Whamcloud - gitweb
LU-13721 utils: fix 'lfs find --pool' for PFL files
[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_27cf() {
1639         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1640         local pid=0
1641
1642         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1643         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1644         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1645         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1646                 error "failed to set $osp_proc=0"
1647
1648         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1649         pid=$!
1650         sleep 1
1651         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1652         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1653                 error "failed to set $osp_proc=1"
1654         wait $pid
1655         [[ $pid -ne 0 ]] ||
1656                 error "should return error due to $osp_proc=0"
1657 }
1658 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1659
1660 test_27d() {
1661         test_mkdir $DIR/$tdir
1662         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1663                 error "setstripe failed"
1664         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1665         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1666 }
1667 run_test 27d "create file with default settings"
1668
1669 test_27e() {
1670         # LU-5839 adds check for existed layout before setting it
1671         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1672                 skip "Need MDS version at least 2.7.56"
1673
1674         test_mkdir $DIR/$tdir
1675         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1676         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1677         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1678 }
1679 run_test 27e "setstripe existing file (should return error)"
1680
1681 test_27f() {
1682         test_mkdir $DIR/$tdir
1683         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1684                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1685         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1686                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1687         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1688         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1689 }
1690 run_test 27f "setstripe with bad stripe size (should return error)"
1691
1692 test_27g() {
1693         test_mkdir $DIR/$tdir
1694         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1695         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1696                 error "$DIR/$tdir/$tfile has object"
1697 }
1698 run_test 27g "$LFS getstripe with no objects"
1699
1700 test_27ga() {
1701         test_mkdir $DIR/$tdir
1702         touch $DIR/$tdir/$tfile || error "touch failed"
1703         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1704         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1705         local rc=$?
1706         (( rc == 2 )) || error "getstripe did not return ENOENT"
1707 }
1708 run_test 27ga "$LFS getstripe with missing file (should return error)"
1709
1710 test_27i() {
1711         test_mkdir $DIR/$tdir
1712         touch $DIR/$tdir/$tfile || error "touch failed"
1713         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1714                 error "missing objects"
1715 }
1716 run_test 27i "$LFS getstripe with some objects"
1717
1718 test_27j() {
1719         test_mkdir $DIR/$tdir
1720         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1721                 error "setstripe failed" || true
1722 }
1723 run_test 27j "setstripe with bad stripe offset (should return error)"
1724
1725 test_27k() { # bug 2844
1726         test_mkdir $DIR/$tdir
1727         local file=$DIR/$tdir/$tfile
1728         local ll_max_blksize=$((4 * 1024 * 1024))
1729         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1730         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1731         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1732         dd if=/dev/zero of=$file bs=4k count=1
1733         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1734         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1735 }
1736 run_test 27k "limit i_blksize for broken user apps"
1737
1738 test_27l() {
1739         mcreate $DIR/$tfile || error "creating file"
1740         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1741                 error "setstripe should have failed" || true
1742 }
1743 run_test 27l "check setstripe permissions (should return error)"
1744
1745 test_27m() {
1746         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1747
1748         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1749                 skip_env "multiple clients -- skipping"
1750
1751         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1752                    head -n1)
1753         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1754                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1755         fi
1756         trap simple_cleanup_common EXIT
1757         test_mkdir $DIR/$tdir
1758         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1759         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1760                 error "dd should fill OST0"
1761         i=2
1762         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1763                 i=$((i + 1))
1764                 [ $i -gt 256 ] && break
1765         done
1766         i=$((i + 1))
1767         touch $DIR/$tdir/$tfile.$i
1768         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1769             awk '{print $1}'| grep -w "0") ] &&
1770                 error "OST0 was full but new created file still use it"
1771         i=$((i + 1))
1772         touch $DIR/$tdir/$tfile.$i
1773         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1774             awk '{print $1}'| grep -w "0") ] &&
1775                 error "OST0 was full but new created file still use it"
1776         simple_cleanup_common
1777 }
1778 run_test 27m "create file while OST0 was full"
1779
1780 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1781 # if the OST isn't full anymore.
1782 reset_enospc() {
1783         local ostidx=${1:-""}
1784         local delay
1785         local ready
1786         local get_prealloc
1787
1788         local list=$(comma_list $(osts_nodes))
1789         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1790
1791         do_nodes $list lctl set_param fail_loc=0
1792         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1793         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1794                 awk '{print $1 * 2;exit;}')
1795         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1796                         grep -v \"^0$\""
1797         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1798 }
1799
1800 __exhaust_precreations() {
1801         local OSTIDX=$1
1802         local FAILLOC=$2
1803         local FAILIDX=${3:-$OSTIDX}
1804         local ofacet=ost$((OSTIDX + 1))
1805
1806         test_mkdir -p -c1 $DIR/$tdir
1807         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
1808         local mfacet=mds$((mdtidx + 1))
1809         echo OSTIDX=$OSTIDX MDTIDX=$mdtidx
1810
1811         local OST=$(ostname_from_index $OSTIDX)
1812
1813         # on the mdt's osc
1814         local mdtosc_proc1=$(get_mdtosc_proc_path $mfacet $OST)
1815         local last_id=$(do_facet $mfacet lctl get_param -n \
1816                         osp.$mdtosc_proc1.prealloc_last_id)
1817         local next_id=$(do_facet $mfacet lctl get_param -n \
1818                         osp.$mdtosc_proc1.prealloc_next_id)
1819
1820         local mdtosc_proc2=$(get_mdtosc_proc_path $mfacet)
1821         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1822
1823         test_mkdir -p $DIR/$tdir/${OST}
1824         $LFS setstripe -i $OSTIDX -c 1 $DIR/$tdir/${OST}
1825 #define OBD_FAIL_OST_ENOSPC              0x215
1826         do_facet $ofacet lctl set_param fail_val=$FAILIDX fail_loc=0x215
1827         echo "Creating to objid $last_id on ost $OST..."
1828         createmany -o $DIR/$tdir/${OST}/f $next_id $((last_id - next_id + 2))
1829         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1830         do_facet $ofacet lctl set_param fail_loc=$FAILLOC
1831 }
1832
1833 exhaust_precreations() {
1834         __exhaust_precreations $1 $2 $3
1835         sleep_maxage
1836 }
1837
1838 exhaust_all_precreations() {
1839         local i
1840         for (( i=0; i < OSTCOUNT; i++ )) ; do
1841                 __exhaust_precreations $i $1 -1
1842         done
1843         sleep_maxage
1844 }
1845
1846 test_27n() {
1847         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1848         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1849         remote_mds_nodsh && skip "remote MDS with nodsh"
1850         remote_ost_nodsh && skip "remote OST with nodsh"
1851
1852         reset_enospc
1853         rm -f $DIR/$tdir/$tfile
1854         exhaust_precreations 0 0x80000215
1855         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1856         touch $DIR/$tdir/$tfile || error "touch failed"
1857         $LFS getstripe $DIR/$tdir/$tfile
1858         reset_enospc
1859 }
1860 run_test 27n "create file with some full OSTs"
1861
1862 test_27o() {
1863         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1864         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1865         remote_mds_nodsh && skip "remote MDS with nodsh"
1866         remote_ost_nodsh && skip "remote OST with nodsh"
1867
1868         reset_enospc
1869         rm -f $DIR/$tdir/$tfile
1870         exhaust_all_precreations 0x215
1871
1872         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1873
1874         reset_enospc
1875         rm -rf $DIR/$tdir/*
1876 }
1877 run_test 27o "create file with all full OSTs (should error)"
1878
1879 test_27p() {
1880         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1881         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1882         remote_mds_nodsh && skip "remote MDS with nodsh"
1883         remote_ost_nodsh && skip "remote OST with nodsh"
1884
1885         reset_enospc
1886         rm -f $DIR/$tdir/$tfile
1887         test_mkdir $DIR/$tdir
1888
1889         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1890         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1891         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1892
1893         exhaust_precreations 0 0x80000215
1894         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1895         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1896         $LFS getstripe $DIR/$tdir/$tfile
1897
1898         reset_enospc
1899 }
1900 run_test 27p "append to a truncated file with some full OSTs"
1901
1902 test_27q() {
1903         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1904         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1905         remote_mds_nodsh && skip "remote MDS with nodsh"
1906         remote_ost_nodsh && skip "remote OST with nodsh"
1907
1908         reset_enospc
1909         rm -f $DIR/$tdir/$tfile
1910
1911         test_mkdir $DIR/$tdir
1912         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1913         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1914                 error "truncate $DIR/$tdir/$tfile failed"
1915         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1916
1917         exhaust_all_precreations 0x215
1918
1919         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1920         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1921
1922         reset_enospc
1923 }
1924 run_test 27q "append to truncated file with all OSTs full (should error)"
1925
1926 test_27r() {
1927         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1928         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1929         remote_mds_nodsh && skip "remote MDS with nodsh"
1930         remote_ost_nodsh && skip "remote OST with nodsh"
1931
1932         reset_enospc
1933         rm -f $DIR/$tdir/$tfile
1934         exhaust_precreations 0 0x80000215
1935
1936         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1937
1938         reset_enospc
1939 }
1940 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
1941
1942 test_27s() { # bug 10725
1943         test_mkdir $DIR/$tdir
1944         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
1945         local stripe_count=0
1946         [ $OSTCOUNT -eq 1 ] || stripe_count=2
1947         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
1948                 error "stripe width >= 2^32 succeeded" || true
1949
1950 }
1951 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
1952
1953 test_27t() { # bug 10864
1954         WDIR=$(pwd)
1955         WLFS=$(which lfs)
1956         cd $DIR
1957         touch $tfile
1958         $WLFS getstripe $tfile
1959         cd $WDIR
1960 }
1961 run_test 27t "check that utils parse path correctly"
1962
1963 test_27u() { # bug 4900
1964         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1965         remote_mds_nodsh && skip "remote MDS with nodsh"
1966
1967         local index
1968         local list=$(comma_list $(mdts_nodes))
1969
1970 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
1971         do_nodes $list $LCTL set_param fail_loc=0x139
1972         test_mkdir -p $DIR/$tdir
1973         trap simple_cleanup_common EXIT
1974         createmany -o $DIR/$tdir/t- 1000
1975         do_nodes $list $LCTL set_param fail_loc=0
1976
1977         TLOG=$TMP/$tfile.getstripe
1978         $LFS getstripe $DIR/$tdir > $TLOG
1979         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
1980         unlinkmany $DIR/$tdir/t- 1000
1981         trap 0
1982         [[ $OBJS -gt 0 ]] &&
1983                 error "$OBJS objects created on OST-0. See $TLOG" ||
1984                 rm -f $TLOG
1985 }
1986 run_test 27u "skip object creation on OSC w/o objects"
1987
1988 test_27v() { # bug 4900
1989         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1990         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1991         remote_mds_nodsh && skip "remote MDS with nodsh"
1992         remote_ost_nodsh && skip "remote OST with nodsh"
1993
1994         exhaust_all_precreations 0x215
1995         reset_enospc
1996
1997         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
1998
1999         touch $DIR/$tdir/$tfile
2000         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2001         # all except ost1
2002         for (( i=1; i < OSTCOUNT; i++ )); do
2003                 do_facet ost$i lctl set_param fail_loc=0x705
2004         done
2005         local START=`date +%s`
2006         createmany -o $DIR/$tdir/$tfile 32
2007
2008         local FINISH=`date +%s`
2009         local TIMEOUT=`lctl get_param -n timeout`
2010         local PROCESS=$((FINISH - START))
2011         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2012                error "$FINISH - $START >= $TIMEOUT / 2"
2013         sleep $((TIMEOUT / 2 - PROCESS))
2014         reset_enospc
2015 }
2016 run_test 27v "skip object creation on slow OST"
2017
2018 test_27w() { # bug 10997
2019         test_mkdir $DIR/$tdir
2020         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2021         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2022                 error "stripe size $size != 65536" || true
2023         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2024                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2025 }
2026 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2027
2028 test_27wa() {
2029         [[ $OSTCOUNT -lt 2 ]] &&
2030                 skip_env "skipping multiple stripe count/offset test"
2031
2032         test_mkdir $DIR/$tdir
2033         for i in $(seq 1 $OSTCOUNT); do
2034                 offset=$((i - 1))
2035                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2036                         error "setstripe -c $i -i $offset failed"
2037                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2038                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2039                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2040                 [ $index -ne $offset ] &&
2041                         error "stripe offset $index != $offset" || true
2042         done
2043 }
2044 run_test 27wa "check $LFS setstripe -c -i options"
2045
2046 test_27x() {
2047         remote_ost_nodsh && skip "remote OST with nodsh"
2048         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2049         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2050
2051         OFFSET=$(($OSTCOUNT - 1))
2052         OSTIDX=0
2053         local OST=$(ostname_from_index $OSTIDX)
2054
2055         test_mkdir $DIR/$tdir
2056         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2057         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2058         sleep_maxage
2059         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2060         for i in $(seq 0 $OFFSET); do
2061                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2062                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2063                 error "OST0 was degraded but new created file still use it"
2064         done
2065         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2066 }
2067 run_test 27x "create files while OST0 is degraded"
2068
2069 test_27y() {
2070         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2071         remote_mds_nodsh && skip "remote MDS with nodsh"
2072         remote_ost_nodsh && skip "remote OST with nodsh"
2073         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2074
2075         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2076         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2077                 osp.$mdtosc.prealloc_last_id)
2078         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2079                 osp.$mdtosc.prealloc_next_id)
2080         local fcount=$((last_id - next_id))
2081         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2082         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2083
2084         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2085                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2086         local OST_DEACTIVE_IDX=-1
2087         local OSC
2088         local OSTIDX
2089         local OST
2090
2091         for OSC in $MDS_OSCS; do
2092                 OST=$(osc_to_ost $OSC)
2093                 OSTIDX=$(index_from_ostuuid $OST)
2094                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2095                         OST_DEACTIVE_IDX=$OSTIDX
2096                 fi
2097                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2098                         echo $OSC "is Deactivated:"
2099                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2100                 fi
2101         done
2102
2103         OSTIDX=$(index_from_ostuuid $OST)
2104         test_mkdir $DIR/$tdir
2105         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2106
2107         for OSC in $MDS_OSCS; do
2108                 OST=$(osc_to_ost $OSC)
2109                 OSTIDX=$(index_from_ostuuid $OST)
2110                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2111                         echo $OST "is degraded:"
2112                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2113                                                 obdfilter.$OST.degraded=1
2114                 fi
2115         done
2116
2117         sleep_maxage
2118         createmany -o $DIR/$tdir/$tfile $fcount
2119
2120         for OSC in $MDS_OSCS; do
2121                 OST=$(osc_to_ost $OSC)
2122                 OSTIDX=$(index_from_ostuuid $OST)
2123                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2124                         echo $OST "is recovered from degraded:"
2125                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2126                                                 obdfilter.$OST.degraded=0
2127                 else
2128                         do_facet $SINGLEMDS lctl --device %$OSC activate
2129                 fi
2130         done
2131
2132         # all osp devices get activated, hence -1 stripe count restored
2133         local stripe_count=0
2134
2135         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2136         # devices get activated.
2137         sleep_maxage
2138         $LFS setstripe -c -1 $DIR/$tfile
2139         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2140         rm -f $DIR/$tfile
2141         [ $stripe_count -ne $OSTCOUNT ] &&
2142                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2143         return 0
2144 }
2145 run_test 27y "create files while OST0 is degraded and the rest inactive"
2146
2147 check_seq_oid()
2148 {
2149         log "check file $1"
2150
2151         lmm_count=$($LFS getstripe -c $1)
2152         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2153         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2154
2155         local old_ifs="$IFS"
2156         IFS=$'[:]'
2157         fid=($($LFS path2fid $1))
2158         IFS="$old_ifs"
2159
2160         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2161         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2162
2163         # compare lmm_seq and lu_fid->f_seq
2164         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2165         # compare lmm_object_id and lu_fid->oid
2166         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2167
2168         # check the trusted.fid attribute of the OST objects of the file
2169         local have_obdidx=false
2170         local stripe_nr=0
2171         $LFS getstripe $1 | while read obdidx oid hex seq; do
2172                 # skip lines up to and including "obdidx"
2173                 [ -z "$obdidx" ] && break
2174                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2175                 $have_obdidx || continue
2176
2177                 local ost=$((obdidx + 1))
2178                 local dev=$(ostdevname $ost)
2179                 local oid_hex
2180
2181                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2182
2183                 seq=$(echo $seq | sed -e "s/^0x//g")
2184                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2185                         oid_hex=$(echo $oid)
2186                 else
2187                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2188                 fi
2189                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2190
2191                 local ff=""
2192                 #
2193                 # Don't unmount/remount the OSTs if we don't need to do that.
2194                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2195                 # update too, until that use mount/ll_decode_filter_fid/mount.
2196                 # Re-enable when debugfs will understand new filter_fid.
2197                 #
2198                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2199                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2200                                 $dev 2>/dev/null" | grep "parent=")
2201                 fi
2202                 if [ -z "$ff" ]; then
2203                         stop ost$ost
2204                         mount_fstype ost$ost
2205                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2206                                 $(facet_mntpt ost$ost)/$obj_file)
2207                         unmount_fstype ost$ost
2208                         start ost$ost $dev $OST_MOUNT_OPTS
2209                         clients_up
2210                 fi
2211
2212                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2213
2214                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2215
2216                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2217                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2218                 #
2219                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2220                 #       stripe_size=1048576 component_id=1 component_start=0 \
2221                 #       component_end=33554432
2222                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2223                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2224                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2225                 local ff_pstripe
2226                 if grep -q 'stripe=' <<<$ff; then
2227                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2228                 else
2229                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2230                         # into f_ver in this case.  See comment on ff_parent.
2231                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2232                 fi
2233
2234                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2235                 [ $ff_pseq = $lmm_seq ] ||
2236                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2237                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2238                 [ $ff_poid = $lmm_oid ] ||
2239                         error "FF parent OID $ff_poid != $lmm_oid"
2240                 (($ff_pstripe == $stripe_nr)) ||
2241                         error "FF stripe $ff_pstripe != $stripe_nr"
2242
2243                 stripe_nr=$((stripe_nr + 1))
2244                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2245                         continue
2246                 if grep -q 'stripe_count=' <<<$ff; then
2247                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2248                                             -e 's/ .*//' <<<$ff)
2249                         [ $lmm_count = $ff_scnt ] ||
2250                                 error "FF stripe count $lmm_count != $ff_scnt"
2251                 fi
2252         done
2253 }
2254
2255 test_27z() {
2256         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2257         remote_ost_nodsh && skip "remote OST with nodsh"
2258
2259         test_mkdir $DIR/$tdir
2260         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2261                 { error "setstripe -c -1 failed"; return 1; }
2262         # We need to send a write to every object to get parent FID info set.
2263         # This _should_ also work for setattr, but does not currently.
2264         # touch $DIR/$tdir/$tfile-1 ||
2265         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2266                 { error "dd $tfile-1 failed"; return 2; }
2267         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2268                 { error "setstripe -c -1 failed"; return 3; }
2269         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2270                 { error "dd $tfile-2 failed"; return 4; }
2271
2272         # make sure write RPCs have been sent to OSTs
2273         sync; sleep 5; sync
2274
2275         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2276         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2277 }
2278 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2279
2280 test_27A() { # b=19102
2281         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2282
2283         save_layout_restore_at_exit $MOUNT
2284         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2285         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2286                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2287         local default_size=$($LFS getstripe -S $MOUNT)
2288         local default_offset=$($LFS getstripe -i $MOUNT)
2289         local dsize=$(do_facet $SINGLEMDS \
2290                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2291         [ $default_size -eq $dsize ] ||
2292                 error "stripe size $default_size != $dsize"
2293         [ $default_offset -eq -1 ] ||
2294                 error "stripe offset $default_offset != -1"
2295 }
2296 run_test 27A "check filesystem-wide default LOV EA values"
2297
2298 test_27B() { # LU-2523
2299         test_mkdir $DIR/$tdir
2300         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2301         touch $DIR/$tdir/f0
2302         # open f1 with O_LOV_DELAY_CREATE
2303         # rename f0 onto f1
2304         # call setstripe ioctl on open file descriptor for f1
2305         # close
2306         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2307                 $DIR/$tdir/f0
2308
2309         rm -f $DIR/$tdir/f1
2310         # open f1 with O_LOV_DELAY_CREATE
2311         # unlink f1
2312         # call setstripe ioctl on open file descriptor for f1
2313         # close
2314         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2315
2316         # Allow multiop to fail in imitation of NFS's busted semantics.
2317         true
2318 }
2319 run_test 27B "call setstripe on open unlinked file/rename victim"
2320
2321 # 27C family tests full striping and overstriping
2322 test_27Ca() { #LU-2871
2323         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2324
2325         declare -a ost_idx
2326         local index
2327         local found
2328         local i
2329         local j
2330
2331         test_mkdir $DIR/$tdir
2332         cd $DIR/$tdir
2333         for i in $(seq 0 $((OSTCOUNT - 1))); do
2334                 # set stripe across all OSTs starting from OST$i
2335                 $LFS setstripe -i $i -c -1 $tfile$i
2336                 # get striping information
2337                 ost_idx=($($LFS getstripe $tfile$i |
2338                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2339                 echo ${ost_idx[@]}
2340
2341                 # check the layout
2342                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2343                         error "${#ost_idx[@]} != $OSTCOUNT"
2344
2345                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2346                         found=0
2347                         for j in $(echo ${ost_idx[@]}); do
2348                                 if [ $index -eq $j ]; then
2349                                         found=1
2350                                         break
2351                                 fi
2352                         done
2353                         [ $found = 1 ] ||
2354                                 error "Can not find $index in ${ost_idx[@]}"
2355                 done
2356         done
2357 }
2358 run_test 27Ca "check full striping across all OSTs"
2359
2360 test_27Cb() {
2361         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2362                 skip "server does not support overstriping"
2363         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2364                 skip_env "too many osts, skipping"
2365
2366         test_mkdir -p $DIR/$tdir
2367         local setcount=$(($OSTCOUNT * 2))
2368         [ $setcount -ge 160 ] || large_xattr_enabled ||
2369                 skip_env "ea_inode feature disabled"
2370
2371         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2372                 error "setstripe failed"
2373
2374         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2375         [ $count -eq $setcount ] ||
2376                 error "stripe count $count, should be $setcount"
2377
2378         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2379                 error "overstriped should be set in pattern"
2380
2381         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2382                 error "dd failed"
2383 }
2384 run_test 27Cb "more stripes than OSTs with -C"
2385
2386 test_27Cc() {
2387         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2388                 skip "server does not support overstriping"
2389         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2390
2391         test_mkdir -p $DIR/$tdir
2392         local setcount=$(($OSTCOUNT - 1))
2393
2394         [ $setcount -ge 160 ] || large_xattr_enabled ||
2395                 skip_env "ea_inode feature disabled"
2396
2397         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2398                 error "setstripe failed"
2399
2400         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2401         [ $count -eq $setcount ] ||
2402                 error "stripe count $count, should be $setcount"
2403
2404         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2405                 error "overstriped should not be set in pattern"
2406
2407         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2408                 error "dd failed"
2409 }
2410 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2411
2412 test_27Cd() {
2413         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2414                 skip "server does not support overstriping"
2415         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2416         large_xattr_enabled || skip_env "ea_inode feature disabled"
2417
2418         test_mkdir -p $DIR/$tdir
2419         local setcount=$LOV_MAX_STRIPE_COUNT
2420
2421         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2422                 error "setstripe failed"
2423
2424         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2425         [ $count -eq $setcount ] ||
2426                 error "stripe count $count, should be $setcount"
2427
2428         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2429                 error "overstriped should be set in pattern"
2430
2431         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2432                 error "dd failed"
2433
2434         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2435 }
2436 run_test 27Cd "test maximum stripe count"
2437
2438 test_27Ce() {
2439         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2440                 skip "server does not support overstriping"
2441         test_mkdir -p $DIR/$tdir
2442
2443         pool_add $TESTNAME || error "Pool creation failed"
2444         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2445
2446         local setcount=8
2447
2448         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2449                 error "setstripe failed"
2450
2451         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2452         [ $count -eq $setcount ] ||
2453                 error "stripe count $count, should be $setcount"
2454
2455         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2456                 error "overstriped should be set in pattern"
2457
2458         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2459                 error "dd failed"
2460
2461         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2462 }
2463 run_test 27Ce "test pool with overstriping"
2464
2465 test_27Cf() {
2466         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2467                 skip "server does not support overstriping"
2468         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2469                 skip_env "too many osts, skipping"
2470
2471         test_mkdir -p $DIR/$tdir
2472
2473         local setcount=$(($OSTCOUNT * 2))
2474         [ $setcount -ge 160 ] || large_xattr_enabled ||
2475                 skip_env "ea_inode feature disabled"
2476
2477         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2478                 error "setstripe failed"
2479
2480         echo 1 > $DIR/$tdir/$tfile
2481
2482         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2483         [ $count -eq $setcount ] ||
2484                 error "stripe count $count, should be $setcount"
2485
2486         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2487                 error "overstriped should be set in pattern"
2488
2489         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2490                 error "dd failed"
2491
2492         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2493 }
2494 run_test 27Cf "test default inheritance with overstriping"
2495
2496 test_27D() {
2497         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2498         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2499         remote_mds_nodsh && skip "remote MDS with nodsh"
2500
2501         local POOL=${POOL:-testpool}
2502         local first_ost=0
2503         local last_ost=$(($OSTCOUNT - 1))
2504         local ost_step=1
2505         local ost_list=$(seq $first_ost $ost_step $last_ost)
2506         local ost_range="$first_ost $last_ost $ost_step"
2507
2508         test_mkdir $DIR/$tdir
2509         pool_add $POOL || error "pool_add failed"
2510         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2511
2512         local skip27D
2513         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2514                 skip27D+="-s 29"
2515         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2516                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2517                         skip27D+=" -s 30,31"
2518         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2519           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2520                 skip27D+=" -s 32,33"
2521         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2522                 skip27D+=" -s 34"
2523         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2524                 error "llapi_layout_test failed"
2525
2526         destroy_test_pools || error "destroy test pools failed"
2527 }
2528 run_test 27D "validate llapi_layout API"
2529
2530 # Verify that default_easize is increased from its initial value after
2531 # accessing a widely striped file.
2532 test_27E() {
2533         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2534         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2535                 skip "client does not have LU-3338 fix"
2536
2537         # 72 bytes is the minimum space required to store striping
2538         # information for a file striped across one OST:
2539         # (sizeof(struct lov_user_md_v3) +
2540         #  sizeof(struct lov_user_ost_data_v1))
2541         local min_easize=72
2542         $LCTL set_param -n llite.*.default_easize $min_easize ||
2543                 error "lctl set_param failed"
2544         local easize=$($LCTL get_param -n llite.*.default_easize)
2545
2546         [ $easize -eq $min_easize ] ||
2547                 error "failed to set default_easize"
2548
2549         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2550                 error "setstripe failed"
2551         # In order to ensure stat() call actually talks to MDS we need to
2552         # do something drastic to this file to shake off all lock, e.g.
2553         # rename it (kills lookup lock forcing cache cleaning)
2554         mv $DIR/$tfile $DIR/${tfile}-1
2555         ls -l $DIR/${tfile}-1
2556         rm $DIR/${tfile}-1
2557
2558         easize=$($LCTL get_param -n llite.*.default_easize)
2559
2560         [ $easize -gt $min_easize ] ||
2561                 error "default_easize not updated"
2562 }
2563 run_test 27E "check that default extended attribute size properly increases"
2564
2565 test_27F() { # LU-5346/LU-7975
2566         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2567         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2568         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2569                 skip "Need MDS version at least 2.8.51"
2570         remote_ost_nodsh && skip "remote OST with nodsh"
2571
2572         test_mkdir $DIR/$tdir
2573         rm -f $DIR/$tdir/f0
2574         $LFS setstripe -c 2 $DIR/$tdir
2575
2576         # stop all OSTs to reproduce situation for LU-7975 ticket
2577         for num in $(seq $OSTCOUNT); do
2578                 stop ost$num
2579         done
2580
2581         # open/create f0 with O_LOV_DELAY_CREATE
2582         # truncate f0 to a non-0 size
2583         # close
2584         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2585
2586         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2587         # open/write it again to force delayed layout creation
2588         cat /etc/hosts > $DIR/$tdir/f0 &
2589         catpid=$!
2590
2591         # restart OSTs
2592         for num in $(seq $OSTCOUNT); do
2593                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2594                         error "ost$num failed to start"
2595         done
2596
2597         wait $catpid || error "cat failed"
2598
2599         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2600         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2601                 error "wrong stripecount"
2602
2603 }
2604 run_test 27F "Client resend delayed layout creation with non-zero size"
2605
2606 test_27G() { #LU-10629
2607         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2608                 skip "Need MDS version at least 2.11.51"
2609         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2610         remote_mds_nodsh && skip "remote MDS with nodsh"
2611         local POOL=${POOL:-testpool}
2612         local ostrange="0 0 1"
2613
2614         test_mkdir $DIR/$tdir
2615         touch $DIR/$tdir/$tfile.nopool
2616         pool_add $POOL || error "pool_add failed"
2617         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2618         $LFS setstripe -p $POOL $DIR/$tdir
2619
2620         local pool=$($LFS getstripe -p $DIR/$tdir)
2621
2622         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2623         touch $DIR/$tdir/$tfile.default
2624         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2625         $LFS find $DIR/$tdir -type f --pool $POOL
2626         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2627         [[ "$found" == "2" ]] ||
2628                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2629
2630         $LFS setstripe -d $DIR/$tdir
2631
2632         pool=$($LFS getstripe -p -d $DIR/$tdir)
2633
2634         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2635 }
2636 run_test 27G "Clear OST pool from stripe"
2637
2638 test_27H() {
2639         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2640                 skip "Need MDS version newer than 2.11.54"
2641         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2642         test_mkdir $DIR/$tdir
2643         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2644         touch $DIR/$tdir/$tfile
2645         $LFS getstripe -c $DIR/$tdir/$tfile
2646         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2647                 error "two-stripe file doesn't have two stripes"
2648
2649         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2650         $LFS getstripe -y $DIR/$tdir/$tfile
2651         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2652              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2653                 error "expected l_ost_idx: [02]$ not matched"
2654
2655         # make sure ost list has been cleared
2656         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2657         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2658                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2659         touch $DIR/$tdir/f3
2660         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2661 }
2662 run_test 27H "Set specific OSTs stripe"
2663
2664 test_27I() {
2665         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2666         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2667         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2668                 skip "Need MDS version newer than 2.12.52"
2669         local pool=$TESTNAME
2670         local ostrange="1 1 1"
2671
2672         save_layout_restore_at_exit $MOUNT
2673         $LFS setstripe -c 2 -i 0 $MOUNT
2674         pool_add $pool || error "pool_add failed"
2675         pool_add_targets $pool $ostrange || "pool_add_targets failed"
2676         test_mkdir $DIR/$tdir
2677         $LFS setstripe -p $pool $DIR/$tdir
2678         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2679         $LFS getstripe $DIR/$tdir/$tfile
2680 }
2681 run_test 27I "check that root dir striping does not break parent dir one"
2682
2683 test_27J() {
2684         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2685                 skip "Need MDS version newer than 2.12.51"
2686
2687         test_mkdir $DIR/$tdir
2688         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2689         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2690
2691         # create foreign file (raw way)
2692         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2693                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2694
2695         # verify foreign file (raw way)
2696         parse_foreign_file -f $DIR/$tdir/$tfile |
2697                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2698                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2699         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2700                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2701         parse_foreign_file -f $DIR/$tdir/$tfile |
2702                 grep "lov_foreign_size: 73" ||
2703                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2704         parse_foreign_file -f $DIR/$tdir/$tfile |
2705                 grep "lov_foreign_type: 1" ||
2706                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2707         parse_foreign_file -f $DIR/$tdir/$tfile |
2708                 grep "lov_foreign_flags: 0x0000DA08" ||
2709                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2710         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2711                 grep "lov_foreign_value: 0x" |
2712                 sed -e 's/lov_foreign_value: 0x//')
2713         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2714         [[ $lov = ${lov2// /} ]] ||
2715                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2716
2717         # create foreign file (lfs + API)
2718         $LFS setstripe --foreign=daos --flags 0xda08 \
2719                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2720                 error "$DIR/$tdir/${tfile}2: create failed"
2721
2722         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2723                 grep "lfm_magic:.*0x0BD70BD0" ||
2724                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2725         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2726         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2727                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2728         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*daos" ||
2729                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2730         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2731                 grep "lfm_flags:.*0x0000DA08" ||
2732                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2733         $LFS getstripe $DIR/$tdir/${tfile}2 |
2734                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2735                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2736
2737         # modify striping should fail
2738         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2739                 error "$DIR/$tdir/$tfile: setstripe should fail"
2740         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2741                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2742
2743         # R/W should fail
2744         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2745         cat $DIR/$tdir/${tfile}2 &&
2746                 error "$DIR/$tdir/${tfile}2: read should fail"
2747         cat /etc/passwd > $DIR/$tdir/$tfile &&
2748                 error "$DIR/$tdir/$tfile: write should fail"
2749         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2750                 error "$DIR/$tdir/${tfile}2: write should fail"
2751
2752         # chmod should work
2753         chmod 222 $DIR/$tdir/$tfile ||
2754                 error "$DIR/$tdir/$tfile: chmod failed"
2755         chmod 222 $DIR/$tdir/${tfile}2 ||
2756                 error "$DIR/$tdir/${tfile}2: chmod failed"
2757
2758         # chown should work
2759         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2760                 error "$DIR/$tdir/$tfile: chown failed"
2761         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2762                 error "$DIR/$tdir/${tfile}2: chown failed"
2763
2764         # rename should work
2765         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2766                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2767         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2768                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2769
2770         #remove foreign file
2771         rm $DIR/$tdir/${tfile}.new ||
2772                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2773         rm $DIR/$tdir/${tfile}2.new ||
2774                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2775 }
2776 run_test 27J "basic ops on file with foreign LOV"
2777
2778 test_27K() {
2779         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2780                 skip "Need MDS version newer than 2.12.49"
2781
2782         test_mkdir $DIR/$tdir
2783         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2784         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2785
2786         # create foreign dir (raw way)
2787         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2788                 error "create_foreign_dir FAILED"
2789
2790         # verify foreign dir (raw way)
2791         parse_foreign_dir -d $DIR/$tdir/$tdir |
2792                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2793                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2794         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2795                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2796         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2797                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2798         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_flags: 0$" ||
2799                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2800         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2801                 grep "lmv_foreign_value: 0x" |
2802                 sed 's/lmv_foreign_value: 0x//')
2803         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2804                 sed 's/ //g')
2805         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2806
2807         # create foreign dir (lfs + API)
2808         $LFS mkdir --foreign=daos --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2809                 $DIR/$tdir/${tdir}2 ||
2810                 error "$DIR/$tdir/${tdir}2: create failed"
2811
2812         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2813                 grep "lfm_magic:.*0x0CD50CD0" ||
2814                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2815         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2816         # - sizeof(lfm_type) - sizeof(lfm_flags)
2817         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2818                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2819         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*daos" ||
2820                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2821         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2822                 grep "lfm_flags:.*0x0000DA05" ||
2823                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2824         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2825                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2826                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2827
2828         # file create in dir should fail
2829         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
2830         touch $DIR/$tdir/${tdir}2/$tfile &&
2831                 "$DIR/${tdir}2: file create should fail"
2832
2833         # chmod should work
2834         chmod 777 $DIR/$tdir/$tdir ||
2835                 error "$DIR/$tdir: chmod failed"
2836         chmod 777 $DIR/$tdir/${tdir}2 ||
2837                 error "$DIR/${tdir}2: chmod failed"
2838
2839         # chown should work
2840         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2841                 error "$DIR/$tdir: chown failed"
2842         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2843                 error "$DIR/${tdir}2: chown failed"
2844
2845         # rename should work
2846         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2847                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2848         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2849                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2850
2851         #remove foreign dir
2852         rmdir $DIR/$tdir/${tdir}.new ||
2853                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2854         rmdir $DIR/$tdir/${tdir}2.new ||
2855                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2856 }
2857 run_test 27K "basic ops on dir with foreign LMV"
2858
2859 test_27L() {
2860         remote_mds_nodsh && skip "remote MDS with nodsh"
2861
2862         local POOL=${POOL:-$TESTNAME}
2863
2864         pool_add $POOL || error "pool_add failed"
2865
2866         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2867                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2868                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2869 }
2870 run_test 27L "lfs pool_list gives correct pool name"
2871
2872 test_27M() {
2873         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2874                 skip "Need MDS version >= than 2.12.57"
2875         remote_mds_nodsh && skip "remote MDS with nodsh"
2876         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2877
2878         test_mkdir $DIR/$tdir
2879
2880         # Set default striping on directory
2881         $LFS setstripe -C 4 $DIR/$tdir
2882
2883         echo 1 > $DIR/$tdir/${tfile}.1
2884         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2885         local setcount=4
2886         [ $count -eq $setcount ] ||
2887                 error "(1) stripe count $count, should be $setcount"
2888
2889         # Capture existing append_stripe_count setting for restore
2890         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2891         local mdts=$(comma_list $(mdts_nodes))
2892         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$orig_count" EXIT
2893
2894         local appendcount=$orig_count
2895         echo 1 >> $DIR/$tdir/${tfile}.2_append
2896         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
2897         [ $count -eq $appendcount ] ||
2898                 error "(2)stripe count $count, should be $appendcount for append"
2899
2900         # Disable O_APPEND striping, verify it works
2901         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
2902
2903         # Should now get the default striping, which is 4
2904         setcount=4
2905         echo 1 >> $DIR/$tdir/${tfile}.3_append
2906         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
2907         [ $count -eq $setcount ] ||
2908                 error "(3) stripe count $count, should be $setcount"
2909
2910         # Try changing the stripe count for append files
2911         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
2912
2913         # Append striping is now 2 (directory default is still 4)
2914         appendcount=2
2915         echo 1 >> $DIR/$tdir/${tfile}.4_append
2916         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
2917         [ $count -eq $appendcount ] ||
2918                 error "(4) stripe count $count, should be $appendcount for append"
2919
2920         # Test append stripe count of -1
2921         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
2922         appendcount=$OSTCOUNT
2923         echo 1 >> $DIR/$tdir/${tfile}.5
2924         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
2925         [ $count -eq $appendcount ] ||
2926                 error "(5) stripe count $count, should be $appendcount for append"
2927
2928         # Set append striping back to default of 1
2929         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
2930
2931         # Try a new default striping, PFL + DOM
2932         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
2933
2934         # Create normal DOM file, DOM returns stripe count == 0
2935         setcount=0
2936         touch $DIR/$tdir/${tfile}.6
2937         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
2938         [ $count -eq $setcount ] ||
2939                 error "(6) stripe count $count, should be $setcount"
2940
2941         # Show
2942         appendcount=1
2943         echo 1 >> $DIR/$tdir/${tfile}.7_append
2944         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
2945         [ $count -eq $appendcount ] ||
2946                 error "(7) stripe count $count, should be $appendcount for append"
2947
2948         # Clean up DOM layout
2949         $LFS setstripe -d $DIR/$tdir
2950
2951         # Now test that append striping works when layout is from root
2952         $LFS setstripe -c 2 $MOUNT
2953         # Make a special directory for this
2954         mkdir $DIR/${tdir}/${tdir}.2
2955         stack_trap "$LFS setstripe -d $MOUNT" EXIT
2956
2957         # Verify for normal file
2958         setcount=2
2959         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
2960         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
2961         [ $count -eq $setcount ] ||
2962                 error "(8) stripe count $count, should be $setcount"
2963
2964         appendcount=1
2965         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
2966         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
2967         [ $count -eq $appendcount ] ||
2968                 error "(9) stripe count $count, should be $appendcount for append"
2969
2970         # Now test O_APPEND striping with pools
2971         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
2972         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'" EXIT
2973
2974         # Create the pool
2975         pool_add $TESTNAME || error "pool creation failed"
2976         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
2977
2978         echo 1 >> $DIR/$tdir/${tfile}.10_append
2979
2980         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
2981         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
2982
2983         # Check that count is still correct
2984         appendcount=1
2985         echo 1 >> $DIR/$tdir/${tfile}.11_append
2986         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
2987         [ $count -eq $appendcount ] ||
2988                 error "(11) stripe count $count, should be $appendcount for append"
2989
2990         # Disable O_APPEND stripe count, verify pool works separately
2991         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
2992
2993         echo 1 >> $DIR/$tdir/${tfile}.12_append
2994
2995         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
2996         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
2997
2998         # Remove pool setting, verify it's not applied
2999         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3000
3001         echo 1 >> $DIR/$tdir/${tfile}.13_append
3002
3003         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3004         [ "$pool" = "" ] || error "(13) pool found: $pool"
3005 }
3006 run_test 27M "test O_APPEND striping"
3007
3008 test_27N() {
3009         combined_mgs_mds && skip "needs separate MGS/MDT"
3010
3011         pool_add $TESTNAME || error "pool_add failed"
3012         do_facet mgs "$LCTL pool_list $FSNAME" |
3013                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3014                 error "lctl pool_list on MGS failed"
3015 }
3016 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3017
3018 # createtest also checks that device nodes are created and
3019 # then visible correctly (#2091)
3020 test_28() { # bug 2091
3021         test_mkdir $DIR/d28
3022         $CREATETEST $DIR/d28/ct || error "createtest failed"
3023 }
3024 run_test 28 "create/mknod/mkdir with bad file types ============"
3025
3026 test_29() {
3027         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3028
3029         sync; sleep 1; sync # flush out any dirty pages from previous tests
3030         cancel_lru_locks
3031         test_mkdir $DIR/d29
3032         touch $DIR/d29/foo
3033         log 'first d29'
3034         ls -l $DIR/d29
3035
3036         declare -i LOCKCOUNTORIG=0
3037         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3038                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3039         done
3040         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3041
3042         declare -i LOCKUNUSEDCOUNTORIG=0
3043         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3044                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3045         done
3046
3047         log 'second d29'
3048         ls -l $DIR/d29
3049         log 'done'
3050
3051         declare -i LOCKCOUNTCURRENT=0
3052         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3053                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3054         done
3055
3056         declare -i LOCKUNUSEDCOUNTCURRENT=0
3057         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3058                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3059         done
3060
3061         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3062                 $LCTL set_param -n ldlm.dump_namespaces ""
3063                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3064                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3065                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3066                 return 2
3067         fi
3068         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3069                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3070                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3071                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3072                 return 3
3073         fi
3074 }
3075 run_test 29 "IT_GETATTR regression  ============================"
3076
3077 test_30a() { # was test_30
3078         cp $(which ls) $DIR || cp /bin/ls $DIR
3079         $DIR/ls / || error "Can't execute binary from lustre"
3080         rm $DIR/ls
3081 }
3082 run_test 30a "execute binary from Lustre (execve) =============="
3083
3084 test_30b() {
3085         cp `which ls` $DIR || cp /bin/ls $DIR
3086         chmod go+rx $DIR/ls
3087         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3088         rm $DIR/ls
3089 }
3090 run_test 30b "execute binary from Lustre as non-root ==========="
3091
3092 test_30c() { # b=22376
3093         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3094
3095         cp $(which ls) $DIR || cp /bin/ls $DIR
3096         chmod a-rw $DIR/ls
3097         cancel_lru_locks mdc
3098         cancel_lru_locks osc
3099         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3100         rm -f $DIR/ls
3101 }
3102 run_test 30c "execute binary from Lustre without read perms ===="
3103
3104 test_30d() {
3105         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3106
3107         for i in {1..10}; do
3108                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3109                 local PID=$!
3110                 sleep 1
3111                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3112                 wait $PID || error "executing dd from Lustre failed"
3113                 rm -f $DIR/$tfile
3114         done
3115
3116         rm -f $DIR/dd
3117 }
3118 run_test 30d "execute binary from Lustre while clear locks"
3119
3120 test_31a() {
3121         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3122         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3123 }
3124 run_test 31a "open-unlink file =================================="
3125
3126 test_31b() {
3127         touch $DIR/f31 || error "touch $DIR/f31 failed"
3128         ln $DIR/f31 $DIR/f31b || error "ln failed"
3129         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3130         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3131 }
3132 run_test 31b "unlink file with multiple links while open ======="
3133
3134 test_31c() {
3135         touch $DIR/f31 || error "touch $DIR/f31 failed"
3136         ln $DIR/f31 $DIR/f31c || error "ln failed"
3137         multiop_bg_pause $DIR/f31 O_uc ||
3138                 error "multiop_bg_pause for $DIR/f31 failed"
3139         MULTIPID=$!
3140         $MULTIOP $DIR/f31c Ouc
3141         kill -USR1 $MULTIPID
3142         wait $MULTIPID
3143 }
3144 run_test 31c "open-unlink file with multiple links ============="
3145
3146 test_31d() {
3147         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3148         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3149 }
3150 run_test 31d "remove of open directory ========================="
3151
3152 test_31e() { # bug 2904
3153         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3154 }
3155 run_test 31e "remove of open non-empty directory ==============="
3156
3157 test_31f() { # bug 4554
3158         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3159
3160         set -vx
3161         test_mkdir $DIR/d31f
3162         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3163         cp /etc/hosts $DIR/d31f
3164         ls -l $DIR/d31f
3165         $LFS getstripe $DIR/d31f/hosts
3166         multiop_bg_pause $DIR/d31f D_c || return 1
3167         MULTIPID=$!
3168
3169         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3170         test_mkdir $DIR/d31f
3171         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3172         cp /etc/hosts $DIR/d31f
3173         ls -l $DIR/d31f
3174         $LFS getstripe $DIR/d31f/hosts
3175         multiop_bg_pause $DIR/d31f D_c || return 1
3176         MULTIPID2=$!
3177
3178         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3179         wait $MULTIPID || error "first opendir $MULTIPID failed"
3180
3181         sleep 6
3182
3183         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3184         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3185         set +vx
3186 }
3187 run_test 31f "remove of open directory with open-unlink file ==="
3188
3189 test_31g() {
3190         echo "-- cross directory link --"
3191         test_mkdir -c1 $DIR/${tdir}ga
3192         test_mkdir -c1 $DIR/${tdir}gb
3193         touch $DIR/${tdir}ga/f
3194         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3195         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3196         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3197         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3198         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3199 }
3200 run_test 31g "cross directory link==============="
3201
3202 test_31h() {
3203         echo "-- cross directory link --"
3204         test_mkdir -c1 $DIR/${tdir}
3205         test_mkdir -c1 $DIR/${tdir}/dir
3206         touch $DIR/${tdir}/f
3207         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3208         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3209         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3210         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3211         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3212 }
3213 run_test 31h "cross directory link under child==============="
3214
3215 test_31i() {
3216         echo "-- cross directory link --"
3217         test_mkdir -c1 $DIR/$tdir
3218         test_mkdir -c1 $DIR/$tdir/dir
3219         touch $DIR/$tdir/dir/f
3220         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3221         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3222         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3223         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3224         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3225 }
3226 run_test 31i "cross directory link under parent==============="
3227
3228 test_31j() {
3229         test_mkdir -c1 -p $DIR/$tdir
3230         test_mkdir -c1 -p $DIR/$tdir/dir1
3231         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3232         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3233         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3234         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3235         return 0
3236 }
3237 run_test 31j "link for directory==============="
3238
3239 test_31k() {
3240         test_mkdir -c1 -p $DIR/$tdir
3241         touch $DIR/$tdir/s
3242         touch $DIR/$tdir/exist
3243         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3244         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3245         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3246         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3247         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3248         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3249         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3250         return 0
3251 }
3252 run_test 31k "link to file: the same, non-existing, dir==============="
3253
3254 test_31m() {
3255         mkdir $DIR/d31m
3256         touch $DIR/d31m/s
3257         mkdir $DIR/d31m2
3258         touch $DIR/d31m2/exist
3259         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3260         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3261         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3262         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3263         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3264         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3265         return 0
3266 }
3267 run_test 31m "link to file: the same, non-existing, dir==============="
3268
3269 test_31n() {
3270         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3271         nlink=$(stat --format=%h $DIR/$tfile)
3272         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3273         local fd=$(free_fd)
3274         local cmd="exec $fd<$DIR/$tfile"
3275         eval $cmd
3276         cmd="exec $fd<&-"
3277         trap "eval $cmd" EXIT
3278         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3279         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3280         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3281         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3282         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3283         eval $cmd
3284 }
3285 run_test 31n "check link count of unlinked file"
3286
3287 link_one() {
3288         local tempfile=$(mktemp $1_XXXXXX)
3289         mlink $tempfile $1 2> /dev/null &&
3290                 echo "$BASHPID: link $tempfile to $1 succeeded"
3291         munlink $tempfile
3292 }
3293
3294 test_31o() { # LU-2901
3295         test_mkdir $DIR/$tdir
3296         for LOOP in $(seq 100); do
3297                 rm -f $DIR/$tdir/$tfile*
3298                 for THREAD in $(seq 8); do
3299                         link_one $DIR/$tdir/$tfile.$LOOP &
3300                 done
3301                 wait
3302                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3303                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3304                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3305                         break || true
3306         done
3307 }
3308 run_test 31o "duplicate hard links with same filename"
3309
3310 test_31p() {
3311         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3312
3313         test_mkdir $DIR/$tdir
3314         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3315         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3316
3317         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3318                 error "open unlink test1 failed"
3319         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3320                 error "open unlink test2 failed"
3321
3322         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3323                 error "test1 still exists"
3324         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3325                 error "test2 still exists"
3326 }
3327 run_test 31p "remove of open striped directory"
3328
3329 cleanup_test32_mount() {
3330         local rc=0
3331         trap 0
3332         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3333         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3334         losetup -d $loopdev || true
3335         rm -rf $DIR/$tdir
3336         return $rc
3337 }
3338
3339 test_32a() {
3340         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3341
3342         echo "== more mountpoints and symlinks ================="
3343         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3344         trap cleanup_test32_mount EXIT
3345         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3346         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3347                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3348         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3349                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3350         cleanup_test32_mount
3351 }
3352 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3353
3354 test_32b() {
3355         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3356
3357         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3358         trap cleanup_test32_mount EXIT
3359         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3360         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3361                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3362         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3363                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3364         cleanup_test32_mount
3365 }
3366 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3367
3368 test_32c() {
3369         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3370
3371         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3372         trap cleanup_test32_mount EXIT
3373         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3374         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3375                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3376         test_mkdir -p $DIR/$tdir/d2/test_dir
3377         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3378                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3379         cleanup_test32_mount
3380 }
3381 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3382
3383 test_32d() {
3384         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3385
3386         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3387         trap cleanup_test32_mount EXIT
3388         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3389         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3390                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3391         test_mkdir -p $DIR/$tdir/d2/test_dir
3392         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3393                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3394         cleanup_test32_mount
3395 }
3396 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3397
3398 test_32e() {
3399         rm -fr $DIR/$tdir
3400         test_mkdir -p $DIR/$tdir/tmp
3401         local tmp_dir=$DIR/$tdir/tmp
3402         ln -s $DIR/$tdir $tmp_dir/symlink11
3403         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3404         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3405         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3406 }
3407 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3408
3409 test_32f() {
3410         rm -fr $DIR/$tdir
3411         test_mkdir -p $DIR/$tdir/tmp
3412         local tmp_dir=$DIR/$tdir/tmp
3413         ln -s $DIR/$tdir $tmp_dir/symlink11
3414         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3415         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3416         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3417 }
3418 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3419
3420 test_32g() {
3421         local tmp_dir=$DIR/$tdir/tmp
3422         test_mkdir -p $tmp_dir
3423         test_mkdir $DIR/${tdir}2
3424         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3425         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3426         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3427         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3428         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3429         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3430 }
3431 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3432
3433 test_32h() {
3434         rm -fr $DIR/$tdir $DIR/${tdir}2
3435         tmp_dir=$DIR/$tdir/tmp
3436         test_mkdir -p $tmp_dir
3437         test_mkdir $DIR/${tdir}2
3438         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3439         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3440         ls $tmp_dir/symlink12 || error "listing symlink12"
3441         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3442 }
3443 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3444
3445 test_32i() {
3446         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3447
3448         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3449         trap cleanup_test32_mount EXIT
3450         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3451         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3452                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3453         touch $DIR/$tdir/test_file
3454         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3455                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3456         cleanup_test32_mount
3457 }
3458 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3459
3460 test_32j() {
3461         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3462
3463         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3464         trap cleanup_test32_mount EXIT
3465         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3466         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3467                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3468         touch $DIR/$tdir/test_file
3469         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3470                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3471         cleanup_test32_mount
3472 }
3473 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3474
3475 test_32k() {
3476         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3477
3478         rm -fr $DIR/$tdir
3479         trap cleanup_test32_mount EXIT
3480         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3481         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3482                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3483         test_mkdir -p $DIR/$tdir/d2
3484         touch $DIR/$tdir/d2/test_file || error "touch failed"
3485         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3486                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3487         cleanup_test32_mount
3488 }
3489 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3490
3491 test_32l() {
3492         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3493
3494         rm -fr $DIR/$tdir
3495         trap cleanup_test32_mount EXIT
3496         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3497         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3498                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3499         test_mkdir -p $DIR/$tdir/d2
3500         touch $DIR/$tdir/d2/test_file || error "touch failed"
3501         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3502                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3503         cleanup_test32_mount
3504 }
3505 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3506
3507 test_32m() {
3508         rm -fr $DIR/d32m
3509         test_mkdir -p $DIR/d32m/tmp
3510         TMP_DIR=$DIR/d32m/tmp
3511         ln -s $DIR $TMP_DIR/symlink11
3512         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3513         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3514                 error "symlink11 not a link"
3515         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3516                 error "symlink01 not a link"
3517 }
3518 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3519
3520 test_32n() {
3521         rm -fr $DIR/d32n
3522         test_mkdir -p $DIR/d32n/tmp
3523         TMP_DIR=$DIR/d32n/tmp
3524         ln -s $DIR $TMP_DIR/symlink11
3525         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3526         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3527         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3528 }
3529 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3530
3531 test_32o() {
3532         touch $DIR/$tfile
3533         test_mkdir -p $DIR/d32o/tmp
3534         TMP_DIR=$DIR/d32o/tmp
3535         ln -s $DIR/$tfile $TMP_DIR/symlink12
3536         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3537         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3538                 error "symlink12 not a link"
3539         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3540         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3541                 error "$DIR/d32o/tmp/symlink12 not file type"
3542         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3543                 error "$DIR/d32o/symlink02 not file type"
3544 }
3545 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3546
3547 test_32p() {
3548         log 32p_1
3549         rm -fr $DIR/d32p
3550         log 32p_2
3551         rm -f $DIR/$tfile
3552         log 32p_3
3553         touch $DIR/$tfile
3554         log 32p_4
3555         test_mkdir -p $DIR/d32p/tmp
3556         log 32p_5
3557         TMP_DIR=$DIR/d32p/tmp
3558         log 32p_6
3559         ln -s $DIR/$tfile $TMP_DIR/symlink12
3560         log 32p_7
3561         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3562         log 32p_8
3563         cat $DIR/d32p/tmp/symlink12 ||
3564                 error "Can't open $DIR/d32p/tmp/symlink12"
3565         log 32p_9
3566         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3567         log 32p_10
3568 }
3569 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3570
3571 test_32q() {
3572         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3573
3574         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3575         trap cleanup_test32_mount EXIT
3576         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3577         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3578         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3579                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3580         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3581         cleanup_test32_mount
3582 }
3583 run_test 32q "stat follows mountpoints in Lustre (should return error)"
3584
3585 test_32r() {
3586         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3587
3588         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3589         trap cleanup_test32_mount EXIT
3590         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3591         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3592         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3593                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3594         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
3595         cleanup_test32_mount
3596 }
3597 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
3598
3599 test_33aa() {
3600         rm -f $DIR/$tfile
3601         touch $DIR/$tfile
3602         chmod 444 $DIR/$tfile
3603         chown $RUNAS_ID $DIR/$tfile
3604         log 33_1
3605         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3606         log 33_2
3607 }
3608 run_test 33aa "write file with mode 444 (should return error)"
3609
3610 test_33a() {
3611         rm -fr $DIR/$tdir
3612         test_mkdir $DIR/$tdir
3613         chown $RUNAS_ID $DIR/$tdir
3614         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
3615                 error "$RUNAS create $tdir/$tfile failed"
3616         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
3617                 error "open RDWR" || true
3618 }
3619 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
3620
3621 test_33b() {
3622         rm -fr $DIR/$tdir
3623         test_mkdir $DIR/$tdir
3624         chown $RUNAS_ID $DIR/$tdir
3625         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
3626 }
3627 run_test 33b "test open file with malformed flags (No panic)"
3628
3629 test_33c() {
3630         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3631         remote_ost_nodsh && skip "remote OST with nodsh"
3632
3633         local ostnum
3634         local ostname
3635         local write_bytes
3636         local all_zeros
3637
3638         all_zeros=:
3639         rm -fr $DIR/$tdir
3640         test_mkdir $DIR/$tdir
3641         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
3642
3643         sync
3644         for ostnum in $(seq $OSTCOUNT); do
3645                 # test-framework's OST numbering is one-based, while Lustre's
3646                 # is zero-based
3647                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3648                 # Parsing llobdstat's output sucks; we could grep the /proc
3649                 # path, but that's likely to not be as portable as using the
3650                 # llobdstat utility.  So we parse lctl output instead.
3651                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3652                         obdfilter/$ostname/stats |
3653                         awk '/^write_bytes/ {print $7}' )
3654                 echo "baseline_write_bytes@$OSTnum/$ostname=$write_bytes"
3655                 if (( ${write_bytes:-0} > 0 ))
3656                 then
3657                         all_zeros=false
3658                         break;
3659                 fi
3660         done
3661
3662         $all_zeros || return 0
3663
3664         # Write four bytes
3665         echo foo > $DIR/$tdir/bar
3666         # Really write them
3667         sync
3668
3669         # Total up write_bytes after writing.  We'd better find non-zeros.
3670         for ostnum in $(seq $OSTCOUNT); do
3671                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3672                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3673                         obdfilter/$ostname/stats |
3674                         awk '/^write_bytes/ {print $7}' )
3675                 echo "write_bytes@$OSTnum/$ostname=$write_bytes"
3676                 if (( ${write_bytes:-0} > 0 ))
3677                 then
3678                         all_zeros=false
3679                         break;
3680                 fi
3681         done
3682
3683         if $all_zeros
3684         then
3685                 for ostnum in $(seq $OSTCOUNT); do
3686                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3687                         echo "Check that write_bytes is present in obdfilter/*/stats:"
3688                         do_facet ost$ostnum lctl get_param -n \
3689                                 obdfilter/$ostname/stats
3690                 done
3691                 error "OST not keeping write_bytes stats (b22312)"
3692         fi
3693 }
3694 run_test 33c "test llobdstat and write_bytes"
3695
3696 test_33d() {
3697         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
3698         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3699
3700         local MDTIDX=1
3701         local remote_dir=$DIR/$tdir/remote_dir
3702
3703         test_mkdir $DIR/$tdir
3704         $LFS mkdir -i $MDTIDX $remote_dir ||
3705                 error "create remote directory failed"
3706
3707         touch $remote_dir/$tfile
3708         chmod 444 $remote_dir/$tfile
3709         chown $RUNAS_ID $remote_dir/$tfile
3710
3711         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3712
3713         chown $RUNAS_ID $remote_dir
3714         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
3715                                         error "create" || true
3716         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
3717                                     error "open RDWR" || true
3718         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
3719 }
3720 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
3721
3722 test_33e() {
3723         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3724
3725         mkdir $DIR/$tdir
3726
3727         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3728         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3729         mkdir $DIR/$tdir/local_dir
3730
3731         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3732         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3733         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3734
3735         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3736                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
3737
3738         rmdir $DIR/$tdir/* || error "rmdir failed"
3739
3740         umask 777
3741         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3742         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3743         mkdir $DIR/$tdir/local_dir
3744
3745         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3746         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3747         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3748
3749         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3750                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
3751
3752         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
3753
3754         umask 000
3755         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3756         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3757         mkdir $DIR/$tdir/local_dir
3758
3759         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3760         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3761         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3762
3763         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3764                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
3765 }
3766 run_test 33e "mkdir and striped directory should have same mode"
3767
3768 cleanup_33f() {
3769         trap 0
3770         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
3771 }
3772
3773 test_33f() {
3774         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3775         remote_mds_nodsh && skip "remote MDS with nodsh"
3776
3777         mkdir $DIR/$tdir
3778         chmod go+rwx $DIR/$tdir
3779         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
3780         trap cleanup_33f EXIT
3781
3782         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
3783                 error "cannot create striped directory"
3784
3785         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
3786                 error "cannot create files in striped directory"
3787
3788         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
3789                 error "cannot remove files in striped directory"
3790
3791         $RUNAS rmdir $DIR/$tdir/striped_dir ||
3792                 error "cannot remove striped directory"
3793
3794         cleanup_33f
3795 }
3796 run_test 33f "nonroot user can create, access, and remove a striped directory"
3797
3798 test_33g() {
3799         mkdir -p $DIR/$tdir/dir2
3800
3801         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
3802         echo $err
3803         [[ $err =~ "exists" ]] || error "Not exists error"
3804 }
3805 run_test 33g "nonroot user create already existing root created file"
3806
3807 test_33h() {
3808         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3809         [ $MDS1_VERSION -lt $(version_code 2.13.50) ] &&
3810                 skip "Need MDS version at least 2.13.50"
3811
3812         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir ||
3813                 error "mkdir $tdir failed"
3814         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
3815
3816         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
3817         local index2
3818
3819         for fname in $DIR/$tdir/$tfile.bak \
3820                      $DIR/$tdir/$tfile.SAV \
3821                      $DIR/$tdir/$tfile.orig \
3822                      $DIR/$tdir/$tfile~; do
3823                 touch $fname  || error "touch $fname failed"
3824                 index2=$($LFS getstripe -m $fname)
3825                 [ $index -eq $index2 ] ||
3826                         error "$fname MDT index mismatch $index != $index2"
3827         done
3828
3829         local failed=0
3830         for i in {1..50}; do
3831                 for fname in $(mktemp -u $DIR/$tdir/.$tfile.XXXXXX) \
3832                              $(mktemp $DIR/$tdir/$tfile.XXXXXXXX); do
3833                         touch $fname  || error "touch $fname failed"
3834                         index2=$($LFS getstripe -m $fname)
3835                         if [[ $index != $index2 ]]; then
3836                                 failed=$((failed + 1))
3837                                 echo "$fname MDT index mismatch $index != $index2"
3838                         fi
3839                 done
3840         done
3841         echo "$failed MDT index mismatches"
3842         (( failed < 4 )) || error "MDT index mismatch $failed times"
3843
3844 }
3845 run_test 33h "temp file is located on the same MDT as target"
3846
3847 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
3848 test_34a() {
3849         rm -f $DIR/f34
3850         $MCREATE $DIR/f34 || error "mcreate failed"
3851         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3852                 error "getstripe failed"
3853         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
3854         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3855                 error "getstripe failed"
3856         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3857                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3858 }
3859 run_test 34a "truncate file that has not been opened ==========="
3860
3861 test_34b() {
3862         [ ! -f $DIR/f34 ] && test_34a
3863         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3864                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3865         $OPENFILE -f O_RDONLY $DIR/f34
3866         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3867                 error "getstripe failed"
3868         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3869                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3870 }
3871 run_test 34b "O_RDONLY opening file doesn't create objects ====="
3872
3873 test_34c() {
3874         [ ! -f $DIR/f34 ] && test_34a
3875         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3876                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3877         $OPENFILE -f O_RDWR $DIR/f34
3878         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
3879                 error "$LFS getstripe failed"
3880         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3881                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3882 }
3883 run_test 34c "O_RDWR opening file-with-size works =============="
3884
3885 test_34d() {
3886         [ ! -f $DIR/f34 ] && test_34a
3887         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
3888                 error "dd failed"
3889         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3890                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3891         rm $DIR/f34
3892 }
3893 run_test 34d "write to sparse file ============================="
3894
3895 test_34e() {
3896         rm -f $DIR/f34e
3897         $MCREATE $DIR/f34e || error "mcreate failed"
3898         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
3899         $CHECKSTAT -s 1000 $DIR/f34e ||
3900                 error "Size of $DIR/f34e not equal to 1000 bytes"
3901         $OPENFILE -f O_RDWR $DIR/f34e
3902         $CHECKSTAT -s 1000 $DIR/f34e ||
3903                 error "Size of $DIR/f34e not equal to 1000 bytes"
3904 }
3905 run_test 34e "create objects, some with size and some without =="
3906
3907 test_34f() { # bug 6242, 6243
3908         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3909
3910         SIZE34F=48000
3911         rm -f $DIR/f34f
3912         $MCREATE $DIR/f34f || error "mcreate failed"
3913         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
3914         dd if=$DIR/f34f of=$TMP/f34f
3915         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
3916         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
3917         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
3918         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
3919         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
3920 }
3921 run_test 34f "read from a file with no objects until EOF ======="
3922
3923 test_34g() {
3924         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3925
3926         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
3927                 error "dd failed"
3928         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
3929         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3930                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
3931         cancel_lru_locks osc
3932         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3933                 error "wrong size after lock cancel"
3934
3935         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
3936         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3937                 error "expanding truncate failed"
3938         cancel_lru_locks osc
3939         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3940                 error "wrong expanded size after lock cancel"
3941 }
3942 run_test 34g "truncate long file ==============================="
3943
3944 test_34h() {
3945         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3946
3947         local gid=10
3948         local sz=1000
3949
3950         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
3951         sync # Flush the cache so that multiop below does not block on cache
3952              # flush when getting the group lock
3953         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
3954         MULTIPID=$!
3955
3956         # Since just timed wait is not good enough, let's do a sync write
3957         # that way we are sure enough time for a roundtrip + processing
3958         # passed + 2 seconds of extra margin.
3959         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
3960         rm $DIR/${tfile}-1
3961         sleep 2
3962
3963         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
3964                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
3965                 kill -9 $MULTIPID
3966         fi
3967         wait $MULTIPID
3968         local nsz=`stat -c %s $DIR/$tfile`
3969         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
3970 }
3971 run_test 34h "ftruncate file under grouplock should not block"
3972
3973 test_35a() {
3974         cp /bin/sh $DIR/f35a
3975         chmod 444 $DIR/f35a
3976         chown $RUNAS_ID $DIR/f35a
3977         $RUNAS $DIR/f35a && error || true
3978         rm $DIR/f35a
3979 }
3980 run_test 35a "exec file with mode 444 (should return and not leak)"
3981
3982 test_36a() {
3983         rm -f $DIR/f36
3984         utime $DIR/f36 || error "utime failed for MDS"
3985 }
3986 run_test 36a "MDS utime check (mknod, utime)"
3987
3988 test_36b() {
3989         echo "" > $DIR/f36
3990         utime $DIR/f36 || error "utime failed for OST"
3991 }
3992 run_test 36b "OST utime check (open, utime)"
3993
3994 test_36c() {
3995         rm -f $DIR/d36/f36
3996         test_mkdir $DIR/d36
3997         chown $RUNAS_ID $DIR/d36
3998         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
3999 }
4000 run_test 36c "non-root MDS utime check (mknod, utime)"
4001
4002 test_36d() {
4003         [ ! -d $DIR/d36 ] && test_36c
4004         echo "" > $DIR/d36/f36
4005         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4006 }
4007 run_test 36d "non-root OST utime check (open, utime)"
4008
4009 test_36e() {
4010         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4011
4012         test_mkdir $DIR/$tdir
4013         touch $DIR/$tdir/$tfile
4014         $RUNAS utime $DIR/$tdir/$tfile &&
4015                 error "utime worked, expected failure" || true
4016 }
4017 run_test 36e "utime on non-owned file (should return error)"
4018
4019 subr_36fh() {
4020         local fl="$1"
4021         local LANG_SAVE=$LANG
4022         local LC_LANG_SAVE=$LC_LANG
4023         export LANG=C LC_LANG=C # for date language
4024
4025         DATESTR="Dec 20  2000"
4026         test_mkdir $DIR/$tdir
4027         lctl set_param fail_loc=$fl
4028         date; date +%s
4029         cp /etc/hosts $DIR/$tdir/$tfile
4030         sync & # write RPC generated with "current" inode timestamp, but delayed
4031         sleep 1
4032         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4033         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4034         cancel_lru_locks $OSC
4035         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4036         date; date +%s
4037         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4038                 echo "BEFORE: $LS_BEFORE" && \
4039                 echo "AFTER : $LS_AFTER" && \
4040                 echo "WANT  : $DATESTR" && \
4041                 error "$DIR/$tdir/$tfile timestamps changed" || true
4042
4043         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4044 }
4045
4046 test_36f() {
4047         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4048
4049         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4050         subr_36fh "0x80000214"
4051 }
4052 run_test 36f "utime on file racing with OST BRW write =========="
4053
4054 test_36g() {
4055         remote_ost_nodsh && skip "remote OST with nodsh"
4056         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4057         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4058                 skip "Need MDS version at least 2.12.51"
4059
4060         local fmd_max_age
4061         local fmd
4062         local facet="ost1"
4063         local tgt="obdfilter"
4064
4065         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4066
4067         test_mkdir $DIR/$tdir
4068         fmd_max_age=$(do_facet $facet \
4069                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4070                 head -n 1")
4071
4072         echo "FMD max age: ${fmd_max_age}s"
4073         touch $DIR/$tdir/$tfile
4074         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4075                 gawk '{cnt=cnt+$1}  END{print cnt}')
4076         echo "FMD before: $fmd"
4077         [[ $fmd == 0 ]] &&
4078                 error "FMD wasn't create by touch"
4079         sleep $((fmd_max_age + 12))
4080         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4081                 gawk '{cnt=cnt+$1}  END{print cnt}')
4082         echo "FMD after: $fmd"
4083         [[ $fmd == 0 ]] ||
4084                 error "FMD wasn't expired by ping"
4085 }
4086 run_test 36g "FMD cache expiry ====================="
4087
4088 test_36h() {
4089         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4090
4091         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4092         subr_36fh "0x80000227"
4093 }
4094 run_test 36h "utime on file racing with OST BRW write =========="
4095
4096 test_36i() {
4097         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4098
4099         test_mkdir $DIR/$tdir
4100         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4101
4102         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4103         local new_mtime=$((mtime + 200))
4104
4105         #change Modify time of striped dir
4106         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4107                         error "change mtime failed"
4108
4109         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4110
4111         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4112 }
4113 run_test 36i "change mtime on striped directory"
4114
4115 # test_37 - duplicate with tests 32q 32r
4116
4117 test_38() {
4118         local file=$DIR/$tfile
4119         touch $file
4120         openfile -f O_DIRECTORY $file
4121         local RC=$?
4122         local ENOTDIR=20
4123         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4124         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4125 }
4126 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4127
4128 test_39a() { # was test_39
4129         touch $DIR/$tfile
4130         touch $DIR/${tfile}2
4131 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4132 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4133 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4134         sleep 2
4135         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4136         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4137                 echo "mtime"
4138                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4139                 echo "atime"
4140                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4141                 echo "ctime"
4142                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4143                 error "O_TRUNC didn't change timestamps"
4144         fi
4145 }
4146 run_test 39a "mtime changed on create"
4147
4148 test_39b() {
4149         test_mkdir -c1 $DIR/$tdir
4150         cp -p /etc/passwd $DIR/$tdir/fopen
4151         cp -p /etc/passwd $DIR/$tdir/flink
4152         cp -p /etc/passwd $DIR/$tdir/funlink
4153         cp -p /etc/passwd $DIR/$tdir/frename
4154         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4155
4156         sleep 1
4157         echo "aaaaaa" >> $DIR/$tdir/fopen
4158         echo "aaaaaa" >> $DIR/$tdir/flink
4159         echo "aaaaaa" >> $DIR/$tdir/funlink
4160         echo "aaaaaa" >> $DIR/$tdir/frename
4161
4162         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4163         local link_new=`stat -c %Y $DIR/$tdir/flink`
4164         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4165         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4166
4167         cat $DIR/$tdir/fopen > /dev/null
4168         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4169         rm -f $DIR/$tdir/funlink2
4170         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4171
4172         for (( i=0; i < 2; i++ )) ; do
4173                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4174                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4175                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4176                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4177
4178                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4179                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4180                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4181                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4182
4183                 cancel_lru_locks $OSC
4184                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4185         done
4186 }
4187 run_test 39b "mtime change on open, link, unlink, rename  ======"
4188
4189 # this should be set to past
4190 TEST_39_MTIME=`date -d "1 year ago" +%s`
4191
4192 # bug 11063
4193 test_39c() {
4194         touch $DIR1/$tfile
4195         sleep 2
4196         local mtime0=`stat -c %Y $DIR1/$tfile`
4197
4198         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4199         local mtime1=`stat -c %Y $DIR1/$tfile`
4200         [ "$mtime1" = $TEST_39_MTIME ] || \
4201                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4202
4203         local d1=`date +%s`
4204         echo hello >> $DIR1/$tfile
4205         local d2=`date +%s`
4206         local mtime2=`stat -c %Y $DIR1/$tfile`
4207         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4208                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4209
4210         mv $DIR1/$tfile $DIR1/$tfile-1
4211
4212         for (( i=0; i < 2; i++ )) ; do
4213                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4214                 [ "$mtime2" = "$mtime3" ] || \
4215                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4216
4217                 cancel_lru_locks $OSC
4218                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4219         done
4220 }
4221 run_test 39c "mtime change on rename ==========================="
4222
4223 # bug 21114
4224 test_39d() {
4225         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4226
4227         touch $DIR1/$tfile
4228         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4229
4230         for (( i=0; i < 2; i++ )) ; do
4231                 local mtime=`stat -c %Y $DIR1/$tfile`
4232                 [ $mtime = $TEST_39_MTIME ] || \
4233                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4234
4235                 cancel_lru_locks $OSC
4236                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4237         done
4238 }
4239 run_test 39d "create, utime, stat =============================="
4240
4241 # bug 21114
4242 test_39e() {
4243         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4244
4245         touch $DIR1/$tfile
4246         local mtime1=`stat -c %Y $DIR1/$tfile`
4247
4248         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4249
4250         for (( i=0; i < 2; i++ )) ; do
4251                 local mtime2=`stat -c %Y $DIR1/$tfile`
4252                 [ $mtime2 = $TEST_39_MTIME ] || \
4253                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4254
4255                 cancel_lru_locks $OSC
4256                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4257         done
4258 }
4259 run_test 39e "create, stat, utime, stat ========================"
4260
4261 # bug 21114
4262 test_39f() {
4263         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4264
4265         touch $DIR1/$tfile
4266         mtime1=`stat -c %Y $DIR1/$tfile`
4267
4268         sleep 2
4269         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4270
4271         for (( i=0; i < 2; i++ )) ; do
4272                 local mtime2=`stat -c %Y $DIR1/$tfile`
4273                 [ $mtime2 = $TEST_39_MTIME ] || \
4274                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4275
4276                 cancel_lru_locks $OSC
4277                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4278         done
4279 }
4280 run_test 39f "create, stat, sleep, utime, stat ================="
4281
4282 # bug 11063
4283 test_39g() {
4284         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4285
4286         echo hello >> $DIR1/$tfile
4287         local mtime1=`stat -c %Y $DIR1/$tfile`
4288
4289         sleep 2
4290         chmod o+r $DIR1/$tfile
4291
4292         for (( i=0; i < 2; i++ )) ; do
4293                 local mtime2=`stat -c %Y $DIR1/$tfile`
4294                 [ "$mtime1" = "$mtime2" ] || \
4295                         error "lost mtime: $mtime2, should be $mtime1"
4296
4297                 cancel_lru_locks $OSC
4298                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4299         done
4300 }
4301 run_test 39g "write, chmod, stat ==============================="
4302
4303 # bug 11063
4304 test_39h() {
4305         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4306
4307         touch $DIR1/$tfile
4308         sleep 1
4309
4310         local d1=`date`
4311         echo hello >> $DIR1/$tfile
4312         local mtime1=`stat -c %Y $DIR1/$tfile`
4313
4314         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4315         local d2=`date`
4316         if [ "$d1" != "$d2" ]; then
4317                 echo "write and touch not within one second"
4318         else
4319                 for (( i=0; i < 2; i++ )) ; do
4320                         local mtime2=`stat -c %Y $DIR1/$tfile`
4321                         [ "$mtime2" = $TEST_39_MTIME ] || \
4322                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4323
4324                         cancel_lru_locks $OSC
4325                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4326                 done
4327         fi
4328 }
4329 run_test 39h "write, utime within one second, stat ============="
4330
4331 test_39i() {
4332         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4333
4334         touch $DIR1/$tfile
4335         sleep 1
4336
4337         echo hello >> $DIR1/$tfile
4338         local mtime1=`stat -c %Y $DIR1/$tfile`
4339
4340         mv $DIR1/$tfile $DIR1/$tfile-1
4341
4342         for (( i=0; i < 2; i++ )) ; do
4343                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4344
4345                 [ "$mtime1" = "$mtime2" ] || \
4346                         error "lost mtime: $mtime2, should be $mtime1"
4347
4348                 cancel_lru_locks $OSC
4349                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4350         done
4351 }
4352 run_test 39i "write, rename, stat =============================="
4353
4354 test_39j() {
4355         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4356
4357         start_full_debug_logging
4358         touch $DIR1/$tfile
4359         sleep 1
4360
4361         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4362         lctl set_param fail_loc=0x80000412
4363         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4364                 error "multiop failed"
4365         local multipid=$!
4366         local mtime1=`stat -c %Y $DIR1/$tfile`
4367
4368         mv $DIR1/$tfile $DIR1/$tfile-1
4369
4370         kill -USR1 $multipid
4371         wait $multipid || error "multiop close failed"
4372
4373         for (( i=0; i < 2; i++ )) ; do
4374                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4375                 [ "$mtime1" = "$mtime2" ] ||
4376                         error "mtime is lost on close: $mtime2, " \
4377                               "should be $mtime1"
4378
4379                 cancel_lru_locks
4380                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4381         done
4382         lctl set_param fail_loc=0
4383         stop_full_debug_logging
4384 }
4385 run_test 39j "write, rename, close, stat ======================="
4386
4387 test_39k() {
4388         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4389
4390         touch $DIR1/$tfile
4391         sleep 1
4392
4393         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4394         local multipid=$!
4395         local mtime1=`stat -c %Y $DIR1/$tfile`
4396
4397         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4398
4399         kill -USR1 $multipid
4400         wait $multipid || error "multiop close failed"
4401
4402         for (( i=0; i < 2; i++ )) ; do
4403                 local mtime2=`stat -c %Y $DIR1/$tfile`
4404
4405                 [ "$mtime2" = $TEST_39_MTIME ] || \
4406                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4407
4408                 cancel_lru_locks
4409                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4410         done
4411 }
4412 run_test 39k "write, utime, close, stat ========================"
4413
4414 # this should be set to future
4415 TEST_39_ATIME=`date -d "1 year" +%s`
4416
4417 test_39l() {
4418         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4419         remote_mds_nodsh && skip "remote MDS with nodsh"
4420
4421         local atime_diff=$(do_facet $SINGLEMDS \
4422                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4423         rm -rf $DIR/$tdir
4424         mkdir -p $DIR/$tdir
4425
4426         # test setting directory atime to future
4427         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4428         local atime=$(stat -c %X $DIR/$tdir)
4429         [ "$atime" = $TEST_39_ATIME ] ||
4430                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4431
4432         # test setting directory atime from future to now
4433         local now=$(date +%s)
4434         touch -a -d @$now $DIR/$tdir
4435
4436         atime=$(stat -c %X $DIR/$tdir)
4437         [ "$atime" -eq "$now"  ] ||
4438                 error "atime is not updated from future: $atime, $now"
4439
4440         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4441         sleep 3
4442
4443         # test setting directory atime when now > dir atime + atime_diff
4444         local d1=$(date +%s)
4445         ls $DIR/$tdir
4446         local d2=$(date +%s)
4447         cancel_lru_locks mdc
4448         atime=$(stat -c %X $DIR/$tdir)
4449         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4450                 error "atime is not updated  : $atime, should be $d2"
4451
4452         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4453         sleep 3
4454
4455         # test not setting directory atime when now < dir atime + atime_diff
4456         ls $DIR/$tdir
4457         cancel_lru_locks mdc
4458         atime=$(stat -c %X $DIR/$tdir)
4459         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4460                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4461
4462         do_facet $SINGLEMDS \
4463                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4464 }
4465 run_test 39l "directory atime update ==========================="
4466
4467 test_39m() {
4468         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4469
4470         touch $DIR1/$tfile
4471         sleep 2
4472         local far_past_mtime=$(date -d "May 29 1953" +%s)
4473         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4474
4475         touch -m -d @$far_past_mtime $DIR1/$tfile
4476         touch -a -d @$far_past_atime $DIR1/$tfile
4477
4478         for (( i=0; i < 2; i++ )) ; do
4479                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4480                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4481                         error "atime or mtime set incorrectly"
4482
4483                 cancel_lru_locks $OSC
4484                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4485         done
4486 }
4487 run_test 39m "test atime and mtime before 1970"
4488
4489 test_39n() { # LU-3832
4490         remote_mds_nodsh && skip "remote MDS with nodsh"
4491
4492         local atime_diff=$(do_facet $SINGLEMDS \
4493                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4494         local atime0
4495         local atime1
4496         local atime2
4497
4498         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4499
4500         rm -rf $DIR/$tfile
4501         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4502         atime0=$(stat -c %X $DIR/$tfile)
4503
4504         sleep 5
4505         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4506         atime1=$(stat -c %X $DIR/$tfile)
4507
4508         sleep 5
4509         cancel_lru_locks mdc
4510         cancel_lru_locks osc
4511         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4512         atime2=$(stat -c %X $DIR/$tfile)
4513
4514         do_facet $SINGLEMDS \
4515                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4516
4517         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4518         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4519 }
4520 run_test 39n "check that O_NOATIME is honored"
4521
4522 test_39o() {
4523         TESTDIR=$DIR/$tdir/$tfile
4524         [ -e $TESTDIR ] && rm -rf $TESTDIR
4525         mkdir -p $TESTDIR
4526         cd $TESTDIR
4527         links1=2
4528         ls
4529         mkdir a b
4530         ls
4531         links2=$(stat -c %h .)
4532         [ $(($links1 + 2)) != $links2 ] &&
4533                 error "wrong links count $(($links1 + 2)) != $links2"
4534         rmdir b
4535         links3=$(stat -c %h .)
4536         [ $(($links1 + 1)) != $links3 ] &&
4537                 error "wrong links count $links1 != $links3"
4538         return 0
4539 }
4540 run_test 39o "directory cached attributes updated after create"
4541
4542 test_39p() {
4543         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4544
4545         local MDTIDX=1
4546         TESTDIR=$DIR/$tdir/$tdir
4547         [ -e $TESTDIR ] && rm -rf $TESTDIR
4548         test_mkdir -p $TESTDIR
4549         cd $TESTDIR
4550         links1=2
4551         ls
4552         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4553         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4554         ls
4555         links2=$(stat -c %h .)
4556         [ $(($links1 + 2)) != $links2 ] &&
4557                 error "wrong links count $(($links1 + 2)) != $links2"
4558         rmdir remote_dir2
4559         links3=$(stat -c %h .)
4560         [ $(($links1 + 1)) != $links3 ] &&
4561                 error "wrong links count $links1 != $links3"
4562         return 0
4563 }
4564 run_test 39p "remote directory cached attributes updated after create ========"
4565
4566 test_39r() {
4567         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
4568                 skip "no atime update on old OST"
4569         if [ "$ost1_FSTYPE" != ldiskfs ]; then
4570                 skip_env "ldiskfs only test"
4571         fi
4572
4573         local saved_adiff
4574         saved_adiff=$(do_facet ost1 \
4575                 lctl get_param -n obdfilter.*OST0000.atime_diff)
4576         stack_trap "do_facet ost1 \
4577                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
4578
4579         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
4580
4581         $LFS setstripe -i 0 $DIR/$tfile
4582         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
4583                 error "can't write initial file"
4584         cancel_lru_locks osc
4585
4586         # exceed atime_diff and access file
4587         sleep 6
4588         dd if=$DIR/$tfile of=/dev/null || error "can't udpate atime"
4589
4590         local atime_cli=$(stat -c %X $DIR/$tfile)
4591         echo "client atime: $atime_cli"
4592         # allow atime update to be written to device
4593         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
4594         sleep 5
4595
4596         local ostdev=$(ostdevname 1)
4597         local fid=($(lfs getstripe -y $DIR/$tfile |
4598                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
4599         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
4600         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
4601
4602         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
4603         local atime_ost=$(do_facet ost1 "$cmd" |&
4604                           awk -F'[: ]' '/atime:/ { print $4 }')
4605         (( atime_cli == atime_ost )) ||
4606                 error "atime on client $atime_cli != ost $atime_ost"
4607 }
4608 run_test 39r "lazy atime update on OST"
4609
4610 test_39q() { # LU-8041
4611         local testdir=$DIR/$tdir
4612         mkdir -p $testdir
4613         multiop_bg_pause $testdir D_c || error "multiop failed"
4614         local multipid=$!
4615         cancel_lru_locks mdc
4616         kill -USR1 $multipid
4617         local atime=$(stat -c %X $testdir)
4618         [ "$atime" -ne 0 ] || error "atime is zero"
4619 }
4620 run_test 39q "close won't zero out atime"
4621
4622 test_40() {
4623         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
4624         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
4625                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
4626         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
4627                 error "$tfile is not 4096 bytes in size"
4628 }
4629 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
4630
4631 test_41() {
4632         # bug 1553
4633         small_write $DIR/f41 18
4634 }
4635 run_test 41 "test small file write + fstat ====================="
4636
4637 count_ost_writes() {
4638         lctl get_param -n ${OSC}.*.stats |
4639                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
4640                         END { printf("%0.0f", writes) }'
4641 }
4642
4643 # decent default
4644 WRITEBACK_SAVE=500
4645 DIRTY_RATIO_SAVE=40
4646 MAX_DIRTY_RATIO=50
4647 BG_DIRTY_RATIO_SAVE=10
4648 MAX_BG_DIRTY_RATIO=25
4649
4650 start_writeback() {
4651         trap 0
4652         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
4653         # dirty_ratio, dirty_background_ratio
4654         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4655                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
4656                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
4657                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
4658         else
4659                 # if file not here, we are a 2.4 kernel
4660                 kill -CONT `pidof kupdated`
4661         fi
4662 }
4663
4664 stop_writeback() {
4665         # setup the trap first, so someone cannot exit the test at the
4666         # exact wrong time and mess up a machine
4667         trap start_writeback EXIT
4668         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
4669         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4670                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
4671                 sysctl -w vm.dirty_writeback_centisecs=0
4672                 sysctl -w vm.dirty_writeback_centisecs=0
4673                 # save and increase /proc/sys/vm/dirty_ratio
4674                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
4675                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
4676                 # save and increase /proc/sys/vm/dirty_background_ratio
4677                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
4678                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
4679         else
4680                 # if file not here, we are a 2.4 kernel
4681                 kill -STOP `pidof kupdated`
4682         fi
4683 }
4684
4685 # ensure that all stripes have some grant before we test client-side cache
4686 setup_test42() {
4687         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
4688                 dd if=/dev/zero of=$i bs=4k count=1
4689                 rm $i
4690         done
4691 }
4692
4693 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
4694 # file truncation, and file removal.
4695 test_42a() {
4696         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4697
4698         setup_test42
4699         cancel_lru_locks $OSC
4700         stop_writeback
4701         sync; sleep 1; sync # just to be safe
4702         BEFOREWRITES=`count_ost_writes`
4703         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
4704         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
4705         AFTERWRITES=`count_ost_writes`
4706         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
4707                 error "$BEFOREWRITES < $AFTERWRITES"
4708         start_writeback
4709 }
4710 run_test 42a "ensure that we don't flush on close"
4711
4712 test_42b() {
4713         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4714
4715         setup_test42
4716         cancel_lru_locks $OSC
4717         stop_writeback
4718         sync
4719         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
4720         BEFOREWRITES=$(count_ost_writes)
4721         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
4722         AFTERWRITES=$(count_ost_writes)
4723         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4724                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
4725         fi
4726         BEFOREWRITES=$(count_ost_writes)
4727         sync || error "sync: $?"
4728         AFTERWRITES=$(count_ost_writes)
4729         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4730                 error "$BEFOREWRITES < $AFTERWRITES on sync"
4731         fi
4732         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
4733         start_writeback
4734         return 0
4735 }
4736 run_test 42b "test destroy of file with cached dirty data ======"
4737
4738 # if these tests just want to test the effect of truncation,
4739 # they have to be very careful.  consider:
4740 # - the first open gets a {0,EOF}PR lock
4741 # - the first write conflicts and gets a {0, count-1}PW
4742 # - the rest of the writes are under {count,EOF}PW
4743 # - the open for truncate tries to match a {0,EOF}PR
4744 #   for the filesize and cancels the PWs.
4745 # any number of fixes (don't get {0,EOF} on open, match
4746 # composite locks, do smarter file size management) fix
4747 # this, but for now we want these tests to verify that
4748 # the cancellation with truncate intent works, so we
4749 # start the file with a full-file pw lock to match against
4750 # until the truncate.
4751 trunc_test() {
4752         test=$1
4753         file=$DIR/$test
4754         offset=$2
4755         cancel_lru_locks $OSC
4756         stop_writeback
4757         # prime the file with 0,EOF PW to match
4758         touch $file
4759         $TRUNCATE $file 0
4760         sync; sync
4761         # now the real test..
4762         dd if=/dev/zero of=$file bs=1024 count=100
4763         BEFOREWRITES=`count_ost_writes`
4764         $TRUNCATE $file $offset
4765         cancel_lru_locks $OSC
4766         AFTERWRITES=`count_ost_writes`
4767         start_writeback
4768 }
4769
4770 test_42c() {
4771         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4772
4773         trunc_test 42c 1024
4774         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
4775                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
4776         rm $file
4777 }
4778 run_test 42c "test partial truncate of file with cached dirty data"
4779
4780 test_42d() {
4781         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4782
4783         trunc_test 42d 0
4784         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
4785                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
4786         rm $file
4787 }
4788 run_test 42d "test complete truncate of file with cached dirty data"
4789
4790 test_42e() { # bug22074
4791         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4792
4793         local TDIR=$DIR/${tdir}e
4794         local pages=16 # hardcoded 16 pages, don't change it.
4795         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
4796         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
4797         local max_dirty_mb
4798         local warmup_files
4799
4800         test_mkdir $DIR/${tdir}e
4801         $LFS setstripe -c 1 $TDIR
4802         createmany -o $TDIR/f $files
4803
4804         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
4805
4806         # we assume that with $OSTCOUNT files, at least one of them will
4807         # be allocated on OST0.
4808         warmup_files=$((OSTCOUNT * max_dirty_mb))
4809         createmany -o $TDIR/w $warmup_files
4810
4811         # write a large amount of data into one file and sync, to get good
4812         # avail_grant number from OST.
4813         for ((i=0; i<$warmup_files; i++)); do
4814                 idx=$($LFS getstripe -i $TDIR/w$i)
4815                 [ $idx -ne 0 ] && continue
4816                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
4817                 break
4818         done
4819         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
4820         sync
4821         $LCTL get_param $proc_osc0/cur_dirty_bytes
4822         $LCTL get_param $proc_osc0/cur_grant_bytes
4823
4824         # create as much dirty pages as we can while not to trigger the actual
4825         # RPCs directly. but depends on the env, VFS may trigger flush during this
4826         # period, hopefully we are good.
4827         for ((i=0; i<$warmup_files; i++)); do
4828                 idx=$($LFS getstripe -i $TDIR/w$i)
4829                 [ $idx -ne 0 ] && continue
4830                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
4831         done
4832         $LCTL get_param $proc_osc0/cur_dirty_bytes
4833         $LCTL get_param $proc_osc0/cur_grant_bytes
4834
4835         # perform the real test
4836         $LCTL set_param $proc_osc0/rpc_stats 0
4837         for ((;i<$files; i++)); do
4838                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
4839                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
4840         done
4841         sync
4842         $LCTL get_param $proc_osc0/rpc_stats
4843
4844         local percent=0
4845         local have_ppr=false
4846         $LCTL get_param $proc_osc0/rpc_stats |
4847                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
4848                         # skip lines until we are at the RPC histogram data
4849                         [ "$PPR" == "pages" ] && have_ppr=true && continue
4850                         $have_ppr || continue
4851
4852                         # we only want the percent stat for < 16 pages
4853                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
4854
4855                         percent=$((percent + WPCT))
4856                         if [[ $percent -gt 15 ]]; then
4857                                 error "less than 16-pages write RPCs" \
4858                                       "$percent% > 15%"
4859                                 break
4860                         fi
4861                 done
4862         rm -rf $TDIR
4863 }
4864 run_test 42e "verify sub-RPC writes are not done synchronously"
4865
4866 test_43A() { # was test_43
4867         test_mkdir $DIR/$tdir
4868         cp -p /bin/ls $DIR/$tdir/$tfile
4869         $MULTIOP $DIR/$tdir/$tfile Ow_c &
4870         pid=$!
4871         # give multiop a chance to open
4872         sleep 1
4873
4874         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
4875         kill -USR1 $pid
4876 }
4877 run_test 43A "execution of file opened for write should return -ETXTBSY"
4878
4879 test_43a() {
4880         test_mkdir $DIR/$tdir
4881         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4882         $DIR/$tdir/sleep 60 &
4883         SLEEP_PID=$!
4884         # Make sure exec of $tdir/sleep wins race with truncate
4885         sleep 1
4886         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
4887         kill $SLEEP_PID
4888 }
4889 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
4890
4891 test_43b() {
4892         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4893
4894         test_mkdir $DIR/$tdir
4895         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4896         $DIR/$tdir/sleep 60 &
4897         SLEEP_PID=$!
4898         # Make sure exec of $tdir/sleep wins race with truncate
4899         sleep 1
4900         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
4901         kill $SLEEP_PID
4902 }
4903 run_test 43b "truncate of file being executed should return -ETXTBSY"
4904
4905 test_43c() {
4906         local testdir="$DIR/$tdir"
4907         test_mkdir $testdir
4908         cp $SHELL $testdir/
4909         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
4910                 ( cd $testdir && md5sum -c )
4911 }
4912 run_test 43c "md5sum of copy into lustre"
4913
4914 test_44A() { # was test_44
4915         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4916
4917         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
4918         dd if=$DIR/f1 bs=4k count=1 > /dev/null
4919 }
4920 run_test 44A "zero length read from a sparse stripe"
4921
4922 test_44a() {
4923         local nstripe=$($LCTL lov_getconfig $DIR | grep default_stripe_count: |
4924                 awk '{ print $2 }')
4925         [ -z "$nstripe" ] && skip "can't get stripe info"
4926         [[ $nstripe -gt $OSTCOUNT ]] &&
4927                 skip "Wrong default_stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
4928
4929         local stride=$($LCTL lov_getconfig $DIR | grep default_stripe_size: |
4930                 awk '{ print $2 }')
4931         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
4932                 nstripe=$($LCTL lov_getconfig $DIR | grep obd_count: |
4933                         awk '{ print $2 }')
4934         fi
4935
4936         OFFSETS="0 $((stride/2)) $((stride-1))"
4937         for offset in $OFFSETS; do
4938                 for i in $(seq 0 $((nstripe-1))); do
4939                         local GLOBALOFFSETS=""
4940                         # size in Bytes
4941                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
4942                         local myfn=$DIR/d44a-$size
4943                         echo "--------writing $myfn at $size"
4944                         ll_sparseness_write $myfn $size ||
4945                                 error "ll_sparseness_write"
4946                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
4947                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4948                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4949
4950                         for j in $(seq 0 $((nstripe-1))); do
4951                                 # size in Bytes
4952                                 size=$((((j + $nstripe )*$stride + $offset)))
4953                                 ll_sparseness_write $myfn $size ||
4954                                         error "ll_sparseness_write"
4955                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
4956                         done
4957                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4958                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4959                         rm -f $myfn
4960                 done
4961         done
4962 }
4963 run_test 44a "test sparse pwrite ==============================="
4964
4965 dirty_osc_total() {
4966         tot=0
4967         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
4968                 tot=$(($tot + $d))
4969         done
4970         echo $tot
4971 }
4972 do_dirty_record() {
4973         before=`dirty_osc_total`
4974         echo executing "\"$*\""
4975         eval $*
4976         after=`dirty_osc_total`
4977         echo before $before, after $after
4978 }
4979 test_45() {
4980         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4981
4982         f="$DIR/f45"
4983         # Obtain grants from OST if it supports it
4984         echo blah > ${f}_grant
4985         stop_writeback
4986         sync
4987         do_dirty_record "echo blah > $f"
4988         [[ $before -eq $after ]] && error "write wasn't cached"
4989         do_dirty_record "> $f"
4990         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
4991         do_dirty_record "echo blah > $f"
4992         [[ $before -eq $after ]] && error "write wasn't cached"
4993         do_dirty_record "sync"
4994         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
4995         do_dirty_record "echo blah > $f"
4996         [[ $before -eq $after ]] && error "write wasn't cached"
4997         do_dirty_record "cancel_lru_locks osc"
4998         [[ $before -gt $after ]] ||
4999                 error "lock cancellation didn't lower dirty count"
5000         start_writeback
5001 }
5002 run_test 45 "osc io page accounting ============================"
5003
5004 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5005 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5006 # objects offset and an assert hit when an rpc was built with 1023's mapped
5007 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5008 test_46() {
5009         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5010
5011         f="$DIR/f46"
5012         stop_writeback
5013         sync
5014         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5015         sync
5016         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5017         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5018         sync
5019         start_writeback
5020 }
5021 run_test 46 "dirtying a previously written page ================"
5022
5023 # test_47 is removed "Device nodes check" is moved to test_28
5024
5025 test_48a() { # bug 2399
5026         [ "$mds1_FSTYPE" = "zfs" ] &&
5027         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5028                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5029
5030         test_mkdir $DIR/$tdir
5031         cd $DIR/$tdir
5032         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5033         test_mkdir $DIR/$tdir
5034         touch foo || error "'touch foo' failed after recreating cwd"
5035         test_mkdir bar
5036         touch .foo || error "'touch .foo' failed after recreating cwd"
5037         test_mkdir .bar
5038         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5039         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5040         cd . || error "'cd .' failed after recreating cwd"
5041         mkdir . && error "'mkdir .' worked after recreating cwd"
5042         rmdir . && error "'rmdir .' worked after recreating cwd"
5043         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5044         cd .. || error "'cd ..' failed after recreating cwd"
5045 }
5046 run_test 48a "Access renamed working dir (should return errors)="
5047
5048 test_48b() { # bug 2399
5049         rm -rf $DIR/$tdir
5050         test_mkdir $DIR/$tdir
5051         cd $DIR/$tdir
5052         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5053         touch foo && error "'touch foo' worked after removing cwd"
5054         mkdir foo && error "'mkdir foo' worked after removing cwd"
5055         touch .foo && error "'touch .foo' worked after removing cwd"
5056         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5057         ls . > /dev/null && error "'ls .' worked after removing cwd"
5058         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5059         mkdir . && error "'mkdir .' worked after removing cwd"
5060         rmdir . && error "'rmdir .' worked after removing cwd"
5061         ln -s . foo && error "'ln -s .' worked after removing cwd"
5062         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5063 }
5064 run_test 48b "Access removed working dir (should return errors)="
5065
5066 test_48c() { # bug 2350
5067         #lctl set_param debug=-1
5068         #set -vx
5069         rm -rf $DIR/$tdir
5070         test_mkdir -p $DIR/$tdir/dir
5071         cd $DIR/$tdir/dir
5072         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5073         $TRACE touch foo && error "touch foo worked after removing cwd"
5074         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5075         touch .foo && error "touch .foo worked after removing cwd"
5076         mkdir .foo && error "mkdir .foo worked after removing cwd"
5077         $TRACE ls . && error "'ls .' worked after removing cwd"
5078         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5079         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5080         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5081         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5082         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5083 }
5084 run_test 48c "Access removed working subdir (should return errors)"
5085
5086 test_48d() { # bug 2350
5087         #lctl set_param debug=-1
5088         #set -vx
5089         rm -rf $DIR/$tdir
5090         test_mkdir -p $DIR/$tdir/dir
5091         cd $DIR/$tdir/dir
5092         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5093         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5094         $TRACE touch foo && error "'touch foo' worked after removing parent"
5095         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5096         touch .foo && error "'touch .foo' worked after removing parent"
5097         mkdir .foo && error "mkdir .foo worked after removing parent"
5098         $TRACE ls . && error "'ls .' worked after removing parent"
5099         $TRACE ls .. && error "'ls ..' worked after removing parent"
5100         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5101         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5102         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5103         true
5104 }
5105 run_test 48d "Access removed parent subdir (should return errors)"
5106
5107 test_48e() { # bug 4134
5108         #lctl set_param debug=-1
5109         #set -vx
5110         rm -rf $DIR/$tdir
5111         test_mkdir -p $DIR/$tdir/dir
5112         cd $DIR/$tdir/dir
5113         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5114         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5115         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5116         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5117         # On a buggy kernel addition of "touch foo" after cd .. will
5118         # produce kernel oops in lookup_hash_it
5119         touch ../foo && error "'cd ..' worked after recreate parent"
5120         cd $DIR
5121         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5122 }
5123 run_test 48e "Access to recreated parent subdir (should return errors)"
5124
5125 test_49() { # LU-1030
5126         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5127         remote_ost_nodsh && skip "remote OST with nodsh"
5128
5129         # get ost1 size - $FSNAME-OST0000
5130         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5131                 awk '{ print $4 }')
5132         # write 800M at maximum
5133         [[ $ost1_size -lt 2 ]] && ost1_size=2
5134         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5135
5136         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5137         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5138         local dd_pid=$!
5139
5140         # change max_pages_per_rpc while writing the file
5141         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5142         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5143         # loop until dd process exits
5144         while ps ax -opid | grep -wq $dd_pid; do
5145                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5146                 sleep $((RANDOM % 5 + 1))
5147         done
5148         # restore original max_pages_per_rpc
5149         $LCTL set_param $osc1_mppc=$orig_mppc
5150         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5151 }
5152 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5153
5154 test_50() {
5155         # bug 1485
5156         test_mkdir $DIR/$tdir
5157         cd $DIR/$tdir
5158         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5159 }
5160 run_test 50 "special situations: /proc symlinks  ==============="
5161
5162 test_51a() {    # was test_51
5163         # bug 1516 - create an empty entry right after ".." then split dir
5164         test_mkdir -c1 $DIR/$tdir
5165         touch $DIR/$tdir/foo
5166         $MCREATE $DIR/$tdir/bar
5167         rm $DIR/$tdir/foo
5168         createmany -m $DIR/$tdir/longfile 201
5169         FNUM=202
5170         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5171                 $MCREATE $DIR/$tdir/longfile$FNUM
5172                 FNUM=$(($FNUM + 1))
5173                 echo -n "+"
5174         done
5175         echo
5176         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5177 }
5178 run_test 51a "special situations: split htree with empty entry =="
5179
5180 cleanup_print_lfs_df () {
5181         trap 0
5182         $LFS df
5183         $LFS df -i
5184 }
5185
5186 test_51b() {
5187         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5188
5189         local dir=$DIR/$tdir
5190         local nrdirs=$((65536 + 100))
5191
5192         # cleanup the directory
5193         rm -fr $dir
5194
5195         test_mkdir -c1 $dir
5196
5197         $LFS df
5198         $LFS df -i
5199         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5200         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5201         [[ $numfree -lt $nrdirs ]] &&
5202                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5203
5204         # need to check free space for the directories as well
5205         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5206         numfree=$(( blkfree / $(fs_inode_ksize) ))
5207         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5208
5209         trap cleanup_print_lfs_df EXIT
5210
5211         # create files
5212         createmany -d $dir/d $nrdirs || {
5213                 unlinkmany $dir/d $nrdirs
5214                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5215         }
5216
5217         # really created :
5218         nrdirs=$(ls -U $dir | wc -l)
5219
5220         # unlink all but 100 subdirectories, then check it still works
5221         local left=100
5222         local delete=$((nrdirs - left))
5223
5224         $LFS df
5225         $LFS df -i
5226
5227         # for ldiskfs the nlink count should be 1, but this is OSD specific
5228         # and so this is listed for informational purposes only
5229         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5230         unlinkmany -d $dir/d $delete ||
5231                 error "unlink of first $delete subdirs failed"
5232
5233         echo "nlink between: $(stat -c %h $dir)"
5234         local found=$(ls -U $dir | wc -l)
5235         [ $found -ne $left ] &&
5236                 error "can't find subdirs: found only $found, expected $left"
5237
5238         unlinkmany -d $dir/d $delete $left ||
5239                 error "unlink of second $left subdirs failed"
5240         # regardless of whether the backing filesystem tracks nlink accurately
5241         # or not, the nlink count shouldn't be more than "." and ".." here
5242         local after=$(stat -c %h $dir)
5243         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5244                 echo "nlink after: $after"
5245
5246         cleanup_print_lfs_df
5247 }
5248 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5249
5250 test_51d() {
5251         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5252         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5253
5254         test_mkdir $DIR/$tdir
5255         createmany -o $DIR/$tdir/t- 1000
5256         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5257         for N in $(seq 0 $((OSTCOUNT - 1))); do
5258                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
5259                         END { printf("%0.0f", objs) }' $TMP/$tfile)
5260                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5261                         '($1 == '$N') { objs += 1 } \
5262                         END { printf("%0.0f", objs) }')
5263                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
5264         done
5265         unlinkmany $DIR/$tdir/t- 1000
5266
5267         NLAST=0
5268         for N in $(seq 1 $((OSTCOUNT - 1))); do
5269                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
5270                         error "OST $N has less objects vs OST $NLAST" \
5271                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5272                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
5273                         error "OST $N has less objects vs OST $NLAST" \
5274                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5275
5276                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
5277                         error "OST $N has less #0 objects vs OST $NLAST" \
5278                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5279                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
5280                         error "OST $N has less #0 objects vs OST $NLAST" \
5281                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5282                 NLAST=$N
5283         done
5284         rm -f $TMP/$tfile
5285 }
5286 run_test 51d "check object distribution"
5287
5288 test_51e() {
5289         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5290                 skip_env "ldiskfs only test"
5291         fi
5292
5293         test_mkdir -c1 $DIR/$tdir
5294         test_mkdir -c1 $DIR/$tdir/d0
5295
5296         touch $DIR/$tdir/d0/foo
5297         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5298                 error "file exceed 65000 nlink limit!"
5299         unlinkmany $DIR/$tdir/d0/f- 65001
5300         return 0
5301 }
5302 run_test 51e "check file nlink limit"
5303
5304 test_51f() {
5305         test_mkdir $DIR/$tdir
5306
5307         local max=100000
5308         local ulimit_old=$(ulimit -n)
5309         local spare=20 # number of spare fd's for scripts/libraries, etc.
5310         local mdt=$($LFS getstripe -m $DIR/$tdir)
5311         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5312
5313         echo "MDT$mdt numfree=$numfree, max=$max"
5314         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5315         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5316                 while ! ulimit -n $((numfree + spare)); do
5317                         numfree=$((numfree * 3 / 4))
5318                 done
5319                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5320         else
5321                 echo "left ulimit at $ulimit_old"
5322         fi
5323
5324         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5325                 unlinkmany $DIR/$tdir/f $numfree
5326                 error "create+open $numfree files in $DIR/$tdir failed"
5327         }
5328         ulimit -n $ulimit_old
5329
5330         # if createmany exits at 120s there will be fewer than $numfree files
5331         unlinkmany $DIR/$tdir/f $numfree || true
5332 }
5333 run_test 51f "check many open files limit"
5334
5335 test_52a() {
5336         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5337         test_mkdir $DIR/$tdir
5338         touch $DIR/$tdir/foo
5339         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5340         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5341         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5342         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5343         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5344                                         error "link worked"
5345         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5346         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5347         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5348                                                      error "lsattr"
5349         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5350         cp -r $DIR/$tdir $TMP/
5351         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5352 }
5353 run_test 52a "append-only flag test (should return errors)"
5354
5355 test_52b() {
5356         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5357         test_mkdir $DIR/$tdir
5358         touch $DIR/$tdir/foo
5359         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5360         cat test > $DIR/$tdir/foo && error "cat test worked"
5361         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5362         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5363         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5364                                         error "link worked"
5365         echo foo >> $DIR/$tdir/foo && error "echo worked"
5366         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5367         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5368         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5369         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5370                                                         error "lsattr"
5371         chattr -i $DIR/$tdir/foo || error "chattr failed"
5372
5373         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5374 }
5375 run_test 52b "immutable flag test (should return errors) ======="
5376
5377 test_53() {
5378         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5379         remote_mds_nodsh && skip "remote MDS with nodsh"
5380         remote_ost_nodsh && skip "remote OST with nodsh"
5381
5382         local param
5383         local param_seq
5384         local ostname
5385         local mds_last
5386         local mds_last_seq
5387         local ost_last
5388         local ost_last_seq
5389         local ost_last_id
5390         local ostnum
5391         local node
5392         local found=false
5393         local support_last_seq=true
5394
5395         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5396                 support_last_seq=false
5397
5398         # only test MDT0000
5399         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5400         local value
5401         for value in $(do_facet $SINGLEMDS \
5402                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5403                 param=$(echo ${value[0]} | cut -d "=" -f1)
5404                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5405
5406                 if $support_last_seq; then
5407                         param_seq=$(echo $param |
5408                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5409                         mds_last_seq=$(do_facet $SINGLEMDS \
5410                                        $LCTL get_param -n $param_seq)
5411                 fi
5412                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5413
5414                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5415                 node=$(facet_active_host ost$((ostnum+1)))
5416                 param="obdfilter.$ostname.last_id"
5417                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5418                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5419                         ost_last_id=$ost_last
5420
5421                         if $support_last_seq; then
5422                                 ost_last_id=$(echo $ost_last |
5423                                               awk -F':' '{print $2}' |
5424                                               sed -e "s/^0x//g")
5425                                 ost_last_seq=$(echo $ost_last |
5426                                                awk -F':' '{print $1}')
5427                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5428                         fi
5429
5430                         if [[ $ost_last_id != $mds_last ]]; then
5431                                 error "$ost_last_id != $mds_last"
5432                         else
5433                                 found=true
5434                                 break
5435                         fi
5436                 done
5437         done
5438         $found || error "can not match last_seq/last_id for $mdtosc"
5439         return 0
5440 }
5441 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5442
5443 test_54a() {
5444         perl -MSocket -e ';' || skip "no Socket perl module installed"
5445
5446         $SOCKETSERVER $DIR/socket ||
5447                 error "$SOCKETSERVER $DIR/socket failed: $?"
5448         $SOCKETCLIENT $DIR/socket ||
5449                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5450         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5451 }
5452 run_test 54a "unix domain socket test =========================="
5453
5454 test_54b() {
5455         f="$DIR/f54b"
5456         mknod $f c 1 3
5457         chmod 0666 $f
5458         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5459 }
5460 run_test 54b "char device works in lustre ======================"
5461
5462 find_loop_dev() {
5463         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5464         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5465         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5466
5467         for i in $(seq 3 7); do
5468                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5469                 LOOPDEV=$LOOPBASE$i
5470                 LOOPNUM=$i
5471                 break
5472         done
5473 }
5474
5475 cleanup_54c() {
5476         local rc=0
5477         loopdev="$DIR/loop54c"
5478
5479         trap 0
5480         $UMOUNT $DIR/$tdir || rc=$?
5481         losetup -d $loopdev || true
5482         losetup -d $LOOPDEV || true
5483         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5484         return $rc
5485 }
5486
5487 test_54c() {
5488         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5489
5490         loopdev="$DIR/loop54c"
5491
5492         find_loop_dev
5493         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5494         trap cleanup_54c EXIT
5495         mknod $loopdev b 7 $LOOPNUM
5496         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5497         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5498         losetup $loopdev $DIR/$tfile ||
5499                 error "can't set up $loopdev for $DIR/$tfile"
5500         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5501         test_mkdir $DIR/$tdir
5502         mount -t ext2 $loopdev $DIR/$tdir ||
5503                 error "error mounting $loopdev on $DIR/$tdir"
5504         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5505                 error "dd write"
5506         df $DIR/$tdir
5507         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5508                 error "dd read"
5509         cleanup_54c
5510 }
5511 run_test 54c "block device works in lustre ====================="
5512
5513 test_54d() {
5514         f="$DIR/f54d"
5515         string="aaaaaa"
5516         mknod $f p
5517         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5518 }
5519 run_test 54d "fifo device works in lustre ======================"
5520
5521 test_54e() {
5522         f="$DIR/f54e"
5523         string="aaaaaa"
5524         cp -aL /dev/console $f
5525         echo $string > $f || error "echo $string to $f failed"
5526 }
5527 run_test 54e "console/tty device works in lustre ======================"
5528
5529 test_56a() {
5530         local numfiles=3
5531         local dir=$DIR/$tdir
5532
5533         rm -rf $dir
5534         test_mkdir -p $dir/dir
5535         for i in $(seq $numfiles); do
5536                 touch $dir/file$i
5537                 touch $dir/dir/file$i
5538         done
5539
5540         local numcomp=$($LFS getstripe --component-count $dir)
5541
5542         [[ $numcomp == 0 ]] && numcomp=1
5543
5544         # test lfs getstripe with --recursive
5545         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5546
5547         [[ $filenum -eq $((numfiles * 2)) ]] ||
5548                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5549         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5550         [[ $filenum -eq $numfiles ]] ||
5551                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5552         echo "$LFS getstripe showed obdidx or l_ost_idx"
5553
5554         # test lfs getstripe with file instead of dir
5555         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5556         [[ $filenum -eq 1 ]] ||
5557                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5558         echo "$LFS getstripe file1 passed"
5559
5560         #test lfs getstripe with --verbose
5561         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5562         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5563                 error "$LFS getstripe --verbose $dir: "\
5564                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5565         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5566                 error "$LFS getstripe $dir: showed lmm_magic"
5567
5568         #test lfs getstripe with -v prints lmm_fid
5569         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5570         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5571                 error "$LFS getstripe -v $dir: "\
5572                       "got $filenum want $((numfiles * numcomp)) lmm_fid"
5573         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5574                 error "$LFS getstripe $dir: showed lmm_fid by default"
5575         echo "$LFS getstripe --verbose passed"
5576
5577         #check for FID information
5578         local fid1=$($LFS getstripe --fid $dir/file1)
5579         local fid2=$($LFS getstripe --verbose $dir/file1 |
5580                      awk '/lmm_fid: / { print $2; exit; }')
5581         local fid3=$($LFS path2fid $dir/file1)
5582
5583         [ "$fid1" != "$fid2" ] &&
5584                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5585         [ "$fid1" != "$fid3" ] &&
5586                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5587         echo "$LFS getstripe --fid passed"
5588
5589         #test lfs getstripe with --obd
5590         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
5591                 error "$LFS getstripe --obd wrong_uuid: should return error"
5592
5593         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5594
5595         local ostidx=1
5596         local obduuid=$(ostuuid_from_index $ostidx)
5597         local found=$($LFS getstripe -r --obd $obduuid $dir |
5598                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
5599
5600         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
5601         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
5602                 ((filenum--))
5603         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
5604                 ((filenum--))
5605
5606         [[ $found -eq $filenum ]] ||
5607                 error "$LFS getstripe --obd: found $found expect $filenum"
5608         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
5609                 sed '/^[         ]*'${ostidx}'[  ]/d' |
5610                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
5611                 error "$LFS getstripe --obd: should not show file on other obd"
5612         echo "$LFS getstripe --obd passed"
5613 }
5614 run_test 56a "check $LFS getstripe"
5615
5616 test_56b() {
5617         local dir=$DIR/$tdir
5618         local numdirs=3
5619
5620         test_mkdir $dir
5621         for i in $(seq $numdirs); do
5622                 test_mkdir $dir/dir$i
5623         done
5624
5625         # test lfs getdirstripe default mode is non-recursion, which is
5626         # different from lfs getstripe
5627         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
5628
5629         [[ $dircnt -eq 1 ]] ||
5630                 error "$LFS getdirstripe: found $dircnt, not 1"
5631         dircnt=$($LFS getdirstripe --recursive $dir |
5632                 grep -c lmv_stripe_count)
5633         [[ $dircnt -eq $((numdirs + 1)) ]] ||
5634                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
5635 }
5636 run_test 56b "check $LFS getdirstripe"
5637
5638 test_56c() {
5639         remote_ost_nodsh && skip "remote OST with nodsh"
5640
5641         local ost_idx=0
5642         local ost_name=$(ostname_from_index $ost_idx)
5643         local old_status=$(ost_dev_status $ost_idx)
5644         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
5645
5646         [[ -z "$old_status" ]] ||
5647                 skip_env "OST $ost_name is in $old_status status"
5648
5649         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
5650         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
5651                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
5652         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
5653                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
5654                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
5655         fi
5656
5657         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
5658                 error "$LFS df -v showing inactive devices"
5659         sleep_maxage
5660
5661         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
5662
5663         [[ "$new_status" =~ "D" ]] ||
5664                 error "$ost_name status is '$new_status', missing 'D'"
5665         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
5666                 [[ "$new_status" =~ "N" ]] ||
5667                         error "$ost_name status is '$new_status', missing 'N'"
5668         fi
5669         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
5670                 [[ "$new_status" =~ "f" ]] ||
5671                         error "$ost_name status is '$new_status', missing 'f'"
5672         fi
5673
5674         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
5675         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
5676                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
5677         [[ -z "$p" ]] && restore_lustre_params < $p || true
5678         sleep_maxage
5679
5680         new_status=$(ost_dev_status $ost_idx)
5681         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
5682                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
5683         # can't check 'f' as devices may actually be on flash
5684 }
5685 run_test 56c "check 'lfs df' showing device status"
5686
5687 test_56d() {
5688         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
5689         local osts=$($LFS df -v $MOUNT | grep -c OST)
5690
5691         $LFS df $MOUNT
5692
5693         (( mdts == MDSCOUNT )) ||
5694                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
5695         (( osts == OSTCOUNT )) ||
5696                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
5697 }
5698 run_test 56d "'lfs df -v' prints only configured devices"
5699
5700 NUMFILES=3
5701 NUMDIRS=3
5702 setup_56() {
5703         local local_tdir="$1"
5704         local local_numfiles="$2"
5705         local local_numdirs="$3"
5706         local dir_params="$4"
5707         local dir_stripe_params="$5"
5708
5709         if [ ! -d "$local_tdir" ] ; then
5710                 test_mkdir -p $dir_stripe_params $local_tdir
5711                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
5712                 for i in $(seq $local_numfiles) ; do
5713                         touch $local_tdir/file$i
5714                 done
5715                 for i in $(seq $local_numdirs) ; do
5716                         test_mkdir $dir_stripe_params $local_tdir/dir$i
5717                         for j in $(seq $local_numfiles) ; do
5718                                 touch $local_tdir/dir$i/file$j
5719                         done
5720                 done
5721         fi
5722 }
5723
5724 setup_56_special() {
5725         local local_tdir=$1
5726         local local_numfiles=$2
5727         local local_numdirs=$3
5728
5729         setup_56 $local_tdir $local_numfiles $local_numdirs
5730
5731         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
5732                 for i in $(seq $local_numfiles) ; do
5733                         mknod $local_tdir/loop${i}b b 7 $i
5734                         mknod $local_tdir/null${i}c c 1 3
5735                         ln -s $local_tdir/file1 $local_tdir/link${i}
5736                 done
5737                 for i in $(seq $local_numdirs) ; do
5738                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
5739                         mknod $local_tdir/dir$i/null${i}c c 1 3
5740                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
5741                 done
5742         fi
5743 }
5744
5745 test_56g() {
5746         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5747         local expected=$(($NUMDIRS + 2))
5748
5749         setup_56 $dir $NUMFILES $NUMDIRS
5750
5751         # test lfs find with -name
5752         for i in $(seq $NUMFILES) ; do
5753                 local nums=$($LFS find -name "*$i" $dir | wc -l)
5754
5755                 [ $nums -eq $expected ] ||
5756                         error "lfs find -name '*$i' $dir wrong: "\
5757                               "found $nums, expected $expected"
5758         done
5759 }
5760 run_test 56g "check lfs find -name"
5761
5762 test_56h() {
5763         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5764         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
5765
5766         setup_56 $dir $NUMFILES $NUMDIRS
5767
5768         # test lfs find with ! -name
5769         for i in $(seq $NUMFILES) ; do
5770                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
5771
5772                 [ $nums -eq $expected ] ||
5773                         error "lfs find ! -name '*$i' $dir wrong: "\
5774                               "found $nums, expected $expected"
5775         done
5776 }
5777 run_test 56h "check lfs find ! -name"
5778
5779 test_56i() {
5780         local dir=$DIR/$tdir
5781
5782         test_mkdir $dir
5783
5784         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
5785         local out=$($cmd)
5786
5787         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
5788 }
5789 run_test 56i "check 'lfs find -ost UUID' skips directories"
5790
5791 test_56j() {
5792         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5793
5794         setup_56_special $dir $NUMFILES $NUMDIRS
5795
5796         local expected=$((NUMDIRS + 1))
5797         local cmd="$LFS find -type d $dir"
5798         local nums=$($cmd | wc -l)
5799
5800         [ $nums -eq $expected ] ||
5801                 error "'$cmd' wrong: found $nums, expected $expected"
5802 }
5803 run_test 56j "check lfs find -type d"
5804
5805 test_56k() {
5806         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5807
5808         setup_56_special $dir $NUMFILES $NUMDIRS
5809
5810         local expected=$(((NUMDIRS + 1) * NUMFILES))
5811         local cmd="$LFS find -type f $dir"
5812         local nums=$($cmd | wc -l)
5813
5814         [ $nums -eq $expected ] ||
5815                 error "'$cmd' wrong: found $nums, expected $expected"
5816 }
5817 run_test 56k "check lfs find -type f"
5818
5819 test_56l() {
5820         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5821
5822         setup_56_special $dir $NUMFILES $NUMDIRS
5823
5824         local expected=$((NUMDIRS + NUMFILES))
5825         local cmd="$LFS find -type b $dir"
5826         local nums=$($cmd | wc -l)
5827
5828         [ $nums -eq $expected ] ||
5829                 error "'$cmd' wrong: found $nums, expected $expected"
5830 }
5831 run_test 56l "check lfs find -type b"
5832
5833 test_56m() {
5834         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5835
5836         setup_56_special $dir $NUMFILES $NUMDIRS
5837
5838         local expected=$((NUMDIRS + NUMFILES))
5839         local cmd="$LFS find -type c $dir"
5840         local nums=$($cmd | wc -l)
5841         [ $nums -eq $expected ] ||
5842                 error "'$cmd' wrong: found $nums, expected $expected"
5843 }
5844 run_test 56m "check lfs find -type c"
5845
5846 test_56n() {
5847         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5848         setup_56_special $dir $NUMFILES $NUMDIRS
5849
5850         local expected=$((NUMDIRS + NUMFILES))
5851         local cmd="$LFS find -type l $dir"
5852         local nums=$($cmd | wc -l)
5853
5854         [ $nums -eq $expected ] ||
5855                 error "'$cmd' wrong: found $nums, expected $expected"
5856 }
5857 run_test 56n "check lfs find -type l"
5858
5859 test_56o() {
5860         local dir=$DIR/$tdir
5861
5862         setup_56 $dir $NUMFILES $NUMDIRS
5863         utime $dir/file1 > /dev/null || error "utime (1)"
5864         utime $dir/file2 > /dev/null || error "utime (2)"
5865         utime $dir/dir1 > /dev/null || error "utime (3)"
5866         utime $dir/dir2 > /dev/null || error "utime (4)"
5867         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
5868         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
5869
5870         local expected=4
5871         local nums=$($LFS find -mtime +0 $dir | wc -l)
5872
5873         [ $nums -eq $expected ] ||
5874                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
5875
5876         expected=12
5877         cmd="$LFS find -mtime 0 $dir"
5878         nums=$($cmd | wc -l)
5879         [ $nums -eq $expected ] ||
5880                 error "'$cmd' wrong: found $nums, expected $expected"
5881 }
5882 run_test 56o "check lfs find -mtime for old files"
5883
5884 test_56ob() {
5885         local dir=$DIR/$tdir
5886         local expected=1
5887         local count=0
5888
5889         # just to make sure there is something that won't be found
5890         test_mkdir $dir
5891         touch $dir/$tfile.now
5892
5893         for age in year week day hour min; do
5894                 count=$((count + 1))
5895
5896                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
5897                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
5898                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
5899
5900                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
5901                 local nums=$($cmd | wc -l)
5902                 [ $nums -eq $expected ] ||
5903                         error "'$cmd' wrong: found $nums, expected $expected"
5904
5905                 cmd="$LFS find $dir -atime $count${age:0:1}"
5906                 nums=$($cmd | wc -l)
5907                 [ $nums -eq $expected ] ||
5908                         error "'$cmd' wrong: found $nums, expected $expected"
5909         done
5910
5911         sleep 2
5912         cmd="$LFS find $dir -ctime +1s -type f"
5913         nums=$($cmd | wc -l)
5914         (( $nums == $count * 2 + 1)) ||
5915                 error "'$cmd' wrong: found $nums, expected $((expected*2+1))"
5916 }
5917 run_test 56ob "check lfs find -atime -mtime -ctime with units"
5918
5919 test_newerXY_base() {
5920         local x=$1
5921         local y=$2
5922         local dir=$DIR/$tdir
5923         local ref
5924         local negref
5925
5926         if [ $y == "t" ]; then
5927                 if [ $x == "b" ]; then
5928                         ref="\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\""
5929                 else
5930                         ref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
5931                 fi
5932         else
5933                 ref=$DIR/$tfile.newer.$x$y
5934                 touch $ref || error "touch $ref failed"
5935         fi
5936         sleep 2
5937         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
5938         sleep 2
5939         if [ $y == "t" ]; then
5940                 if [ $x == "b" ]; then
5941                         negref="\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\""
5942                 else
5943                         negref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
5944                 fi
5945         else
5946                 negref=$DIR/$tfile.negnewer.$x$y
5947                 touch $negref || error "touch $negref failed"
5948         fi
5949
5950         local cmd="$LFS find $dir -newer$x$y $ref"
5951         local nums=$(eval $cmd | wc -l)
5952         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
5953
5954         [ $nums -eq $expected ] ||
5955                 error "'$cmd' wrong: found $nums, expected $expected"
5956
5957         cmd="$LFS find $dir ! -newer$x$y $negref"
5958         nums=$(eval $cmd | wc -l)
5959         [ $nums -eq $expected ] ||
5960                 error "'$cmd' wrong: found $nums, expected $expected"
5961
5962         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
5963         nums=$(eval $cmd | wc -l)
5964         [ $nums -eq $expected ] ||
5965                 error "'$cmd' wrong: found $nums, expected $expected"
5966
5967         rm -rf $DIR/*
5968 }
5969
5970 test_56oc() {
5971         test_newerXY_base "b" "t"
5972         test_newerXY_base "a" "a"
5973         test_newerXY_base "a" "m"
5974         test_newerXY_base "a" "c"
5975         test_newerXY_base "m" "a"
5976         test_newerXY_base "m" "m"
5977         test_newerXY_base "m" "c"
5978         test_newerXY_base "c" "a"
5979         test_newerXY_base "c" "m"
5980         test_newerXY_base "c" "c"
5981         test_newerXY_base "b" "b"
5982         test_newerXY_base "a" "t"
5983         test_newerXY_base "m" "t"
5984         test_newerXY_base "c" "t"
5985         test_newerXY_base "b" "t"
5986 }
5987 run_test 56oc "check lfs find -newerXY work"
5988
5989 btime_supported() {
5990         local dir=$DIR/$tdir
5991         local rc
5992
5993         mkdir -p $dir
5994         touch $dir/$tfile
5995         $LFS find $dir -btime -1d -type f
5996         rc=$?
5997         rm -rf $dir
5998         return $rc
5999 }
6000
6001 test_56od() {
6002         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6003                 ! btime_supported && skip "btime unsupported on MDS"
6004
6005         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6006                 ! btime_supported && skip "btime unsupported on clients"
6007
6008         local dir=$DIR/$tdir
6009         local ref=$DIR/$tfile.ref
6010         local negref=$DIR/$tfile.negref
6011
6012         mkdir $dir || error "mkdir $dir failed"
6013         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6014         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6015         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6016         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6017         touch $ref || error "touch $ref failed"
6018         # sleep 3 seconds at least
6019         sleep 3
6020
6021         local before=$(do_facet mds1 date +%s)
6022         local skew=$(($(date +%s) - before + 1))
6023
6024         if (( skew < 0 && skew > -5 )); then
6025                 sleep $((0 - skew + 1))
6026                 skew=0
6027         fi
6028
6029         # Set the dir stripe params to limit files all on MDT0,
6030         # otherwise we need to calc the max clock skew between
6031         # the client and MDTs.
6032         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6033         sleep 2
6034         touch $negref || error "touch $negref failed"
6035
6036         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6037         local nums=$($cmd | wc -l)
6038         local expected=$(((NUMFILES + 1) * NUMDIRS))
6039
6040         [ $nums -eq $expected ] ||
6041                 error "'$cmd' wrong: found $nums, expected $expected"
6042
6043         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6044         nums=$($cmd | wc -l)
6045         expected=$((NUMFILES + 1))
6046         [ $nums -eq $expected ] ||
6047                 error "'$cmd' wrong: found $nums, expected $expected"
6048
6049         [ $skew -lt 0 ] && return
6050
6051         local after=$(do_facet mds1 date +%s)
6052         local age=$((after - before + 1 + skew))
6053
6054         cmd="$LFS find $dir -btime -${age}s -type f"
6055         nums=$($cmd | wc -l)
6056         expected=$(((NUMFILES + 1) * NUMDIRS))
6057
6058         echo "Clock skew between client and server: $skew, age:$age"
6059         [ $nums -eq $expected ] ||
6060                 error "'$cmd' wrong: found $nums, expected $expected"
6061
6062         expected=$(($NUMDIRS + 1))
6063         cmd="$LFS find $dir -btime -${age}s -type d"
6064         nums=$($cmd | wc -l)
6065         [ $nums -eq $expected ] ||
6066                 error "'$cmd' wrong: found $nums, expected $expected"
6067         rm -f $ref $negref || error "Failed to remove $ref $negref"
6068 }
6069 run_test 56od "check lfs find -btime with units"
6070
6071 test_56p() {
6072         [ $RUNAS_ID -eq $UID ] &&
6073                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6074
6075         local dir=$DIR/$tdir
6076
6077         setup_56 $dir $NUMFILES $NUMDIRS
6078         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6079
6080         local expected=$NUMFILES
6081         local cmd="$LFS find -uid $RUNAS_ID $dir"
6082         local nums=$($cmd | wc -l)
6083
6084         [ $nums -eq $expected ] ||
6085                 error "'$cmd' wrong: found $nums, expected $expected"
6086
6087         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6088         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6089         nums=$($cmd | wc -l)
6090         [ $nums -eq $expected ] ||
6091                 error "'$cmd' wrong: found $nums, expected $expected"
6092 }
6093 run_test 56p "check lfs find -uid and ! -uid"
6094
6095 test_56q() {
6096         [ $RUNAS_ID -eq $UID ] &&
6097                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6098
6099         local dir=$DIR/$tdir
6100
6101         setup_56 $dir $NUMFILES $NUMDIRS
6102         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6103
6104         local expected=$NUMFILES
6105         local cmd="$LFS find -gid $RUNAS_GID $dir"
6106         local nums=$($cmd | wc -l)
6107
6108         [ $nums -eq $expected ] ||
6109                 error "'$cmd' wrong: found $nums, expected $expected"
6110
6111         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6112         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6113         nums=$($cmd | wc -l)
6114         [ $nums -eq $expected ] ||
6115                 error "'$cmd' wrong: found $nums, expected $expected"
6116 }
6117 run_test 56q "check lfs find -gid and ! -gid"
6118
6119 test_56r() {
6120         local dir=$DIR/$tdir
6121
6122         setup_56 $dir $NUMFILES $NUMDIRS
6123
6124         local expected=12
6125         local cmd="$LFS find -size 0 -type f -lazy $dir"
6126         local nums=$($cmd | wc -l)
6127
6128         [ $nums -eq $expected ] ||
6129                 error "'$cmd' wrong: found $nums, expected $expected"
6130         cmd="$LFS find -size 0 -type f $dir"
6131         nums=$($cmd | wc -l)
6132         [ $nums -eq $expected ] ||
6133                 error "'$cmd' wrong: found $nums, expected $expected"
6134
6135         expected=0
6136         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6137         nums=$($cmd | wc -l)
6138         [ $nums -eq $expected ] ||
6139                 error "'$cmd' wrong: found $nums, expected $expected"
6140         cmd="$LFS find ! -size 0 -type f $dir"
6141         nums=$($cmd | wc -l)
6142         [ $nums -eq $expected ] ||
6143                 error "'$cmd' wrong: found $nums, expected $expected"
6144
6145         echo "test" > $dir/$tfile
6146         echo "test2" > $dir/$tfile.2 && sync
6147         expected=1
6148         cmd="$LFS find -size 5 -type f -lazy $dir"
6149         nums=$($cmd | wc -l)
6150         [ $nums -eq $expected ] ||
6151                 error "'$cmd' wrong: found $nums, expected $expected"
6152         cmd="$LFS find -size 5 -type f $dir"
6153         nums=$($cmd | wc -l)
6154         [ $nums -eq $expected ] ||
6155                 error "'$cmd' wrong: found $nums, expected $expected"
6156
6157         expected=1
6158         cmd="$LFS find -size +5 -type f -lazy $dir"
6159         nums=$($cmd | wc -l)
6160         [ $nums -eq $expected ] ||
6161                 error "'$cmd' wrong: found $nums, expected $expected"
6162         cmd="$LFS find -size +5 -type f $dir"
6163         nums=$($cmd | wc -l)
6164         [ $nums -eq $expected ] ||
6165                 error "'$cmd' wrong: found $nums, expected $expected"
6166
6167         expected=2
6168         cmd="$LFS find -size +0 -type f -lazy $dir"
6169         nums=$($cmd | wc -l)
6170         [ $nums -eq $expected ] ||
6171                 error "'$cmd' wrong: found $nums, expected $expected"
6172         cmd="$LFS find -size +0 -type f $dir"
6173         nums=$($cmd | wc -l)
6174         [ $nums -eq $expected ] ||
6175                 error "'$cmd' wrong: found $nums, expected $expected"
6176
6177         expected=2
6178         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6179         nums=$($cmd | wc -l)
6180         [ $nums -eq $expected ] ||
6181                 error "'$cmd' wrong: found $nums, expected $expected"
6182         cmd="$LFS find ! -size -5 -type f $dir"
6183         nums=$($cmd | wc -l)
6184         [ $nums -eq $expected ] ||
6185                 error "'$cmd' wrong: found $nums, expected $expected"
6186
6187         expected=12
6188         cmd="$LFS find -size -5 -type f -lazy $dir"
6189         nums=$($cmd | wc -l)
6190         [ $nums -eq $expected ] ||
6191                 error "'$cmd' wrong: found $nums, expected $expected"
6192         cmd="$LFS find -size -5 -type f $dir"
6193         nums=$($cmd | wc -l)
6194         [ $nums -eq $expected ] ||
6195                 error "'$cmd' wrong: found $nums, expected $expected"
6196 }
6197 run_test 56r "check lfs find -size works"
6198
6199 test_56ra_sub() {
6200         local expected=$1
6201         local glimpses=$2
6202         local cmd="$3"
6203
6204         cancel_lru_locks $OSC
6205
6206         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6207         local nums=$($cmd | wc -l)
6208
6209         [ $nums -eq $expected ] ||
6210                 error "'$cmd' wrong: found $nums, expected $expected"
6211
6212         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6213
6214         if (( rpcs_before + glimpses != rpcs_after )); then
6215                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6216                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6217
6218                 if [[ $glimpses == 0 ]]; then
6219                         error "'$cmd' should not send glimpse RPCs to OST"
6220                 else
6221                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6222                 fi
6223         fi
6224 }
6225
6226 test_56ra() {
6227         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6228                 skip "MDS < 2.12.58 doesn't return LSOM data"
6229         local dir=$DIR/$tdir
6230
6231         [[ $OSC == "mdc" ]] && skip "DoM files" && return
6232
6233         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6234         # open and close all files to ensure LSOM is updated
6235         cancel_lru_locks $OSC
6236         find $dir -type f | xargs cat > /dev/null
6237
6238         #   expect_found  glimpse_rpcs  command_to_run
6239         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6240         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6241         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6242         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6243
6244         echo "test" > $dir/$tfile
6245         echo "test2" > $dir/$tfile.2 && sync
6246         cancel_lru_locks $OSC
6247         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6248
6249         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6250         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6251         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6252         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6253
6254         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6255         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6256         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6257         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6258         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6259         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6260 }
6261 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6262
6263 test_56rb() {
6264         local dir=$DIR/$tdir
6265         local tmp=$TMP/$tfile.log
6266         local mdt_idx;
6267
6268         test_mkdir -p $dir || error "failed to mkdir $dir"
6269         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6270                 error "failed to setstripe $dir/$tfile"
6271         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6272
6273         stack_trap "rm -f $tmp" EXIT
6274         $LFS find --size +100K --ost 0 $dir 2>&1 | tee $tmp
6275         [ -z "$(cat $tmp | grep "obd_uuid: ")" ] ||
6276                 error "failed to find --size +100K --ost 0 $dir"
6277         $LFS find --size +100K --mdt $mdt_idx $dir 2>&1 | tee $tmp
6278         [ -z "$(cat $tmp | grep "obd_uuid: ")" ] ||
6279                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6280 }
6281 run_test 56rb "check lfs find --size --ost/--mdt works"
6282
6283 test_56s() { # LU-611 #LU-9369
6284         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6285
6286         local dir=$DIR/$tdir
6287         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6288
6289         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6290         for i in $(seq $NUMDIRS); do
6291                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6292         done
6293
6294         local expected=$NUMDIRS
6295         local cmd="$LFS find -c $OSTCOUNT $dir"
6296         local nums=$($cmd | wc -l)
6297
6298         [ $nums -eq $expected ] || {
6299                 $LFS getstripe -R $dir
6300                 error "'$cmd' wrong: found $nums, expected $expected"
6301         }
6302
6303         expected=$((NUMDIRS + onestripe))
6304         cmd="$LFS find -stripe-count +0 -type f $dir"
6305         nums=$($cmd | wc -l)
6306         [ $nums -eq $expected ] || {
6307                 $LFS getstripe -R $dir
6308                 error "'$cmd' wrong: found $nums, expected $expected"
6309         }
6310
6311         expected=$onestripe
6312         cmd="$LFS find -stripe-count 1 -type f $dir"
6313         nums=$($cmd | wc -l)
6314         [ $nums -eq $expected ] || {
6315                 $LFS getstripe -R $dir
6316                 error "'$cmd' wrong: found $nums, expected $expected"
6317         }
6318
6319         cmd="$LFS find -stripe-count -2 -type f $dir"
6320         nums=$($cmd | wc -l)
6321         [ $nums -eq $expected ] || {
6322                 $LFS getstripe -R $dir
6323                 error "'$cmd' wrong: found $nums, expected $expected"
6324         }
6325
6326         expected=0
6327         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6328         nums=$($cmd | wc -l)
6329         [ $nums -eq $expected ] || {
6330                 $LFS getstripe -R $dir
6331                 error "'$cmd' wrong: found $nums, expected $expected"
6332         }
6333 }
6334 run_test 56s "check lfs find -stripe-count works"
6335
6336 test_56t() { # LU-611 #LU-9369
6337         local dir=$DIR/$tdir
6338
6339         setup_56 $dir 0 $NUMDIRS
6340         for i in $(seq $NUMDIRS); do
6341                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6342         done
6343
6344         local expected=$NUMDIRS
6345         local cmd="$LFS find -S 8M $dir"
6346         local nums=$($cmd | wc -l)
6347
6348         [ $nums -eq $expected ] || {
6349                 $LFS getstripe -R $dir
6350                 error "'$cmd' wrong: found $nums, expected $expected"
6351         }
6352         rm -rf $dir
6353
6354         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6355
6356         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6357
6358         expected=$(((NUMDIRS + 1) * NUMFILES))
6359         cmd="$LFS find -stripe-size 512k -type f $dir"
6360         nums=$($cmd | wc -l)
6361         [ $nums -eq $expected ] ||
6362                 error "'$cmd' wrong: found $nums, expected $expected"
6363
6364         cmd="$LFS find -stripe-size +320k -type f $dir"
6365         nums=$($cmd | wc -l)
6366         [ $nums -eq $expected ] ||
6367                 error "'$cmd' wrong: found $nums, expected $expected"
6368
6369         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6370         cmd="$LFS find -stripe-size +200k -type f $dir"
6371         nums=$($cmd | wc -l)
6372         [ $nums -eq $expected ] ||
6373                 error "'$cmd' wrong: found $nums, expected $expected"
6374
6375         cmd="$LFS find -stripe-size -640k -type f $dir"
6376         nums=$($cmd | wc -l)
6377         [ $nums -eq $expected ] ||
6378                 error "'$cmd' wrong: found $nums, expected $expected"
6379
6380         expected=4
6381         cmd="$LFS find -stripe-size 256k -type f $dir"
6382         nums=$($cmd | wc -l)
6383         [ $nums -eq $expected ] ||
6384                 error "'$cmd' wrong: found $nums, expected $expected"
6385
6386         cmd="$LFS find -stripe-size -320k -type f $dir"
6387         nums=$($cmd | wc -l)
6388         [ $nums -eq $expected ] ||
6389                 error "'$cmd' wrong: found $nums, expected $expected"
6390
6391         expected=0
6392         cmd="$LFS find -stripe-size 1024k -type f $dir"
6393         nums=$($cmd | wc -l)
6394         [ $nums -eq $expected ] ||
6395                 error "'$cmd' wrong: found $nums, expected $expected"
6396 }
6397 run_test 56t "check lfs find -stripe-size works"
6398
6399 test_56u() { # LU-611
6400         local dir=$DIR/$tdir
6401
6402         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6403
6404         if [[ $OSTCOUNT -gt 1 ]]; then
6405                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6406                 onestripe=4
6407         else
6408                 onestripe=0
6409         fi
6410
6411         local expected=$(((NUMDIRS + 1) * NUMFILES))
6412         local cmd="$LFS find -stripe-index 0 -type f $dir"
6413         local nums=$($cmd | wc -l)
6414
6415         [ $nums -eq $expected ] ||
6416                 error "'$cmd' wrong: found $nums, expected $expected"
6417
6418         expected=$onestripe
6419         cmd="$LFS find -stripe-index 1 -type f $dir"
6420         nums=$($cmd | wc -l)
6421         [ $nums -eq $expected ] ||
6422                 error "'$cmd' wrong: found $nums, expected $expected"
6423
6424         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6425         nums=$($cmd | wc -l)
6426         [ $nums -eq $expected ] ||
6427                 error "'$cmd' wrong: found $nums, expected $expected"
6428
6429         expected=0
6430         # This should produce an error and not return any files
6431         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
6432         nums=$($cmd 2>/dev/null | wc -l)
6433         [ $nums -eq $expected ] ||
6434                 error "'$cmd' wrong: found $nums, expected $expected"
6435
6436         if [[ $OSTCOUNT -gt 1 ]]; then
6437                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
6438                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
6439                 nums=$($cmd | wc -l)
6440                 [ $nums -eq $expected ] ||
6441                         error "'$cmd' wrong: found $nums, expected $expected"
6442         fi
6443 }
6444 run_test 56u "check lfs find -stripe-index works"
6445
6446 test_56v() {
6447         local mdt_idx=0
6448         local dir=$DIR/$tdir
6449
6450         setup_56 $dir $NUMFILES $NUMDIRS
6451
6452         UUID=$(mdtuuid_from_index $mdt_idx $dir)
6453         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
6454
6455         for file in $($LFS find -m $UUID $dir); do
6456                 file_midx=$($LFS getstripe -m $file)
6457                 [ $file_midx -eq $mdt_idx ] ||
6458                         error "lfs find -m $UUID != getstripe -m $file_midx"
6459         done
6460 }
6461 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
6462
6463 test_56w() {
6464         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6465         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6466
6467         local dir=$DIR/$tdir
6468
6469         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
6470
6471         local stripe_size=$($LFS getstripe -S -d $dir) ||
6472                 error "$LFS getstripe -S -d $dir failed"
6473         stripe_size=${stripe_size%% *}
6474
6475         local file_size=$((stripe_size * OSTCOUNT))
6476         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
6477         local required_space=$((file_num * file_size))
6478         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
6479                            head -n1)
6480         [[ $free_space -le $((required_space / 1024)) ]] &&
6481                 skip_env "need $required_space, have $free_space kbytes"
6482
6483         local dd_bs=65536
6484         local dd_count=$((file_size / dd_bs))
6485
6486         # write data into the files
6487         local i
6488         local j
6489         local file
6490
6491         for i in $(seq $NUMFILES); do
6492                 file=$dir/file$i
6493                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6494                         error "write data into $file failed"
6495         done
6496         for i in $(seq $NUMDIRS); do
6497                 for j in $(seq $NUMFILES); do
6498                         file=$dir/dir$i/file$j
6499                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6500                                 error "write data into $file failed"
6501                 done
6502         done
6503
6504         # $LFS_MIGRATE will fail if hard link migration is unsupported
6505         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
6506                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
6507                         error "creating links to $dir/dir1/file1 failed"
6508         fi
6509
6510         local expected=-1
6511
6512         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
6513
6514         # lfs_migrate file
6515         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
6516
6517         echo "$cmd"
6518         eval $cmd || error "$cmd failed"
6519
6520         check_stripe_count $dir/file1 $expected
6521
6522         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
6523         then
6524                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
6525                 # OST 1 if it is on OST 0. This file is small enough to
6526                 # be on only one stripe.
6527                 file=$dir/migr_1_ost
6528                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
6529                         error "write data into $file failed"
6530                 local obdidx=$($LFS getstripe -i $file)
6531                 local oldmd5=$(md5sum $file)
6532                 local newobdidx=0
6533
6534                 [[ $obdidx -eq 0 ]] && newobdidx=1
6535                 cmd="$LFS migrate -i $newobdidx $file"
6536                 echo $cmd
6537                 eval $cmd || error "$cmd failed"
6538
6539                 local realobdix=$($LFS getstripe -i $file)
6540                 local newmd5=$(md5sum $file)
6541
6542                 [[ $newobdidx -ne $realobdix ]] &&
6543                         error "new OST is different (was=$obdidx, "\
6544                               "wanted=$newobdidx, got=$realobdix)"
6545                 [[ "$oldmd5" != "$newmd5" ]] &&
6546                         error "md5sum differ: $oldmd5, $newmd5"
6547         fi
6548
6549         # lfs_migrate dir
6550         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
6551         echo "$cmd"
6552         eval $cmd || error "$cmd failed"
6553
6554         for j in $(seq $NUMFILES); do
6555                 check_stripe_count $dir/dir1/file$j $expected
6556         done
6557
6558         # lfs_migrate works with lfs find
6559         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
6560              $LFS_MIGRATE -y -c $expected"
6561         echo "$cmd"
6562         eval $cmd || error "$cmd failed"
6563
6564         for i in $(seq 2 $NUMFILES); do
6565                 check_stripe_count $dir/file$i $expected
6566         done
6567         for i in $(seq 2 $NUMDIRS); do
6568                 for j in $(seq $NUMFILES); do
6569                 check_stripe_count $dir/dir$i/file$j $expected
6570                 done
6571         done
6572 }
6573 run_test 56w "check lfs_migrate -c stripe_count works"
6574
6575 test_56wb() {
6576         local file1=$DIR/$tdir/file1
6577         local create_pool=false
6578         local initial_pool=$($LFS getstripe -p $DIR)
6579         local pool_list=()
6580         local pool=""
6581
6582         echo -n "Creating test dir..."
6583         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6584         echo "done."
6585
6586         echo -n "Creating test file..."
6587         touch $file1 || error "cannot create file"
6588         echo "done."
6589
6590         echo -n "Detecting existing pools..."
6591         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
6592
6593         if [ ${#pool_list[@]} -gt 0 ]; then
6594                 echo "${pool_list[@]}"
6595                 for thispool in "${pool_list[@]}"; do
6596                         if [[ -z "$initial_pool" ||
6597                               "$initial_pool" != "$thispool" ]]; then
6598                                 pool="$thispool"
6599                                 echo "Using existing pool '$pool'"
6600                                 break
6601                         fi
6602                 done
6603         else
6604                 echo "none detected."
6605         fi
6606         if [ -z "$pool" ]; then
6607                 pool=${POOL:-testpool}
6608                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
6609                 echo -n "Creating pool '$pool'..."
6610                 create_pool=true
6611                 pool_add $pool &> /dev/null ||
6612                         error "pool_add failed"
6613                 echo "done."
6614
6615                 echo -n "Adding target to pool..."
6616                 pool_add_targets $pool 0 0 1 &> /dev/null ||
6617                         error "pool_add_targets failed"
6618                 echo "done."
6619         fi
6620
6621         echo -n "Setting pool using -p option..."
6622         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
6623                 error "migrate failed rc = $?"
6624         echo "done."
6625
6626         echo -n "Verifying test file is in pool after migrating..."
6627         [ "$($LFS getstripe -p $file1)" = $pool ] ||
6628                 error "file was not migrated to pool $pool"
6629         echo "done."
6630
6631         echo -n "Removing test file from pool '$pool'..."
6632         # "lfs migrate $file" won't remove the file from the pool
6633         # until some striping information is changed.
6634         $LFS migrate -c 1 $file1 &> /dev/null ||
6635                 error "cannot remove from pool"
6636         [ "$($LFS getstripe -p $file1)" ] &&
6637                 error "pool still set"
6638         echo "done."
6639
6640         echo -n "Setting pool using --pool option..."
6641         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
6642                 error "migrate failed rc = $?"
6643         echo "done."
6644
6645         # Clean up
6646         rm -f $file1
6647         if $create_pool; then
6648                 destroy_test_pools 2> /dev/null ||
6649                         error "destroy test pools failed"
6650         fi
6651 }
6652 run_test 56wb "check lfs_migrate pool support"
6653
6654 test_56wc() {
6655         local file1="$DIR/$tdir/file1"
6656         local parent_ssize
6657         local parent_scount
6658         local cur_ssize
6659         local cur_scount
6660         local orig_ssize
6661
6662         echo -n "Creating test dir..."
6663         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6664         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
6665                 error "cannot set stripe by '-S 1M -c 1'"
6666         echo "done"
6667
6668         echo -n "Setting initial stripe for test file..."
6669         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
6670                 error "cannot set stripe"
6671         cur_ssize=$($LFS getstripe -S "$file1")
6672         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
6673         echo "done."
6674
6675         # File currently set to -S 512K -c 1
6676
6677         # Ensure -c and -S options are rejected when -R is set
6678         echo -n "Verifying incompatible options are detected..."
6679         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
6680                 error "incompatible -c and -R options not detected"
6681         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
6682                 error "incompatible -S and -R options not detected"
6683         echo "done."
6684
6685         # Ensure unrecognized options are passed through to 'lfs migrate'
6686         echo -n "Verifying -S option is passed through to lfs migrate..."
6687         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
6688                 error "migration failed"
6689         cur_ssize=$($LFS getstripe -S "$file1")
6690         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
6691         echo "done."
6692
6693         # File currently set to -S 1M -c 1
6694
6695         # Ensure long options are supported
6696         echo -n "Verifying long options supported..."
6697         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
6698                 error "long option without argument not supported"
6699         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
6700                 error "long option with argument not supported"
6701         cur_ssize=$($LFS getstripe -S "$file1")
6702         [ $cur_ssize -eq 524288 ] ||
6703                 error "migrate --stripe-size $cur_ssize != 524288"
6704         echo "done."
6705
6706         # File currently set to -S 512K -c 1
6707
6708         if [ "$OSTCOUNT" -gt 1 ]; then
6709                 echo -n "Verifying explicit stripe count can be set..."
6710                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
6711                         error "migrate failed"
6712                 cur_scount=$($LFS getstripe -c "$file1")
6713                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
6714                 echo "done."
6715         fi
6716
6717         # File currently set to -S 512K -c 1 or -S 512K -c 2
6718
6719         # Ensure parent striping is used if -R is set, and no stripe
6720         # count or size is specified
6721         echo -n "Setting stripe for parent directory..."
6722         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6723                 error "cannot set stripe '-S 2M -c 1'"
6724         echo "done."
6725
6726         echo -n "Verifying restripe option uses parent stripe settings..."
6727         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
6728         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
6729         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
6730                 error "migrate failed"
6731         cur_ssize=$($LFS getstripe -S "$file1")
6732         [ $cur_ssize -eq $parent_ssize ] ||
6733                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
6734         cur_scount=$($LFS getstripe -c "$file1")
6735         [ $cur_scount -eq $parent_scount ] ||
6736                 error "migrate -R stripe_count $cur_scount != $parent_scount"
6737         echo "done."
6738
6739         # File currently set to -S 1M -c 1
6740
6741         # Ensure striping is preserved if -R is not set, and no stripe
6742         # count or size is specified
6743         echo -n "Verifying striping size preserved when not specified..."
6744         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
6745         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6746                 error "cannot set stripe on parent directory"
6747         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6748                 error "migrate failed"
6749         cur_ssize=$($LFS getstripe -S "$file1")
6750         [ $cur_ssize -eq $orig_ssize ] ||
6751                 error "migrate by default $cur_ssize != $orig_ssize"
6752         echo "done."
6753
6754         # Ensure file name properly detected when final option has no argument
6755         echo -n "Verifying file name properly detected..."
6756         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6757                 error "file name interpreted as option argument"
6758         echo "done."
6759
6760         # Clean up
6761         rm -f "$file1"
6762 }
6763 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
6764
6765 test_56wd() {
6766         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6767
6768         local file1=$DIR/$tdir/file1
6769
6770         echo -n "Creating test dir..."
6771         test_mkdir $DIR/$tdir || error "cannot create dir"
6772         echo "done."
6773
6774         echo -n "Creating test file..."
6775         touch $file1
6776         echo "done."
6777
6778         # Ensure 'lfs migrate' will fail by using a non-existent option,
6779         # and make sure rsync is not called to recover
6780         echo -n "Make sure --no-rsync option works..."
6781         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
6782                 grep -q 'refusing to fall back to rsync' ||
6783                 error "rsync was called with --no-rsync set"
6784         echo "done."
6785
6786         # Ensure rsync is called without trying 'lfs migrate' first
6787         echo -n "Make sure --rsync option works..."
6788         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
6789                 grep -q 'falling back to rsync' &&
6790                 error "lfs migrate was called with --rsync set"
6791         echo "done."
6792
6793         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
6794         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
6795                 grep -q 'at the same time' ||
6796                 error "--rsync and --no-rsync accepted concurrently"
6797         echo "done."
6798
6799         # Clean up
6800         rm -f $file1
6801 }
6802 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
6803
6804 test_56we() {
6805         local td=$DIR/$tdir
6806         local tf=$td/$tfile
6807
6808         test_mkdir $td || error "cannot create $td"
6809         touch $tf || error "cannot touch $tf"
6810
6811         echo -n "Make sure --non-direct|-D works..."
6812         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
6813                 grep -q "lfs migrate --non-direct" ||
6814                 error "--non-direct option cannot work correctly"
6815         $LFS_MIGRATE -y -D -v $tf 2>&1 |
6816                 grep -q "lfs migrate -D" ||
6817                 error "-D option cannot work correctly"
6818         echo "done."
6819 }
6820 run_test 56we "check lfs_migrate --non-direct|-D support"
6821
6822 test_56x() {
6823         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6824         check_swap_layouts_support
6825
6826         local dir=$DIR/$tdir
6827         local ref1=/etc/passwd
6828         local file1=$dir/file1
6829
6830         test_mkdir $dir || error "creating dir $dir"
6831         $LFS setstripe -c 2 $file1
6832         cp $ref1 $file1
6833         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
6834         stripe=$($LFS getstripe -c $file1)
6835         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6836         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6837
6838         # clean up
6839         rm -f $file1
6840 }
6841 run_test 56x "lfs migration support"
6842
6843 test_56xa() {
6844         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6845         check_swap_layouts_support
6846
6847         local dir=$DIR/$tdir/$testnum
6848
6849         test_mkdir -p $dir
6850
6851         local ref1=/etc/passwd
6852         local file1=$dir/file1
6853
6854         $LFS setstripe -c 2 $file1
6855         cp $ref1 $file1
6856         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
6857
6858         local stripe=$($LFS getstripe -c $file1)
6859
6860         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6861         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6862
6863         # clean up
6864         rm -f $file1
6865 }
6866 run_test 56xa "lfs migration --block support"
6867
6868 check_migrate_links() {
6869         local dir="$1"
6870         local file1="$dir/file1"
6871         local begin="$2"
6872         local count="$3"
6873         local runas="$4"
6874         local total_count=$(($begin + $count - 1))
6875         local symlink_count=10
6876         local uniq_count=10
6877
6878         if [ ! -f "$file1" ]; then
6879                 echo -n "creating initial file..."
6880                 $LFS setstripe -c 1 -S "512k" "$file1" ||
6881                         error "cannot setstripe initial file"
6882                 echo "done"
6883
6884                 echo -n "creating symlinks..."
6885                 for s in $(seq 1 $symlink_count); do
6886                         ln -s "$file1" "$dir/slink$s" ||
6887                                 error "cannot create symlinks"
6888                 done
6889                 echo "done"
6890
6891                 echo -n "creating nonlinked files..."
6892                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
6893                         error "cannot create nonlinked files"
6894                 echo "done"
6895         fi
6896
6897         # create hard links
6898         if [ ! -f "$dir/file$total_count" ]; then
6899                 echo -n "creating hard links $begin:$total_count..."
6900                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
6901                         /dev/null || error "cannot create hard links"
6902                 echo "done"
6903         fi
6904
6905         echo -n "checking number of hard links listed in xattrs..."
6906         local fid=$($LFS getstripe -F "$file1")
6907         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
6908
6909         echo "${#paths[*]}"
6910         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
6911                         skip "hard link list has unexpected size, skipping test"
6912         fi
6913         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
6914                         error "link names should exceed xattrs size"
6915         fi
6916
6917         echo -n "migrating files..."
6918         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
6919         local rc=$?
6920         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
6921         echo "done"
6922
6923         # make sure all links have been properly migrated
6924         echo -n "verifying files..."
6925         fid=$($LFS getstripe -F "$file1") ||
6926                 error "cannot get fid for file $file1"
6927         for i in $(seq 2 $total_count); do
6928                 local fid2=$($LFS getstripe -F $dir/file$i)
6929
6930                 [ "$fid2" == "$fid" ] ||
6931                         error "migrated hard link has mismatched FID"
6932         done
6933
6934         # make sure hard links were properly detected, and migration was
6935         # performed only once for the entire link set; nonlinked files should
6936         # also be migrated
6937         local actual=$(grep -c 'done' <<< "$migrate_out")
6938         local expected=$(($uniq_count + 1))
6939
6940         [ "$actual" -eq  "$expected" ] ||
6941                 error "hard links individually migrated ($actual != $expected)"
6942
6943         # make sure the correct number of hard links are present
6944         local hardlinks=$(stat -c '%h' "$file1")
6945
6946         [ $hardlinks -eq $total_count ] ||
6947                 error "num hard links $hardlinks != $total_count"
6948         echo "done"
6949
6950         return 0
6951 }
6952
6953 test_56xb() {
6954         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
6955                 skip "Need MDS version at least 2.10.55"
6956
6957         local dir="$DIR/$tdir"
6958
6959         test_mkdir "$dir" || error "cannot create dir $dir"
6960
6961         echo "testing lfs migrate mode when all links fit within xattrs"
6962         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
6963
6964         echo "testing rsync mode when all links fit within xattrs"
6965         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
6966
6967         echo "testing lfs migrate mode when all links do not fit within xattrs"
6968         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
6969
6970         echo "testing rsync mode when all links do not fit within xattrs"
6971         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
6972
6973         chown -R $RUNAS_ID $dir
6974         echo "testing non-root lfs migrate mode when not all links are in xattr"
6975         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
6976
6977         # clean up
6978         rm -rf $dir
6979 }
6980 run_test 56xb "lfs migration hard link support"
6981
6982 test_56xc() {
6983         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6984
6985         local dir="$DIR/$tdir"
6986
6987         test_mkdir "$dir" || error "cannot create dir $dir"
6988
6989         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
6990         echo -n "Setting initial stripe for 20MB test file..."
6991         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
6992                 error "cannot setstripe 20MB file"
6993         echo "done"
6994         echo -n "Sizing 20MB test file..."
6995         truncate "$dir/20mb" 20971520 || error "cannot create 20MB test file"
6996         echo "done"
6997         echo -n "Verifying small file autostripe count is 1..."
6998         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
6999                 error "cannot migrate 20MB file"
7000         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7001                 error "cannot get stripe for $dir/20mb"
7002         [ $stripe_count -eq 1 ] ||
7003                 error "unexpected stripe count $stripe_count for 20MB file"
7004         rm -f "$dir/20mb"
7005         echo "done"
7006
7007         # Test 2: File is small enough to fit within the available space on
7008         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7009         # have at least an additional 1KB for each desired stripe for test 3
7010         echo -n "Setting stripe for 1GB test file..."
7011         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7012         echo "done"
7013         echo -n "Sizing 1GB test file..."
7014         # File size is 1GB + 3KB
7015         truncate "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7016         echo "done"
7017
7018         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7019         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7020         if (( avail > 524288 * OSTCOUNT )); then
7021                 echo -n "Migrating 1GB file..."
7022                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7023                         error "cannot migrate 1GB file"
7024                 echo "done"
7025                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7026                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7027                         error "cannot getstripe for 1GB file"
7028                 [ $stripe_count -eq 2 ] ||
7029                         error "unexpected stripe count $stripe_count != 2"
7030                 echo "done"
7031         fi
7032
7033         # Test 3: File is too large to fit within the available space on
7034         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7035         if [ $OSTCOUNT -ge 3 ]; then
7036                 # The required available space is calculated as
7037                 # file size (1GB + 3KB) / OST count (3).
7038                 local kb_per_ost=349526
7039
7040                 echo -n "Migrating 1GB file with limit..."
7041                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7042                         error "cannot migrate 1GB file with limit"
7043                 echo "done"
7044
7045                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7046                 echo -n "Verifying 1GB autostripe count with limited space..."
7047                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7048                         error "unexpected stripe count $stripe_count (min 3)"
7049                 echo "done"
7050         fi
7051
7052         # clean up
7053         rm -rf $dir
7054 }
7055 run_test 56xc "lfs migration autostripe"
7056
7057 test_56xd() {
7058         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7059
7060         local dir=$DIR/$tdir
7061         local f_mgrt=$dir/$tfile.mgrt
7062         local f_yaml=$dir/$tfile.yaml
7063         local f_copy=$dir/$tfile.copy
7064         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7065         local layout_copy="-c 2 -S 2M -i 1"
7066         local yamlfile=$dir/yamlfile
7067         local layout_before;
7068         local layout_after;
7069
7070         test_mkdir "$dir" || error "cannot create dir $dir"
7071         $LFS setstripe $layout_yaml $f_yaml ||
7072                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7073         $LFS getstripe --yaml $f_yaml > $yamlfile
7074         $LFS setstripe $layout_copy $f_copy ||
7075                 error "cannot setstripe $f_copy with layout $layout_copy"
7076         touch $f_mgrt
7077         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7078
7079         # 1. test option --yaml
7080         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7081                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7082         layout_before=$(get_layout_param $f_yaml)
7083         layout_after=$(get_layout_param $f_mgrt)
7084         [ "$layout_after" == "$layout_before" ] ||
7085                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7086
7087         # 2. test option --copy
7088         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7089                 error "cannot migrate $f_mgrt with --copy $f_copy"
7090         layout_before=$(get_layout_param $f_copy)
7091         layout_after=$(get_layout_param $f_mgrt)
7092         [ "$layout_after" == "$layout_before" ] ||
7093                 error "lfs_migrate --copy: $layout_after != $layout_before"
7094 }
7095 run_test 56xd "check lfs_migrate --yaml and --copy support"
7096
7097 test_56xe() {
7098         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7099
7100         local dir=$DIR/$tdir
7101         local f_comp=$dir/$tfile
7102         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7103         local layout_before=""
7104         local layout_after=""
7105
7106         test_mkdir "$dir" || error "cannot create dir $dir"
7107         $LFS setstripe $layout $f_comp ||
7108                 error "cannot setstripe $f_comp with layout $layout"
7109         layout_before=$(get_layout_param $f_comp)
7110         dd if=/dev/zero of=$f_comp bs=1M count=4
7111
7112         # 1. migrate a comp layout file by lfs_migrate
7113         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7114         layout_after=$(get_layout_param $f_comp)
7115         [ "$layout_before" == "$layout_after" ] ||
7116                 error "lfs_migrate: $layout_before != $layout_after"
7117
7118         # 2. migrate a comp layout file by lfs migrate
7119         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7120         layout_after=$(get_layout_param $f_comp)
7121         [ "$layout_before" == "$layout_after" ] ||
7122                 error "lfs migrate: $layout_before != $layout_after"
7123 }
7124 run_test 56xe "migrate a composite layout file"
7125
7126 test_56xf() {
7127         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7128
7129         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7130                 skip "Need server version at least 2.13.53"
7131
7132         local dir=$DIR/$tdir
7133         local f_comp=$dir/$tfile
7134         local layout="-E 1M -c1 -E -1 -c2"
7135         local fid_before=""
7136         local fid_after=""
7137
7138         test_mkdir "$dir" || error "cannot create dir $dir"
7139         $LFS setstripe $layout $f_comp ||
7140                 error "cannot setstripe $f_comp with layout $layout"
7141         fid_before=$($LFS getstripe --fid $f_comp)
7142         dd if=/dev/zero of=$f_comp bs=1M count=4
7143
7144         # 1. migrate a comp layout file to a comp layout
7145         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7146         fid_after=$($LFS getstripe --fid $f_comp)
7147         [ "$fid_before" == "$fid_after" ] ||
7148                 error "comp-to-comp migrate: $fid_before != $fid_after"
7149
7150         # 2. migrate a comp layout file to a plain layout
7151         $LFS migrate -c2 $f_comp ||
7152                 error "cannot migrate $f_comp by lfs migrate"
7153         fid_after=$($LFS getstripe --fid $f_comp)
7154         [ "$fid_before" == "$fid_after" ] ||
7155                 error "comp-to-plain migrate: $fid_before != $fid_after"
7156
7157         # 3. migrate a plain layout file to a comp layout
7158         $LFS migrate $layout $f_comp ||
7159                 error "cannot migrate $f_comp by lfs migrate"
7160         fid_after=$($LFS getstripe --fid $f_comp)
7161         [ "$fid_before" == "$fid_after" ] ||
7162                 error "plain-to-comp migrate: $fid_before != $fid_after"
7163 }
7164 run_test 56xf "FID is not lost during migration of a composite layout file"
7165
7166 test_56y() {
7167         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7168                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7169
7170         local res=""
7171         local dir=$DIR/$tdir
7172         local f1=$dir/file1
7173         local f2=$dir/file2
7174
7175         test_mkdir -p $dir || error "creating dir $dir"
7176         touch $f1 || error "creating std file $f1"
7177         $MULTIOP $f2 H2c || error "creating released file $f2"
7178
7179         # a directory can be raid0, so ask only for files
7180         res=$($LFS find $dir -L raid0 -type f | wc -l)
7181         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7182
7183         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7184         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7185
7186         # only files can be released, so no need to force file search
7187         res=$($LFS find $dir -L released)
7188         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7189
7190         res=$($LFS find $dir -type f \! -L released)
7191         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7192 }
7193 run_test 56y "lfs find -L raid0|released"
7194
7195 test_56z() { # LU-4824
7196         # This checks to make sure 'lfs find' continues after errors
7197         # There are two classes of errors that should be caught:
7198         # - If multiple paths are provided, all should be searched even if one
7199         #   errors out
7200         # - If errors are encountered during the search, it should not terminate
7201         #   early
7202         local dir=$DIR/$tdir
7203         local i
7204
7205         test_mkdir $dir
7206         for i in d{0..9}; do
7207                 test_mkdir $dir/$i
7208                 touch $dir/$i/$tfile
7209         done
7210         $LFS find $DIR/non_existent_dir $dir &&
7211                 error "$LFS find did not return an error"
7212         # Make a directory unsearchable. This should NOT be the last entry in
7213         # directory order.  Arbitrarily pick the 6th entry
7214         chmod 700 $($LFS find $dir -type d | sed '6!d')
7215
7216         $RUNAS $LFS find $DIR/non_existent $dir
7217         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7218
7219         # The user should be able to see 10 directories and 9 files
7220         (( count == 19 )) ||
7221                 error "$LFS find found $count != 19 entries after error"
7222 }
7223 run_test 56z "lfs find should continue after an error"
7224
7225 test_56aa() { # LU-5937
7226         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7227
7228         local dir=$DIR/$tdir
7229
7230         mkdir $dir
7231         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7232
7233         createmany -o $dir/striped_dir/${tfile}- 1024
7234         local dirs=$($LFS find --size +8k $dir/)
7235
7236         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7237 }
7238 run_test 56aa "lfs find --size under striped dir"
7239
7240 test_56ab() { # LU-10705
7241         test_mkdir $DIR/$tdir
7242         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7243         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7244         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7245         # Flush writes to ensure valid blocks.  Need to be more thorough for
7246         # ZFS, since blocks are not allocated/returned to client immediately.
7247         sync_all_data
7248         wait_zfs_commit ost1 2
7249         cancel_lru_locks osc
7250         ls -ls $DIR/$tdir
7251
7252         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7253
7254         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7255
7256         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7257         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7258
7259         rm -f $DIR/$tdir/$tfile.[123]
7260 }
7261 run_test 56ab "lfs find --blocks"
7262
7263 test_56ba() {
7264         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
7265                 skip "Need MDS version at least 2.10.50"
7266
7267         # Create composite files with one component
7268         local dir=$DIR/$tdir
7269
7270         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
7271         # Create composite files with three components
7272         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
7273         # Create non-composite files
7274         createmany -o $dir/${tfile}- 10
7275
7276         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
7277
7278         [[ $nfiles == 10 ]] ||
7279                 error "lfs find -E 1M found $nfiles != 10 files"
7280
7281         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
7282         [[ $nfiles == 25 ]] ||
7283                 error "lfs find ! -E 1M found $nfiles != 25 files"
7284
7285         # All files have a component that starts at 0
7286         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
7287         [[ $nfiles == 35 ]] ||
7288                 error "lfs find --component-start 0 - $nfiles != 35 files"
7289
7290         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
7291         [[ $nfiles == 15 ]] ||
7292                 error "lfs find --component-start 2M - $nfiles != 15 files"
7293
7294         # All files created here have a componenet that does not starts at 2M
7295         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
7296         [[ $nfiles == 35 ]] ||
7297                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
7298
7299         # Find files with a specified number of components
7300         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
7301         [[ $nfiles == 15 ]] ||
7302                 error "lfs find --component-count 3 - $nfiles != 15 files"
7303
7304         # Remember non-composite files have a component count of zero
7305         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
7306         [[ $nfiles == 10 ]] ||
7307                 error "lfs find --component-count 0 - $nfiles != 10 files"
7308
7309         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
7310         [[ $nfiles == 20 ]] ||
7311                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
7312
7313         # All files have a flag called "init"
7314         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
7315         [[ $nfiles == 35 ]] ||
7316                 error "lfs find --component-flags init - $nfiles != 35 files"
7317
7318         # Multi-component files will have a component not initialized
7319         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
7320         [[ $nfiles == 15 ]] ||
7321                 error "lfs find !--component-flags init - $nfiles != 15 files"
7322
7323         rm -rf $dir
7324
7325 }
7326 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
7327
7328 test_56ca() {
7329         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
7330                 skip "Need MDS version at least 2.10.57"
7331
7332         local td=$DIR/$tdir
7333         local tf=$td/$tfile
7334         local dir
7335         local nfiles
7336         local cmd
7337         local i
7338         local j
7339
7340         # create mirrored directories and mirrored files
7341         mkdir $td || error "mkdir $td failed"
7342         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
7343         createmany -o $tf- 10 || error "create $tf- failed"
7344
7345         for i in $(seq 2); do
7346                 dir=$td/dir$i
7347                 mkdir $dir || error "mkdir $dir failed"
7348                 $LFS mirror create -N$((3 + i)) $dir ||
7349                         error "create mirrored dir $dir failed"
7350                 createmany -o $dir/$tfile- 10 ||
7351                         error "create $dir/$tfile- failed"
7352         done
7353
7354         # change the states of some mirrored files
7355         echo foo > $tf-6
7356         for i in $(seq 2); do
7357                 dir=$td/dir$i
7358                 for j in $(seq 4 9); do
7359                         echo foo > $dir/$tfile-$j
7360                 done
7361         done
7362
7363         # find mirrored files with specific mirror count
7364         cmd="$LFS find --mirror-count 3 --type f $td"
7365         nfiles=$($cmd | wc -l)
7366         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
7367
7368         cmd="$LFS find ! --mirror-count 3 --type f $td"
7369         nfiles=$($cmd | wc -l)
7370         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
7371
7372         cmd="$LFS find --mirror-count +2 --type f $td"
7373         nfiles=$($cmd | wc -l)
7374         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7375
7376         cmd="$LFS find --mirror-count -6 --type f $td"
7377         nfiles=$($cmd | wc -l)
7378         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7379
7380         # find mirrored files with specific file state
7381         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
7382         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
7383
7384         cmd="$LFS find --mirror-state=ro --type f $td"
7385         nfiles=$($cmd | wc -l)
7386         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
7387
7388         cmd="$LFS find ! --mirror-state=ro --type f $td"
7389         nfiles=$($cmd | wc -l)
7390         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7391
7392         cmd="$LFS find --mirror-state=wp --type f $td"
7393         nfiles=$($cmd | wc -l)
7394         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7395
7396         cmd="$LFS find ! --mirror-state=sp --type f $td"
7397         nfiles=$($cmd | wc -l)
7398         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7399 }
7400 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
7401
7402 test_57a() {
7403         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7404         # note test will not do anything if MDS is not local
7405         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7406                 skip_env "ldiskfs only test"
7407         fi
7408         remote_mds_nodsh && skip "remote MDS with nodsh"
7409
7410         local MNTDEV="osd*.*MDT*.mntdev"
7411         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
7412         [ -z "$DEV" ] && error "can't access $MNTDEV"
7413         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
7414                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
7415                         error "can't access $DEV"
7416                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
7417                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
7418                 rm $TMP/t57a.dump
7419         done
7420 }
7421 run_test 57a "verify MDS filesystem created with large inodes =="
7422
7423 test_57b() {
7424         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7425         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7426                 skip_env "ldiskfs only test"
7427         fi
7428         remote_mds_nodsh && skip "remote MDS with nodsh"
7429
7430         local dir=$DIR/$tdir
7431         local filecount=100
7432         local file1=$dir/f1
7433         local fileN=$dir/f$filecount
7434
7435         rm -rf $dir || error "removing $dir"
7436         test_mkdir -c1 $dir
7437         local mdtidx=$($LFS getstripe -m $dir)
7438         local mdtname=MDT$(printf %04x $mdtidx)
7439         local facet=mds$((mdtidx + 1))
7440
7441         echo "mcreating $filecount files"
7442         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
7443
7444         # verify that files do not have EAs yet
7445         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
7446                 error "$file1 has an EA"
7447         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
7448                 error "$fileN has an EA"
7449
7450         sync
7451         sleep 1
7452         df $dir  #make sure we get new statfs data
7453         local mdsfree=$(do_facet $facet \
7454                         lctl get_param -n osd*.*$mdtname.kbytesfree)
7455         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7456         local file
7457
7458         echo "opening files to create objects/EAs"
7459         for file in $(seq -f $dir/f%g 1 $filecount); do
7460                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
7461                         error "opening $file"
7462         done
7463
7464         # verify that files have EAs now
7465         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
7466         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
7467
7468         sleep 1  #make sure we get new statfs data
7469         df $dir
7470         local mdsfree2=$(do_facet $facet \
7471                          lctl get_param -n osd*.*$mdtname.kbytesfree)
7472         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7473
7474         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
7475                 if [ "$mdsfree" != "$mdsfree2" ]; then
7476                         error "MDC before $mdcfree != after $mdcfree2"
7477                 else
7478                         echo "MDC before $mdcfree != after $mdcfree2"
7479                         echo "unable to confirm if MDS has large inodes"
7480                 fi
7481         fi
7482         rm -rf $dir
7483 }
7484 run_test 57b "default LOV EAs are stored inside large inodes ==="
7485
7486 test_58() {
7487         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7488         [ -z "$(which wiretest 2>/dev/null)" ] &&
7489                         skip_env "could not find wiretest"
7490
7491         wiretest
7492 }
7493 run_test 58 "verify cross-platform wire constants =============="
7494
7495 test_59() {
7496         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7497
7498         echo "touch 130 files"
7499         createmany -o $DIR/f59- 130
7500         echo "rm 130 files"
7501         unlinkmany $DIR/f59- 130
7502         sync
7503         # wait for commitment of removal
7504         wait_delete_completed
7505 }
7506 run_test 59 "verify cancellation of llog records async ========="
7507
7508 TEST60_HEAD="test_60 run $RANDOM"
7509 test_60a() {
7510         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7511         remote_mgs_nodsh && skip "remote MGS with nodsh"
7512         do_facet mgs "! which run-llog.sh &> /dev/null" &&
7513                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
7514                         skip_env "missing subtest run-llog.sh"
7515
7516         log "$TEST60_HEAD - from kernel mode"
7517         do_facet mgs "$LCTL dk > /dev/null"
7518         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
7519         do_facet mgs $LCTL dk > $TMP/$tfile
7520
7521         # LU-6388: test llog_reader
7522         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
7523         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
7524         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
7525                         skip_env "missing llog_reader"
7526         local fstype=$(facet_fstype mgs)
7527         [ $fstype != ldiskfs -a $fstype != zfs ] &&
7528                 skip_env "Only for ldiskfs or zfs type mgs"
7529
7530         local mntpt=$(facet_mntpt mgs)
7531         local mgsdev=$(mgsdevname 1)
7532         local fid_list
7533         local fid
7534         local rec_list
7535         local rec
7536         local rec_type
7537         local obj_file
7538         local path
7539         local seq
7540         local oid
7541         local pass=true
7542
7543         #get fid and record list
7544         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
7545                 tail -n 4))
7546         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
7547                 tail -n 4))
7548         #remount mgs as ldiskfs or zfs type
7549         stop mgs || error "stop mgs failed"
7550         mount_fstype mgs || error "remount mgs failed"
7551         for ((i = 0; i < ${#fid_list[@]}; i++)); do
7552                 fid=${fid_list[i]}
7553                 rec=${rec_list[i]}
7554                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
7555                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
7556                 oid=$((16#$oid))
7557
7558                 case $fstype in
7559                         ldiskfs )
7560                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
7561                         zfs )
7562                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
7563                 esac
7564                 echo "obj_file is $obj_file"
7565                 do_facet mgs $llog_reader $obj_file
7566
7567                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
7568                         awk '{ print $3 }' | sed -e "s/^type=//g")
7569                 if [ $rec_type != $rec ]; then
7570                         echo "FAILED test_60a wrong record type $rec_type," \
7571                               "should be $rec"
7572                         pass=false
7573                         break
7574                 fi
7575
7576                 #check obj path if record type is LLOG_LOGID_MAGIC
7577                 if [ "$rec" == "1064553b" ]; then
7578                         path=$(do_facet mgs $llog_reader $obj_file |
7579                                 grep "path=" | awk '{ print $NF }' |
7580                                 sed -e "s/^path=//g")
7581                         if [ $obj_file != $mntpt/$path ]; then
7582                                 echo "FAILED test_60a wrong obj path" \
7583                                       "$montpt/$path, should be $obj_file"
7584                                 pass=false
7585                                 break
7586                         fi
7587                 fi
7588         done
7589         rm -f $TMP/$tfile
7590         #restart mgs before "error", otherwise it will block the next test
7591         stop mgs || error "stop mgs failed"
7592         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
7593         $pass || error "test failed, see FAILED test_60a messages for specifics"
7594 }
7595 run_test 60a "llog_test run from kernel module and test llog_reader"
7596
7597 test_60b() { # bug 6411
7598         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7599
7600         dmesg > $DIR/$tfile
7601         LLOG_COUNT=$(do_facet mgs dmesg |
7602                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
7603                           /llog_[a-z]*.c:[0-9]/ {
7604                                 if (marker)
7605                                         from_marker++
7606                                 from_begin++
7607                           }
7608                           END {
7609                                 if (marker)
7610                                         print from_marker
7611                                 else
7612                                         print from_begin
7613                           }")
7614
7615         [[ $LLOG_COUNT -gt 120 ]] &&
7616                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
7617 }
7618 run_test 60b "limit repeated messages from CERROR/CWARN"
7619
7620 test_60c() {
7621         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7622
7623         echo "create 5000 files"
7624         createmany -o $DIR/f60c- 5000
7625 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
7626         lctl set_param fail_loc=0x80000137
7627         unlinkmany $DIR/f60c- 5000
7628         lctl set_param fail_loc=0
7629 }
7630 run_test 60c "unlink file when mds full"
7631
7632 test_60d() {
7633         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7634
7635         SAVEPRINTK=$(lctl get_param -n printk)
7636         # verify "lctl mark" is even working"
7637         MESSAGE="test message ID $RANDOM $$"
7638         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7639         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
7640
7641         lctl set_param printk=0 || error "set lnet.printk failed"
7642         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
7643         MESSAGE="new test message ID $RANDOM $$"
7644         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
7645         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7646         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
7647
7648         lctl set_param -n printk="$SAVEPRINTK"
7649 }
7650 run_test 60d "test printk console message masking"
7651
7652 test_60e() {
7653         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7654         remote_mds_nodsh && skip "remote MDS with nodsh"
7655
7656         touch $DIR/$tfile
7657 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
7658         do_facet mds1 lctl set_param fail_loc=0x15b
7659         rm $DIR/$tfile
7660 }
7661 run_test 60e "no space while new llog is being created"
7662
7663 test_60g() {
7664         local pid
7665         local i
7666
7667         test_mkdir -c $MDSCOUNT $DIR/$tdir
7668
7669         (
7670                 local index=0
7671                 while true; do
7672                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
7673                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
7674                                 2>/dev/null
7675                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
7676                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
7677                         index=$((index + 1))
7678                 done
7679         ) &
7680
7681         pid=$!
7682
7683         for i in {0..100}; do
7684                 # define OBD_FAIL_OSD_TXN_START    0x19a
7685                 local index=$((i % MDSCOUNT + 1))
7686
7687                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
7688                         > /dev/null
7689                 usleep 100
7690         done
7691
7692         kill -9 $pid
7693
7694         for i in $(seq $MDSCOUNT); do
7695                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
7696         done
7697
7698         mkdir $DIR/$tdir/new || error "mkdir failed"
7699         rmdir $DIR/$tdir/new || error "rmdir failed"
7700
7701         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
7702                 -t namespace
7703         for i in $(seq $MDSCOUNT); do
7704                 wait_update_facet mds$i "$LCTL get_param -n \
7705                         mdd.$(facet_svc mds$i).lfsck_namespace |
7706                         awk '/^status/ { print \\\$2 }'" "completed"
7707         done
7708
7709         ls -R $DIR/$tdir || error "ls failed"
7710         rm -rf $DIR/$tdir || error "rmdir failed"
7711 }
7712 run_test 60g "transaction abort won't cause MDT hung"
7713
7714 test_60h() {
7715         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
7716                 skip "Need MDS version at least 2.12.52"
7717         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
7718
7719         local f
7720
7721         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
7722         #define OBD_FAIL_MDS_STRIPE_FID          0x189
7723         for fail_loc in 0x80000188 0x80000189; do
7724                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
7725                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
7726                         error "mkdir $dir-$fail_loc failed"
7727                 for i in {0..10}; do
7728                         # create may fail on missing stripe
7729                         echo $i > $DIR/$tdir-$fail_loc/$i
7730                 done
7731                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7732                         error "getdirstripe $tdir-$fail_loc failed"
7733                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
7734                         error "migrate $tdir-$fail_loc failed"
7735                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7736                         error "getdirstripe $tdir-$fail_loc failed"
7737                 pushd $DIR/$tdir-$fail_loc
7738                 for f in *; do
7739                         echo $f | cmp $f - || error "$f data mismatch"
7740                 done
7741                 popd
7742                 rm -rf $DIR/$tdir-$fail_loc
7743         done
7744 }
7745 run_test 60h "striped directory with missing stripes can be accessed"
7746
7747 test_61a() {
7748         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7749
7750         f="$DIR/f61"
7751         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
7752         cancel_lru_locks osc
7753         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
7754         sync
7755 }
7756 run_test 61a "mmap() writes don't make sync hang ================"
7757
7758 test_61b() {
7759         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
7760 }
7761 run_test 61b "mmap() of unstriped file is successful"
7762
7763 # bug 2330 - insufficient obd_match error checking causes LBUG
7764 test_62() {
7765         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7766
7767         f="$DIR/f62"
7768         echo foo > $f
7769         cancel_lru_locks osc
7770         lctl set_param fail_loc=0x405
7771         cat $f && error "cat succeeded, expect -EIO"
7772         lctl set_param fail_loc=0
7773 }
7774 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
7775 # match every page all of the time.
7776 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
7777
7778 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
7779 # Though this test is irrelevant anymore, it helped to reveal some
7780 # other grant bugs (LU-4482), let's keep it.
7781 test_63a() {   # was test_63
7782         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7783
7784         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
7785
7786         for i in `seq 10` ; do
7787                 dd if=/dev/zero of=$DIR/f63 bs=8k &
7788                 sleep 5
7789                 kill $!
7790                 sleep 1
7791         done
7792
7793         rm -f $DIR/f63 || true
7794 }
7795 run_test 63a "Verify oig_wait interruption does not crash ======="
7796
7797 # bug 2248 - async write errors didn't return to application on sync
7798 # bug 3677 - async write errors left page locked
7799 test_63b() {
7800         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7801
7802         debugsave
7803         lctl set_param debug=-1
7804
7805         # ensure we have a grant to do async writes
7806         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
7807         rm $DIR/$tfile
7808
7809         sync    # sync lest earlier test intercept the fail_loc
7810
7811         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
7812         lctl set_param fail_loc=0x80000406
7813         $MULTIOP $DIR/$tfile Owy && \
7814                 error "sync didn't return ENOMEM"
7815         sync; sleep 2; sync     # do a real sync this time to flush page
7816         lctl get_param -n llite.*.dump_page_cache | grep locked && \
7817                 error "locked page left in cache after async error" || true
7818         debugrestore
7819 }
7820 run_test 63b "async write errors should be returned to fsync ==="
7821
7822 test_64a () {
7823         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7824
7825         lfs df $DIR
7826         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
7827 }
7828 run_test 64a "verify filter grant calculations (in kernel) ====="
7829
7830 test_64b () {
7831         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7832
7833         sh oos.sh $MOUNT || error "oos.sh failed: $?"
7834 }
7835 run_test 64b "check out-of-space detection on client"
7836
7837 test_64c() {
7838         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
7839 }
7840 run_test 64c "verify grant shrink"
7841
7842 # this does exactly what osc_request.c:osc_announce_cached() does in
7843 # order to calculate max amount of grants to ask from server
7844 want_grant() {
7845         local tgt=$1
7846
7847         local nrpages=$($LCTL get_param -n osc.${tgt}.max_pages_per_rpc)
7848         local rpc_in_flight=$($LCTL get_param -n osc.${tgt}.max_rpcs_in_flight)
7849
7850         ((rpc_in_flight ++));
7851         nrpages=$((nrpages * rpc_in_flight))
7852
7853         local dirty_max_pages=$($LCTL get_param -n osc.${tgt}.max_dirty_mb)
7854
7855         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
7856
7857         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
7858         local undirty=$((nrpages * PAGE_SIZE))
7859
7860         local max_extent_pages
7861         max_extent_pages=$($LCTL get_param osc.${tgt}.import |
7862             grep grant_max_extent_size | awk '{print $2}')
7863         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
7864         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
7865         local grant_extent_tax
7866         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
7867             grep grant_extent_tax | awk '{print $2}')
7868
7869         undirty=$((undirty + nrextents * grant_extent_tax))
7870
7871         echo $undirty
7872 }
7873
7874 # this is size of unit for grant allocation. It should be equal to
7875 # what tgt_grant.c:tgt_grant_chunk() calculates
7876 grant_chunk() {
7877         local tgt=$1
7878         local max_brw_size
7879         local grant_extent_tax
7880
7881         max_brw_size=$($LCTL get_param osc.${tgt}.import |
7882             grep max_brw_size | awk '{print $2}')
7883
7884         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
7885             grep grant_extent_tax | awk '{print $2}')
7886
7887         echo $(((max_brw_size + grant_extent_tax) * 2))
7888 }
7889
7890 test_64d() {
7891         [ $OST1_VERSION -lt $(version_code 2.10.56) ] &&
7892                 skip "OST < 2.10.55 doesn't limit grants enough"
7893
7894         local tgt=$($LCTL dl | grep "0000-osc-[^mM]" | awk '{print $4}')
7895         local file=$DIR/$tfile
7896
7897         [[ $($LCTL get_param osc.${tgt}.import |
7898              grep "connect_flags:.*grant_param") ]] ||
7899                 skip "no grant_param connect flag"
7900
7901         local olddebug=$($LCTL get_param -n debug 2> /dev/null)
7902
7903         $LCTL set_param debug="$OLDDEBUG" 2> /dev/null || true
7904
7905         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
7906         stack_trap "rm -f $file" EXIT
7907
7908         $LFS setstripe $file -i 0 -c 1
7909         dd if=/dev/zero of=$file bs=1M count=1000 &
7910         ddpid=$!
7911
7912         while true
7913         do
7914                 local cur_grant=$($LCTL get_param -n osc.${tgt}.cur_grant_bytes)
7915                 if [[ $cur_grant -gt $max_cur_granted ]]
7916                 then
7917                         kill $ddpid
7918                         error "cur_grant $cur_grant > $max_cur_granted"
7919                 fi
7920                 kill -0 $ddpid
7921                 [[ $? -ne 0 ]] && break;
7922                 sleep 2
7923         done
7924
7925         rm -f $DIR/$tfile
7926         wait_delete_completed
7927         $LCTL set_param debug="$olddebug" 2> /dev/null || true
7928 }
7929 run_test 64d "check grant limit exceed"
7930
7931 # bug 1414 - set/get directories' stripe info
7932 test_65a() {
7933         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7934
7935         test_mkdir $DIR/$tdir
7936         touch $DIR/$tdir/f1
7937         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
7938 }
7939 run_test 65a "directory with no stripe info"
7940
7941 test_65b() {
7942         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7943
7944         test_mkdir $DIR/$tdir
7945         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7946
7947         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
7948                                                 error "setstripe"
7949         touch $DIR/$tdir/f2
7950         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
7951 }
7952 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
7953
7954 test_65c() {
7955         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7956         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
7957
7958         test_mkdir $DIR/$tdir
7959         local stripesize=$($LFS getstripe -S $DIR/$tdir)
7960
7961         $LFS setstripe -S $((stripesize * 4)) -i 1 \
7962                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
7963         touch $DIR/$tdir/f3
7964         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
7965 }
7966 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
7967
7968 test_65d() {
7969         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7970
7971         test_mkdir $DIR/$tdir
7972         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
7973         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7974
7975         if [[ $STRIPECOUNT -le 0 ]]; then
7976                 sc=1
7977         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
7978                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
7979                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
7980         else
7981                 sc=$(($STRIPECOUNT - 1))
7982         fi
7983         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
7984         touch $DIR/$tdir/f4 $DIR/$tdir/f5
7985         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
7986                 error "lverify failed"
7987 }
7988 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
7989
7990 test_65e() {
7991         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7992
7993         test_mkdir $DIR/$tdir
7994
7995         $LFS setstripe $DIR/$tdir || error "setstripe"
7996         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
7997                                         error "no stripe info failed"
7998         touch $DIR/$tdir/f6
7999         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
8000 }
8001 run_test 65e "directory setstripe defaults"
8002
8003 test_65f() {
8004         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8005
8006         test_mkdir $DIR/${tdir}f
8007         $RUNAS $LFS setstripe $DIR/${tdir}f &&
8008                 error "setstripe succeeded" || true
8009 }
8010 run_test 65f "dir setstripe permission (should return error) ==="
8011
8012 test_65g() {
8013         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8014
8015         test_mkdir $DIR/$tdir
8016         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8017
8018         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8019                 error "setstripe -S failed"
8020         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
8021         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8022                 error "delete default stripe failed"
8023 }
8024 run_test 65g "directory setstripe -d"
8025
8026 test_65h() {
8027         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8028
8029         test_mkdir $DIR/$tdir
8030         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8031
8032         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8033                 error "setstripe -S failed"
8034         test_mkdir $DIR/$tdir/dd1
8035         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
8036                 error "stripe info inherit failed"
8037 }
8038 run_test 65h "directory stripe info inherit ===================="
8039
8040 test_65i() {
8041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8042
8043         save_layout_restore_at_exit $MOUNT
8044
8045         # bug6367: set non-default striping on root directory
8046         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
8047
8048         # bug12836: getstripe on -1 default directory striping
8049         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
8050
8051         # bug12836: getstripe -v on -1 default directory striping
8052         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
8053
8054         # bug12836: new find on -1 default directory striping
8055         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
8056 }
8057 run_test 65i "various tests to set root directory striping"
8058
8059 test_65j() { # bug6367
8060         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8061
8062         sync; sleep 1
8063
8064         # if we aren't already remounting for each test, do so for this test
8065         if [ "$I_MOUNTED" = "yes" ]; then
8066                 cleanup || error "failed to unmount"
8067                 setup
8068         fi
8069
8070         save_layout_restore_at_exit $MOUNT
8071
8072         $LFS setstripe -d $MOUNT || error "setstripe failed"
8073 }
8074 run_test 65j "set default striping on root directory (bug 6367)="
8075
8076 cleanup_65k() {
8077         rm -rf $DIR/$tdir
8078         wait_delete_completed
8079         do_facet $SINGLEMDS "lctl set_param -n \
8080                 osp.$ost*MDT0000.max_create_count=$max_count"
8081         do_facet $SINGLEMDS "lctl set_param -n \
8082                 osp.$ost*MDT0000.create_count=$count"
8083         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8084         echo $INACTIVE_OSC "is Activate"
8085
8086         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8087 }
8088
8089 test_65k() { # bug11679
8090         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8091         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8092         remote_mds_nodsh && skip "remote MDS with nodsh"
8093
8094         local disable_precreate=true
8095         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
8096                 disable_precreate=false
8097
8098         echo "Check OST status: "
8099         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
8100                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
8101
8102         for OSC in $MDS_OSCS; do
8103                 echo $OSC "is active"
8104                 do_facet $SINGLEMDS lctl --device %$OSC activate
8105         done
8106
8107         for INACTIVE_OSC in $MDS_OSCS; do
8108                 local ost=$(osc_to_ost $INACTIVE_OSC)
8109                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
8110                                lov.*md*.target_obd |
8111                                awk -F: /$ost/'{ print $1 }' | head -n 1)
8112
8113                 mkdir -p $DIR/$tdir
8114                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
8115                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
8116
8117                 echo "Deactivate: " $INACTIVE_OSC
8118                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
8119
8120                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
8121                               osp.$ost*MDT0000.create_count")
8122                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
8123                                   osp.$ost*MDT0000.max_create_count")
8124                 $disable_precreate &&
8125                         do_facet $SINGLEMDS "lctl set_param -n \
8126                                 osp.$ost*MDT0000.max_create_count=0"
8127
8128                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
8129                         [ -f $DIR/$tdir/$idx ] && continue
8130                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
8131                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
8132                                 { cleanup_65k;
8133                                   error "setstripe $idx should succeed"; }
8134                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
8135                 done
8136                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
8137                 rmdir $DIR/$tdir
8138
8139                 do_facet $SINGLEMDS "lctl set_param -n \
8140                         osp.$ost*MDT0000.max_create_count=$max_count"
8141                 do_facet $SINGLEMDS "lctl set_param -n \
8142                         osp.$ost*MDT0000.create_count=$count"
8143                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8144                 echo $INACTIVE_OSC "is Activate"
8145
8146                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8147         done
8148 }
8149 run_test 65k "validate manual striping works properly with deactivated OSCs"
8150
8151 test_65l() { # bug 12836
8152         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8153
8154         test_mkdir -p $DIR/$tdir/test_dir
8155         $LFS setstripe -c -1 $DIR/$tdir/test_dir
8156         $LFS find -mtime -1 $DIR/$tdir >/dev/null
8157 }
8158 run_test 65l "lfs find on -1 stripe dir ========================"
8159
8160 test_65m() {
8161         local layout=$(save_layout $MOUNT)
8162         $RUNAS $LFS setstripe -c 2 $MOUNT && {
8163                 restore_layout $MOUNT $layout
8164                 error "setstripe should fail by non-root users"
8165         }
8166         true
8167 }
8168 run_test 65m "normal user can't set filesystem default stripe"
8169
8170 test_65n() {
8171         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
8172         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
8173                 skip "Need MDS version at least 2.12.50"
8174         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8175
8176         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8177         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
8178         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
8179
8180         local root_layout=$(save_layout $MOUNT)
8181         stack_trap "restore_layout $MOUNT $root_layout" EXIT
8182
8183         # new subdirectory under root directory should not inherit
8184         # the default layout from root
8185         local dir1=$MOUNT/$tdir-1
8186         mkdir $dir1 || error "mkdir $dir1 failed"
8187         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
8188                 error "$dir1 shouldn't have LOV EA"
8189
8190         # delete the default layout on root directory
8191         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
8192
8193         local dir2=$MOUNT/$tdir-2
8194         mkdir $dir2 || error "mkdir $dir2 failed"
8195         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
8196                 error "$dir2 shouldn't have LOV EA"
8197
8198         # set a new striping pattern on root directory
8199         local def_stripe_size=$($LFS getstripe -S $MOUNT)
8200         local new_def_stripe_size=$((def_stripe_size * 2))
8201         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
8202                 error "set stripe size on $MOUNT failed"
8203
8204         # new file created in $dir2 should inherit the new stripe size from
8205         # the filesystem default
8206         local file2=$dir2/$tfile-2
8207         touch $file2 || error "touch $file2 failed"
8208
8209         local file2_stripe_size=$($LFS getstripe -S $file2)
8210         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
8211                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
8212
8213         local dir3=$MOUNT/$tdir-3
8214         mkdir $dir3 || error "mkdir $dir3 failed"
8215         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
8216         # the root layout, which is the actual default layout that will be used
8217         # when new files are created in $dir3.
8218         local dir3_layout=$(get_layout_param $dir3)
8219         local root_dir_layout=$(get_layout_param $MOUNT)
8220         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
8221                 error "$dir3 should show the default layout from $MOUNT"
8222
8223         # set OST pool on root directory
8224         local pool=$TESTNAME
8225         pool_add $pool || error "add $pool failed"
8226         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8227                 error "add targets to $pool failed"
8228
8229         $LFS setstripe -p $pool $MOUNT ||
8230                 error "set OST pool on $MOUNT failed"
8231
8232         # new file created in $dir3 should inherit the pool from
8233         # the filesystem default
8234         local file3=$dir3/$tfile-3
8235         touch $file3 || error "touch $file3 failed"
8236
8237         local file3_pool=$($LFS getstripe -p $file3)
8238         [[ "$file3_pool" = "$pool" ]] ||
8239                 error "$file3 didn't inherit OST pool $pool"
8240
8241         local dir4=$MOUNT/$tdir-4
8242         mkdir $dir4 || error "mkdir $dir4 failed"
8243         local dir4_layout=$(get_layout_param $dir4)
8244         root_dir_layout=$(get_layout_param $MOUNT)
8245         echo "$LFS getstripe -d $dir4"
8246         $LFS getstripe -d $dir4
8247         echo "$LFS getstripe -d $MOUNT"
8248         $LFS getstripe -d $MOUNT
8249         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
8250                 error "$dir4 should show the default layout from $MOUNT"
8251
8252         # new file created in $dir4 should inherit the pool from
8253         # the filesystem default
8254         local file4=$dir4/$tfile-4
8255         touch $file4 || error "touch $file4 failed"
8256
8257         local file4_pool=$($LFS getstripe -p $file4)
8258         [[ "$file4_pool" = "$pool" ]] ||
8259                 error "$file4 didn't inherit OST pool $pool"
8260
8261         # new subdirectory under non-root directory should inherit
8262         # the default layout from its parent directory
8263         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
8264                 error "set directory layout on $dir4 failed"
8265
8266         local dir5=$dir4/$tdir-5
8267         mkdir $dir5 || error "mkdir $dir5 failed"
8268
8269         dir4_layout=$(get_layout_param $dir4)
8270         local dir5_layout=$(get_layout_param $dir5)
8271         [[ "$dir4_layout" = "$dir5_layout" ]] ||
8272                 error "$dir5 should inherit the default layout from $dir4"
8273
8274         # though subdir under ROOT doesn't inherit default layout, but
8275         # its sub dir/file should be created with default layout.
8276         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
8277         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
8278                 skip "Need MDS version at least 2.12.59"
8279
8280         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
8281         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
8282         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
8283
8284         if [ $default_lmv_hash == "none" ]; then
8285                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
8286         else
8287                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
8288                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
8289         fi
8290
8291         $LFS setdirstripe -D -c 2 $MOUNT ||
8292                 error "setdirstripe -D -c 2 failed"
8293         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
8294         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
8295         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
8296 }
8297 run_test 65n "don't inherit default layout from root for new subdirectories"
8298
8299 # bug 2543 - update blocks count on client
8300 test_66() {
8301         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8302
8303         COUNT=${COUNT:-8}
8304         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
8305         sync; sync_all_data; sync; sync_all_data
8306         cancel_lru_locks osc
8307         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
8308         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
8309 }
8310 run_test 66 "update inode blocks count on client ==============="
8311
8312 meminfo() {
8313         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
8314 }
8315
8316 swap_used() {
8317         swapon -s | awk '($1 == "'$1'") { print $4 }'
8318 }
8319
8320 # bug5265, obdfilter oa2dentry return -ENOENT
8321 # #define OBD_FAIL_SRV_ENOENT 0x217
8322 test_69() {
8323         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8324         remote_ost_nodsh && skip "remote OST with nodsh"
8325
8326         f="$DIR/$tfile"
8327         $LFS setstripe -c 1 -i 0 $f
8328
8329         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
8330
8331         do_facet ost1 lctl set_param fail_loc=0x217
8332         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
8333         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
8334
8335         do_facet ost1 lctl set_param fail_loc=0
8336         $DIRECTIO write $f 0 2 || error "write error"
8337
8338         cancel_lru_locks osc
8339         $DIRECTIO read $f 0 1 || error "read error"
8340
8341         do_facet ost1 lctl set_param fail_loc=0x217
8342         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
8343
8344         do_facet ost1 lctl set_param fail_loc=0
8345         rm -f $f
8346 }
8347 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
8348
8349 test_71() {
8350         test_mkdir $DIR/$tdir
8351         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
8352         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
8353 }
8354 run_test 71 "Running dbench on lustre (don't segment fault) ===="
8355
8356 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
8357         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8358         [ "$RUNAS_ID" = "$UID" ] &&
8359                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8360         # Check that testing environment is properly set up. Skip if not
8361         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
8362                 skip_env "User $RUNAS_ID does not exist - skipping"
8363
8364         touch $DIR/$tfile
8365         chmod 777 $DIR/$tfile
8366         chmod ug+s $DIR/$tfile
8367         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
8368                 error "$RUNAS dd $DIR/$tfile failed"
8369         # See if we are still setuid/sgid
8370         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8371                 error "S/gid is not dropped on write"
8372         # Now test that MDS is updated too
8373         cancel_lru_locks mdc
8374         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8375                 error "S/gid is not dropped on MDS"
8376         rm -f $DIR/$tfile
8377 }
8378 run_test 72a "Test that remove suid works properly (bug5695) ===="
8379
8380 test_72b() { # bug 24226 -- keep mode setting when size is not changing
8381         local perm
8382
8383         [ "$RUNAS_ID" = "$UID" ] &&
8384                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8385         [ "$RUNAS_ID" -eq 0 ] &&
8386                 skip_env "RUNAS_ID = 0 -- skipping"
8387         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8388         # Check that testing environment is properly set up. Skip if not
8389         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
8390                 skip_env "User $RUNAS_ID does not exist - skipping"
8391
8392         touch $DIR/${tfile}-f{g,u}
8393         test_mkdir $DIR/${tfile}-dg
8394         test_mkdir $DIR/${tfile}-du
8395         chmod 770 $DIR/${tfile}-{f,d}{g,u}
8396         chmod g+s $DIR/${tfile}-{f,d}g
8397         chmod u+s $DIR/${tfile}-{f,d}u
8398         for perm in 777 2777 4777; do
8399                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
8400                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
8401                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
8402                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
8403         done
8404         true
8405 }
8406 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
8407
8408 # bug 3462 - multiple simultaneous MDC requests
8409 test_73() {
8410         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8411
8412         test_mkdir $DIR/d73-1
8413         test_mkdir $DIR/d73-2
8414         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
8415         pid1=$!
8416
8417         lctl set_param fail_loc=0x80000129
8418         $MULTIOP $DIR/d73-1/f73-2 Oc &
8419         sleep 1
8420         lctl set_param fail_loc=0
8421
8422         $MULTIOP $DIR/d73-2/f73-3 Oc &
8423         pid3=$!
8424
8425         kill -USR1 $pid1
8426         wait $pid1 || return 1
8427
8428         sleep 25
8429
8430         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
8431         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
8432         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
8433
8434         rm -rf $DIR/d73-*
8435 }
8436 run_test 73 "multiple MDC requests (should not deadlock)"
8437
8438 test_74a() { # bug 6149, 6184
8439         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8440
8441         touch $DIR/f74a
8442         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8443         #
8444         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8445         # will spin in a tight reconnection loop
8446         $LCTL set_param fail_loc=0x8000030e
8447         # get any lock that won't be difficult - lookup works.
8448         ls $DIR/f74a
8449         $LCTL set_param fail_loc=0
8450         rm -f $DIR/f74a
8451         true
8452 }
8453 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
8454
8455 test_74b() { # bug 13310
8456         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8457
8458         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8459         #
8460         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8461         # will spin in a tight reconnection loop
8462         $LCTL set_param fail_loc=0x8000030e
8463         # get a "difficult" lock
8464         touch $DIR/f74b
8465         $LCTL set_param fail_loc=0
8466         rm -f $DIR/f74b
8467         true
8468 }
8469 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
8470
8471 test_74c() {
8472         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8473
8474         #define OBD_FAIL_LDLM_NEW_LOCK
8475         $LCTL set_param fail_loc=0x319
8476         touch $DIR/$tfile && error "touch successful"
8477         $LCTL set_param fail_loc=0
8478         true
8479 }
8480 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
8481
8482 num_inodes() {
8483         awk '/lustre_inode_cache/ {print $2; exit}' /proc/slabinfo
8484 }
8485
8486 test_76() { # Now for bug 20433, added originally in bug 1443
8487         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8488
8489         cancel_lru_locks osc
8490         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
8491         local before=$(num_inodes)
8492         local count=$((512 * cpus))
8493         [ "$SLOW" = "no" ] && count=$((64 * cpus))
8494
8495         echo "before inodes: $before"
8496         for i in $(seq $count); do
8497                 touch $DIR/$tfile
8498                 rm -f $DIR/$tfile
8499         done
8500         cancel_lru_locks osc
8501         local after=$(num_inodes)
8502         echo "after inodes: $after"
8503         while (( after > before + 8 * ${cpus:-1} )); do
8504                 sleep 1
8505                 after=$(num_inodes)
8506                 wait=$((wait + 1))
8507                 (( wait % 5 == 0 )) && echo "wait $wait seconds inodes: $after"
8508                 if (( wait > 30 )); then
8509                         error "inode slab grew from $before to $after"
8510                 fi
8511         done
8512 }
8513 run_test 76 "confirm clients recycle inodes properly ===="
8514
8515
8516 export ORIG_CSUM=""
8517 set_checksums()
8518 {
8519         # Note: in sptlrpc modes which enable its own bulk checksum, the
8520         # original crc32_le bulk checksum will be automatically disabled,
8521         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
8522         # will be checked by sptlrpc code against sptlrpc bulk checksum.
8523         # In this case set_checksums() will not be no-op, because sptlrpc
8524         # bulk checksum will be enabled all through the test.
8525
8526         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
8527         lctl set_param -n osc.*.checksums $1
8528         return 0
8529 }
8530
8531 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8532                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
8533 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8534                              tr -d [] | head -n1)}
8535 set_checksum_type()
8536 {
8537         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
8538         rc=$?
8539         log "set checksum type to $1, rc = $rc"
8540         return $rc
8541 }
8542
8543 get_osc_checksum_type()
8544 {
8545         # arugment 1: OST name, like OST0000
8546         ost=$1
8547         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
8548                         sed 's/.*\[\(.*\)\].*/\1/g')
8549         rc=$?
8550         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
8551         echo $checksum_type
8552 }
8553
8554 F77_TMP=$TMP/f77-temp
8555 F77SZ=8
8556 setup_f77() {
8557         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
8558                 error "error writing to $F77_TMP"
8559 }
8560
8561 test_77a() { # bug 10889
8562         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8563         $GSS && skip_env "could not run with gss"
8564
8565         [ ! -f $F77_TMP ] && setup_f77
8566         set_checksums 1
8567         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
8568         set_checksums 0
8569         rm -f $DIR/$tfile
8570 }
8571 run_test 77a "normal checksum read/write operation"
8572
8573 test_77b() { # bug 10889
8574         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8575         $GSS && skip_env "could not run with gss"
8576
8577         [ ! -f $F77_TMP ] && setup_f77
8578         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8579         $LCTL set_param fail_loc=0x80000409
8580         set_checksums 1
8581
8582         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8583                 error "dd error: $?"
8584         $LCTL set_param fail_loc=0
8585
8586         for algo in $CKSUM_TYPES; do
8587                 cancel_lru_locks osc
8588                 set_checksum_type $algo
8589                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8590                 $LCTL set_param fail_loc=0x80000408
8591                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
8592                 $LCTL set_param fail_loc=0
8593         done
8594         set_checksums 0
8595         set_checksum_type $ORIG_CSUM_TYPE
8596         rm -f $DIR/$tfile
8597 }
8598 run_test 77b "checksum error on client write, read"
8599
8600 cleanup_77c() {
8601         trap 0
8602         set_checksums 0
8603         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
8604         $check_ost &&
8605                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
8606         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
8607         $check_ost && [ -n "$ost_file_prefix" ] &&
8608                 do_facet ost1 rm -f ${ost_file_prefix}\*
8609 }
8610
8611 test_77c() {
8612         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8613         $GSS && skip_env "could not run with gss"
8614         remote_ost_nodsh && skip "remote OST with nodsh"
8615
8616         local bad1
8617         local osc_file_prefix
8618         local osc_file
8619         local check_ost=false
8620         local ost_file_prefix
8621         local ost_file
8622         local orig_cksum
8623         local dump_cksum
8624         local fid
8625
8626         # ensure corruption will occur on first OSS/OST
8627         $LFS setstripe -i 0 $DIR/$tfile
8628
8629         [ ! -f $F77_TMP ] && setup_f77
8630         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8631                 error "dd write error: $?"
8632         fid=$($LFS path2fid $DIR/$tfile)
8633
8634         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
8635         then
8636                 check_ost=true
8637                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
8638                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
8639         else
8640                 echo "OSS do not support bulk pages dump upon error"
8641         fi
8642
8643         osc_file_prefix=$($LCTL get_param -n debug_path)
8644         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
8645
8646         trap cleanup_77c EXIT
8647
8648         set_checksums 1
8649         # enable bulk pages dump upon error on Client
8650         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
8651         # enable bulk pages dump upon error on OSS
8652         $check_ost &&
8653                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
8654
8655         # flush Client cache to allow next read to reach OSS
8656         cancel_lru_locks osc
8657
8658         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
8659         $LCTL set_param fail_loc=0x80000408
8660         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
8661         $LCTL set_param fail_loc=0
8662
8663         rm -f $DIR/$tfile
8664
8665         # check cksum dump on Client
8666         osc_file=$(ls ${osc_file_prefix}*)
8667         [ -n "$osc_file" ] || error "no checksum dump file on Client"
8668         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
8669         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
8670         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
8671         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
8672                      cksum)
8673         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
8674         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8675                 error "dump content does not match on Client"
8676
8677         $check_ost || skip "No need to check cksum dump on OSS"
8678
8679         # check cksum dump on OSS
8680         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
8681         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
8682         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
8683         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
8684         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8685                 error "dump content does not match on OSS"
8686
8687         cleanup_77c
8688 }
8689 run_test 77c "checksum error on client read with debug"
8690
8691 test_77d() { # bug 10889
8692         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8693         $GSS && skip_env "could not run with gss"
8694
8695         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8696         $LCTL set_param fail_loc=0x80000409
8697         set_checksums 1
8698         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8699                 error "direct write: rc=$?"
8700         $LCTL set_param fail_loc=0
8701         set_checksums 0
8702
8703         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8704         $LCTL set_param fail_loc=0x80000408
8705         set_checksums 1
8706         cancel_lru_locks osc
8707         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8708                 error "direct read: rc=$?"
8709         $LCTL set_param fail_loc=0
8710         set_checksums 0
8711 }
8712 run_test 77d "checksum error on OST direct write, read"
8713
8714 test_77f() { # bug 10889
8715         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8716         $GSS && skip_env "could not run with gss"
8717
8718         set_checksums 1
8719         for algo in $CKSUM_TYPES; do
8720                 cancel_lru_locks osc
8721                 set_checksum_type $algo
8722                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8723                 $LCTL set_param fail_loc=0x409
8724                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
8725                         error "direct write succeeded"
8726                 $LCTL set_param fail_loc=0
8727         done
8728         set_checksum_type $ORIG_CSUM_TYPE
8729         set_checksums 0
8730 }
8731 run_test 77f "repeat checksum error on write (expect error)"
8732
8733 test_77g() { # bug 10889
8734         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8735         $GSS && skip_env "could not run with gss"
8736         remote_ost_nodsh && skip "remote OST with nodsh"
8737
8738         [ ! -f $F77_TMP ] && setup_f77
8739
8740         local file=$DIR/$tfile
8741         stack_trap "rm -f $file" EXIT
8742
8743         $LFS setstripe -c 1 -i 0 $file
8744         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
8745         do_facet ost1 lctl set_param fail_loc=0x8000021a
8746         set_checksums 1
8747         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
8748                 error "write error: rc=$?"
8749         do_facet ost1 lctl set_param fail_loc=0
8750         set_checksums 0
8751
8752         cancel_lru_locks osc
8753         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
8754         do_facet ost1 lctl set_param fail_loc=0x8000021b
8755         set_checksums 1
8756         cmp $F77_TMP $file || error "file compare failed"
8757         do_facet ost1 lctl set_param fail_loc=0
8758         set_checksums 0
8759 }
8760 run_test 77g "checksum error on OST write, read"
8761
8762 test_77k() { # LU-10906
8763         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8764         $GSS && skip_env "could not run with gss"
8765
8766         local cksum_param="osc.$FSNAME*.checksums"
8767         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
8768         local checksum
8769         local i
8770
8771         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
8772         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM" EXIT
8773         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM" \
8774                 EXIT
8775
8776         for i in 0 1; do
8777                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
8778                         error "failed to set checksum=$i on MGS"
8779                 wait_update $HOSTNAME "$get_checksum" $i
8780                 #remount
8781                 echo "remount client, checksum should be $i"
8782                 remount_client $MOUNT || error "failed to remount client"
8783                 checksum=$(eval $get_checksum)
8784                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
8785         done
8786         # remove persistent param to avoid races with checksum mountopt below
8787         do_facet mgs $LCTL set_param -P -d $cksum_param ||
8788                 error "failed to delete checksum on MGS"
8789
8790         for opt in "checksum" "nochecksum"; do
8791                 #remount with mount option
8792                 echo "remount client with option $opt, checksum should be $i"
8793                 umount_client $MOUNT || error "failed to umount client"
8794                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
8795                         error "failed to mount client with option '$opt'"
8796                 checksum=$(eval $get_checksum)
8797                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
8798                 i=$((i - 1))
8799         done
8800
8801         remount_client $MOUNT || error "failed to remount client"
8802 }
8803 run_test 77k "enable/disable checksum correctly"
8804
8805 test_77l() {
8806         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8807         $GSS && skip_env "could not run with gss"
8808
8809         set_checksums 1
8810         stack_trap "set_checksums $ORIG_CSUM" EXIT
8811         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
8812
8813         set_checksum_type invalid && error "unexpected success of invalid checksum type"
8814
8815         $LFS setstripe -c 1 -i 0 $DIR/$tfile
8816         for algo in $CKSUM_TYPES; do
8817                 set_checksum_type $algo || error "fail to set checksum type $algo"
8818                 osc_algo=$(get_osc_checksum_type OST0000)
8819                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
8820
8821                 # no locks, no reqs to let the connection idle
8822                 cancel_lru_locks osc
8823                 lru_resize_disable osc
8824                 wait_osc_import_state client ost1 IDLE
8825
8826                 # ensure ost1 is connected
8827                 stat $DIR/$tfile >/dev/null || error "can't stat"
8828                 wait_osc_import_state client ost1 FULL
8829
8830                 osc_algo=$(get_osc_checksum_type OST0000)
8831                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
8832         done
8833         return 0
8834 }
8835 run_test 77l "preferred checksum type is remembered after reconnected"
8836
8837 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
8838 rm -f $F77_TMP
8839 unset F77_TMP
8840
8841 cleanup_test_78() {
8842         trap 0
8843         rm -f $DIR/$tfile
8844 }
8845
8846 test_78() { # bug 10901
8847         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8848         remote_ost || skip_env "local OST"
8849
8850         NSEQ=5
8851         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
8852         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
8853         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
8854         echo "MemTotal: $MEMTOTAL"
8855
8856         # reserve 256MB of memory for the kernel and other running processes,
8857         # and then take 1/2 of the remaining memory for the read/write buffers.
8858         if [ $MEMTOTAL -gt 512 ] ;then
8859                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
8860         else
8861                 # for those poor memory-starved high-end clusters...
8862                 MEMTOTAL=$((MEMTOTAL / 2))
8863         fi
8864         echo "Mem to use for directio: $MEMTOTAL"
8865
8866         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
8867         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
8868         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
8869         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
8870                 head -n1)
8871         echo "Smallest OST: $SMALLESTOST"
8872         [[ $SMALLESTOST -lt 10240 ]] &&
8873                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
8874
8875         trap cleanup_test_78 EXIT
8876
8877         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
8878                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
8879
8880         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
8881         echo "File size: $F78SIZE"
8882         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
8883         for i in $(seq 1 $NSEQ); do
8884                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
8885                 echo directIO rdwr round $i of $NSEQ
8886                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
8887         done
8888
8889         cleanup_test_78
8890 }
8891 run_test 78 "handle large O_DIRECT writes correctly ============"
8892
8893 test_79() { # bug 12743
8894         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8895
8896         wait_delete_completed
8897
8898         BKTOTAL=$(calc_osc_kbytes kbytestotal)
8899         BKFREE=$(calc_osc_kbytes kbytesfree)
8900         BKAVAIL=$(calc_osc_kbytes kbytesavail)
8901
8902         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
8903         DFTOTAL=`echo $STRING | cut -d, -f1`
8904         DFUSED=`echo $STRING  | cut -d, -f2`
8905         DFAVAIL=`echo $STRING | cut -d, -f3`
8906         DFFREE=$(($DFTOTAL - $DFUSED))
8907
8908         ALLOWANCE=$((64 * $OSTCOUNT))
8909
8910         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
8911            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
8912                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
8913         fi
8914         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
8915            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
8916                 error "df free($DFFREE) mismatch OST free($BKFREE)"
8917         fi
8918         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
8919            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
8920                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
8921         fi
8922 }
8923 run_test 79 "df report consistency check ======================="
8924
8925 test_80() { # bug 10718
8926         remote_ost_nodsh && skip "remote OST with nodsh"
8927         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8928
8929         # relax strong synchronous semantics for slow backends like ZFS
8930         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
8931                 local soc="obdfilter.*.sync_lock_cancel"
8932                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
8933
8934                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
8935                 if [ -z "$save" ]; then
8936                         soc="obdfilter.*.sync_on_lock_cancel"
8937                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
8938                 fi
8939
8940                 if [ "$save" != "never" ]; then
8941                         local hosts=$(comma_list $(osts_nodes))
8942
8943                         do_nodes $hosts $LCTL set_param $soc=never
8944                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
8945                 fi
8946         fi
8947
8948         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
8949         sync; sleep 1; sync
8950         local before=$(date +%s)
8951         cancel_lru_locks osc
8952         local after=$(date +%s)
8953         local diff=$((after - before))
8954         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
8955
8956         rm -f $DIR/$tfile
8957 }
8958 run_test 80 "Page eviction is equally fast at high offsets too"
8959
8960 test_81a() { # LU-456
8961         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8962         remote_ost_nodsh && skip "remote OST with nodsh"
8963
8964         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
8965         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
8966         do_facet ost1 lctl set_param fail_loc=0x80000228
8967
8968         # write should trigger a retry and success
8969         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8970         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
8971         RC=$?
8972         if [ $RC -ne 0 ] ; then
8973                 error "write should success, but failed for $RC"
8974         fi
8975 }
8976 run_test 81a "OST should retry write when get -ENOSPC ==============="
8977
8978 test_81b() { # LU-456
8979         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8980         remote_ost_nodsh && skip "remote OST with nodsh"
8981
8982         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
8983         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
8984         do_facet ost1 lctl set_param fail_loc=0x228
8985
8986         # write should retry several times and return -ENOSPC finally
8987         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8988         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
8989         RC=$?
8990         ENOSPC=28
8991         if [ $RC -ne $ENOSPC ] ; then
8992                 error "dd should fail for -ENOSPC, but succeed."
8993         fi
8994 }
8995 run_test 81b "OST should return -ENOSPC when retry still fails ======="
8996
8997 test_82() { # LU-1031
8998         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10
8999         local gid1=14091995
9000         local gid2=16022000
9001
9002         multiop_bg_pause $DIR/$tfile OG${gid1}_g${gid1}c || return 1
9003         local MULTIPID1=$!
9004         multiop_bg_pause $DIR/$tfile O_G${gid2}r10g${gid2}c || return 2
9005         local MULTIPID2=$!
9006         kill -USR1 $MULTIPID2
9007         sleep 2
9008         if [[ `ps h -o comm -p $MULTIPID2` == "" ]]; then
9009                 error "First grouplock does not block second one"
9010         else
9011                 echo "Second grouplock blocks first one"
9012         fi
9013         kill -USR1 $MULTIPID1
9014         wait $MULTIPID1
9015         wait $MULTIPID2
9016 }
9017 run_test 82 "Basic grouplock test"
9018
9019 test_99() {
9020         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
9021
9022         test_mkdir $DIR/$tdir.cvsroot
9023         chown $RUNAS_ID $DIR/$tdir.cvsroot
9024
9025         cd $TMP
9026         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
9027
9028         cd /etc/init.d
9029         # some versions of cvs import exit(1) when asked to import links or
9030         # files they can't read.  ignore those files.
9031         local toignore=$(find . -type l -printf '-I %f\n' -o \
9032                          ! -perm /4 -printf '-I %f\n')
9033         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
9034                 $tdir.reposname vtag rtag
9035
9036         cd $DIR
9037         test_mkdir $DIR/$tdir.reposname
9038         chown $RUNAS_ID $DIR/$tdir.reposname
9039         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
9040
9041         cd $DIR/$tdir.reposname
9042         $RUNAS touch foo99
9043         $RUNAS cvs add -m 'addmsg' foo99
9044         $RUNAS cvs update
9045         $RUNAS cvs commit -m 'nomsg' foo99
9046         rm -fr $DIR/$tdir.cvsroot
9047 }
9048 run_test 99 "cvs strange file/directory operations"
9049
9050 test_100() {
9051         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9052         [[ "$NETTYPE" =~ tcp ]] ||
9053                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
9054         remote_ost_nodsh && skip "remote OST with nodsh"
9055         remote_mds_nodsh && skip "remote MDS with nodsh"
9056         remote_servers ||
9057                 skip "useless for local single node setup"
9058
9059         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
9060                 [ "$PROT" != "tcp" ] && continue
9061                 RPORT=$(echo $REMOTE | cut -d: -f2)
9062                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
9063
9064                 rc=0
9065                 LPORT=`echo $LOCAL | cut -d: -f2`
9066                 if [ $LPORT -ge 1024 ]; then
9067                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
9068                         netstat -tna
9069                         error_exit "local: $LPORT > 1024, remote: $RPORT"
9070                 fi
9071         done
9072         [ "$rc" = 0 ] || error_exit "privileged port not found" )
9073 }
9074 run_test 100 "check local port using privileged port ==========="
9075
9076 function get_named_value()
9077 {
9078     local tag
9079
9080     tag=$1
9081     while read ;do
9082         line=$REPLY
9083         case $line in
9084         $tag*)
9085             echo $line | sed "s/^$tag[ ]*//"
9086             break
9087             ;;
9088         esac
9089     done
9090 }
9091
9092 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
9093                    awk '/^max_cached_mb/ { print $2 }')
9094
9095 cleanup_101a() {
9096         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
9097         trap 0
9098 }
9099
9100 test_101a() {
9101         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9102
9103         local s
9104         local discard
9105         local nreads=10000
9106         local cache_limit=32
9107
9108         $LCTL set_param -n osc.*-osc*.rpc_stats 0
9109         trap cleanup_101a EXIT
9110         $LCTL set_param -n llite.*.read_ahead_stats 0
9111         $LCTL set_param -n llite.*.max_cached_mb $cache_limit
9112
9113         #
9114         # randomly read 10000 of 64K chunks from file 3x 32MB in size
9115         #
9116         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
9117         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
9118
9119         discard=0
9120         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
9121                 get_named_value 'read but discarded' | cut -d" " -f1); do
9122                         discard=$(($discard + $s))
9123         done
9124         cleanup_101a
9125
9126         $LCTL get_param osc.*-osc*.rpc_stats
9127         $LCTL get_param llite.*.read_ahead_stats
9128
9129         # Discard is generally zero, but sometimes a few random reads line up
9130         # and trigger larger readahead, which is wasted & leads to discards.
9131         if [[ $(($discard)) -gt $nreads ]]; then
9132                 error "too many ($discard) discarded pages"
9133         fi
9134         rm -f $DIR/$tfile || true
9135 }
9136 run_test 101a "check read-ahead for random reads"
9137
9138 setup_test101bc() {
9139         test_mkdir $DIR/$tdir
9140         local ssize=$1
9141         local FILE_LENGTH=$2
9142         STRIPE_OFFSET=0
9143
9144         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
9145
9146         local list=$(comma_list $(osts_nodes))
9147         set_osd_param $list '' read_cache_enable 0
9148         set_osd_param $list '' writethrough_cache_enable 0
9149
9150         trap cleanup_test101bc EXIT
9151         # prepare the read-ahead file
9152         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
9153
9154         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
9155                                 count=$FILE_SIZE_MB 2> /dev/null
9156
9157 }
9158
9159 cleanup_test101bc() {
9160         trap 0
9161         rm -rf $DIR/$tdir
9162         rm -f $DIR/$tfile
9163
9164         local list=$(comma_list $(osts_nodes))
9165         set_osd_param $list '' read_cache_enable 1
9166         set_osd_param $list '' writethrough_cache_enable 1
9167 }
9168
9169 calc_total() {
9170         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
9171 }
9172
9173 ra_check_101() {
9174         local READ_SIZE=$1
9175         local STRIPE_SIZE=$2
9176         local FILE_LENGTH=$3
9177         local RA_INC=1048576
9178         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
9179         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
9180                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
9181         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
9182                         get_named_value 'read but discarded' |
9183                         cut -d" " -f1 | calc_total)
9184         if [[ $DISCARD -gt $discard_limit ]]; then
9185                 $LCTL get_param llite.*.read_ahead_stats
9186                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
9187         else
9188                 echo "Read-ahead success for size ${READ_SIZE}"
9189         fi
9190 }
9191
9192 test_101b() {
9193         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9194         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9195
9196         local STRIPE_SIZE=1048576
9197         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
9198
9199         if [ $SLOW == "yes" ]; then
9200                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
9201         else
9202                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
9203         fi
9204
9205         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
9206
9207         # prepare the read-ahead file
9208         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9209         cancel_lru_locks osc
9210         for BIDX in 2 4 8 16 32 64 128 256
9211         do
9212                 local BSIZE=$((BIDX*4096))
9213                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
9214                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
9215                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
9216                 $LCTL set_param -n llite.*.read_ahead_stats 0
9217                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
9218                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
9219                 cancel_lru_locks osc
9220                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
9221         done
9222         cleanup_test101bc
9223         true
9224 }
9225 run_test 101b "check stride-io mode read-ahead ================="
9226
9227 test_101c() {
9228         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9229
9230         local STRIPE_SIZE=1048576
9231         local FILE_LENGTH=$((STRIPE_SIZE*100))
9232         local nreads=10000
9233         local rsize=65536
9234         local osc_rpc_stats
9235
9236         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9237
9238         cancel_lru_locks osc
9239         $LCTL set_param osc.*.rpc_stats 0
9240         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
9241         $LCTL get_param osc.*.rpc_stats
9242         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
9243                 local stats=$($LCTL get_param -n $osc_rpc_stats)
9244                 local lines=$(echo "$stats" | awk 'END {print NR;}')
9245                 local size
9246
9247                 if [ $lines -le 20 ]; then
9248                         echo "continue debug"
9249                         continue
9250                 fi
9251                 for size in 1 2 4 8; do
9252                         local rpc=$(echo "$stats" |
9253                                     awk '($1 == "'$size':") {print $2; exit; }')
9254                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
9255                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
9256                 done
9257                 echo "$osc_rpc_stats check passed!"
9258         done
9259         cleanup_test101bc
9260         true
9261 }
9262 run_test 101c "check stripe_size aligned read-ahead ================="
9263
9264 test_101d() {
9265         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9266
9267         local file=$DIR/$tfile
9268         local sz_MB=${FILESIZE_101d:-80}
9269         local ra_MB=${READAHEAD_MB:-40}
9270
9271         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
9272         [ $free_MB -lt $sz_MB ] &&
9273                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
9274
9275         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
9276         $LFS setstripe -c -1 $file || error "setstripe failed"
9277
9278         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
9279         echo Cancel LRU locks on lustre client to flush the client cache
9280         cancel_lru_locks osc
9281
9282         echo Disable read-ahead
9283         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9284         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9285         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_RA" EXIT
9286         $LCTL get_param -n llite.*.max_read_ahead_mb
9287
9288         echo "Reading the test file $file with read-ahead disabled"
9289         local sz_KB=$((sz_MB * 1024 / 4))
9290         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
9291         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
9292         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9293                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9294
9295         echo "Cancel LRU locks on lustre client to flush the client cache"
9296         cancel_lru_locks osc
9297         echo Enable read-ahead with ${ra_MB}MB
9298         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
9299
9300         echo "Reading the test file $file with read-ahead enabled"
9301         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9302                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9303
9304         echo "read-ahead disabled time read $raOFF"
9305         echo "read-ahead enabled time read $raON"
9306
9307         rm -f $file
9308         wait_delete_completed
9309
9310         # use awk for this check instead of bash because it handles decimals
9311         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
9312                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
9313 }
9314 run_test 101d "file read with and without read-ahead enabled"
9315
9316 test_101e() {
9317         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9318
9319         local file=$DIR/$tfile
9320         local size_KB=500  #KB
9321         local count=100
9322         local bsize=1024
9323
9324         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
9325         local need_KB=$((count * size_KB))
9326         [[ $free_KB -le $need_KB ]] &&
9327                 skip_env "Need free space $need_KB, have $free_KB"
9328
9329         echo "Creating $count ${size_KB}K test files"
9330         for ((i = 0; i < $count; i++)); do
9331                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
9332         done
9333
9334         echo "Cancel LRU locks on lustre client to flush the client cache"
9335         cancel_lru_locks $OSC
9336
9337         echo "Reset readahead stats"
9338         $LCTL set_param -n llite.*.read_ahead_stats 0
9339
9340         for ((i = 0; i < $count; i++)); do
9341                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
9342         done
9343
9344         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9345                      get_named_value 'misses' | cut -d" " -f1 | calc_total)
9346
9347         for ((i = 0; i < $count; i++)); do
9348                 rm -rf $file.$i 2>/dev/null
9349         done
9350
9351         #10000 means 20% reads are missing in readahead
9352         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
9353 }
9354 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
9355
9356 test_101f() {
9357         which iozone || skip_env "no iozone installed"
9358
9359         local old_debug=$($LCTL get_param debug)
9360         old_debug=${old_debug#*=}
9361         $LCTL set_param debug="reada mmap"
9362
9363         # create a test file
9364         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
9365
9366         echo Cancel LRU locks on lustre client to flush the client cache
9367         cancel_lru_locks osc
9368
9369         echo Reset readahead stats
9370         $LCTL set_param -n llite.*.read_ahead_stats 0
9371
9372         echo mmap read the file with small block size
9373         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
9374                 > /dev/null 2>&1
9375
9376         echo checking missing pages
9377         $LCTL get_param llite.*.read_ahead_stats
9378         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9379                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9380
9381         $LCTL set_param debug="$old_debug"
9382         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
9383         rm -f $DIR/$tfile
9384 }
9385 run_test 101f "check mmap read performance"
9386
9387 test_101g_brw_size_test() {
9388         local mb=$1
9389         local pages=$((mb * 1048576 / PAGE_SIZE))
9390         local file=$DIR/$tfile
9391
9392         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
9393                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
9394         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
9395                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
9396                         return 2
9397         done
9398
9399         stack_trap "rm -f $file" EXIT
9400         $LCTL set_param -n osc.*.rpc_stats=0
9401
9402         # 10 RPCs should be enough for the test
9403         local count=10
9404         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
9405                 { error "dd write ${mb} MB blocks failed"; return 3; }
9406         cancel_lru_locks osc
9407         dd of=/dev/null if=$file bs=${mb}M count=$count ||
9408                 { error "dd write ${mb} MB blocks failed"; return 4; }
9409
9410         # calculate number of full-sized read and write RPCs
9411         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
9412                 sed -n '/pages per rpc/,/^$/p' |
9413                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
9414                 END { print reads,writes }'))
9415         [ ${rpcs[0]} -ne $count ] && error "${rpcs[0]} != $count read RPCs" &&
9416                 return 5
9417         [ ${rpcs[1]} -ne $count ] && error "${rpcs[1]} != $count write RPCs" &&
9418                 return 6
9419
9420         return 0
9421 }
9422
9423 test_101g() {
9424         remote_ost_nodsh && skip "remote OST with nodsh"
9425
9426         local rpcs
9427         local osts=$(get_facets OST)
9428         local list=$(comma_list $(osts_nodes))
9429         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9430         local brw_size="obdfilter.*.brw_size"
9431
9432         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9433
9434         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
9435
9436         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
9437                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
9438                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
9439            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
9440                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
9441                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
9442
9443                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
9444                         suffix="M"
9445
9446                 if [[ $orig_mb -lt 16 ]]; then
9447                         save_lustre_params $osts "$brw_size" > $p
9448                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
9449                                 error "set 16MB RPC size failed"
9450
9451                         echo "remount client to enable new RPC size"
9452                         remount_client $MOUNT || error "remount_client failed"
9453                 fi
9454
9455                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
9456                 # should be able to set brw_size=12, but no rpc_stats for that
9457                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
9458         fi
9459
9460         test_101g_brw_size_test 4 || error "4MB RPC test failed"
9461
9462         if [[ $orig_mb -lt 16 ]]; then
9463                 restore_lustre_params < $p
9464                 remount_client $MOUNT || error "remount_client restore failed"
9465         fi
9466
9467         rm -f $p $DIR/$tfile
9468 }
9469 run_test 101g "Big bulk(4/16 MiB) readahead"
9470
9471 test_101h() {
9472         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9473
9474         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
9475                 error "dd 70M file failed"
9476         echo Cancel LRU locks on lustre client to flush the client cache
9477         cancel_lru_locks osc
9478
9479         echo "Reset readahead stats"
9480         $LCTL set_param -n llite.*.read_ahead_stats 0
9481
9482         echo "Read 10M of data but cross 64M bundary"
9483         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
9484         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9485                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9486         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
9487         rm -f $p $DIR/$tfile
9488 }
9489 run_test 101h "Readahead should cover current read window"
9490
9491 test_101i() {
9492         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
9493                 error "dd 10M file failed"
9494
9495         local max_per_file_mb=$($LCTL get_param -n \
9496                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
9497         cancel_lru_locks osc
9498         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
9499         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
9500                 error "set max_read_ahead_per_file_mb to 1 failed"
9501
9502         echo "Reset readahead stats"
9503         $LCTL set_param llite.*.read_ahead_stats=0
9504
9505         dd if=$DIR/$tfile of=/dev/null bs=2M
9506
9507         $LCTL get_param llite.*.read_ahead_stats
9508         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9509                      awk '/misses/ { print $2 }')
9510         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
9511         rm -f $DIR/$tfile
9512 }
9513 run_test 101i "allow current readahead to exceed reservation"
9514
9515 test_101j() {
9516         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
9517                 error "setstripe $DIR/$tfile failed"
9518         local file_size=$((1048576 * 16))
9519         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9520         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
9521
9522         echo Disable read-ahead
9523         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9524
9525         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
9526         for blk in $PAGE_SIZE 1048576 $file_size; do
9527                 cancel_lru_locks osc
9528                 echo "Reset readahead stats"
9529                 $LCTL set_param -n llite.*.read_ahead_stats=0
9530                 local count=$(($file_size / $blk))
9531                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
9532                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9533                              get_named_value 'failed to fast read' |
9534                              cut -d" " -f1 | calc_total)
9535                 $LCTL get_param -n llite.*.read_ahead_stats
9536                 [ $miss -eq $count ] || error "expected $count got $miss"
9537         done
9538
9539         rm -f $p $DIR/$tfile
9540 }
9541 run_test 101j "A complete read block should be submitted when no RA"
9542
9543 setup_test102() {
9544         test_mkdir $DIR/$tdir
9545         chown $RUNAS_ID $DIR/$tdir
9546         STRIPE_SIZE=65536
9547         STRIPE_OFFSET=1
9548         STRIPE_COUNT=$OSTCOUNT
9549         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
9550
9551         trap cleanup_test102 EXIT
9552         cd $DIR
9553         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
9554         cd $DIR/$tdir
9555         for num in 1 2 3 4; do
9556                 for count in $(seq 1 $STRIPE_COUNT); do
9557                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
9558                                 local size=`expr $STRIPE_SIZE \* $num`
9559                                 local file=file"$num-$idx-$count"
9560                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
9561                         done
9562                 done
9563         done
9564
9565         cd $DIR
9566         $1 tar cf $TMP/f102.tar $tdir --xattrs
9567 }
9568
9569 cleanup_test102() {
9570         trap 0
9571         rm -f $TMP/f102.tar
9572         rm -rf $DIR/d0.sanity/d102
9573 }
9574
9575 test_102a() {
9576         [ "$UID" != 0 ] && skip "must run as root"
9577         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
9578                 skip_env "must have user_xattr"
9579
9580         [ -z "$(which setfattr 2>/dev/null)" ] &&
9581                 skip_env "could not find setfattr"
9582
9583         local testfile=$DIR/$tfile
9584
9585         touch $testfile
9586         echo "set/get xattr..."
9587         setfattr -n trusted.name1 -v value1 $testfile ||
9588                 error "setfattr -n trusted.name1=value1 $testfile failed"
9589         getfattr -n trusted.name1 $testfile 2> /dev/null |
9590           grep "trusted.name1=.value1" ||
9591                 error "$testfile missing trusted.name1=value1"
9592
9593         setfattr -n user.author1 -v author1 $testfile ||
9594                 error "setfattr -n user.author1=author1 $testfile failed"
9595         getfattr -n user.author1 $testfile 2> /dev/null |
9596           grep "user.author1=.author1" ||
9597                 error "$testfile missing trusted.author1=author1"
9598
9599         echo "listxattr..."
9600         setfattr -n trusted.name2 -v value2 $testfile ||
9601                 error "$testfile unable to set trusted.name2"
9602         setfattr -n trusted.name3 -v value3 $testfile ||
9603                 error "$testfile unable to set trusted.name3"
9604         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
9605             grep "trusted.name" | wc -l) -eq 3 ] ||
9606                 error "$testfile missing 3 trusted.name xattrs"
9607
9608         setfattr -n user.author2 -v author2 $testfile ||
9609                 error "$testfile unable to set user.author2"
9610         setfattr -n user.author3 -v author3 $testfile ||
9611                 error "$testfile unable to set user.author3"
9612         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
9613             grep "user.author" | wc -l) -eq 3 ] ||
9614                 error "$testfile missing 3 user.author xattrs"
9615
9616         echo "remove xattr..."
9617         setfattr -x trusted.name1 $testfile ||
9618                 error "$testfile error deleting trusted.name1"
9619         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
9620                 error "$testfile did not delete trusted.name1 xattr"
9621
9622         setfattr -x user.author1 $testfile ||
9623                 error "$testfile error deleting user.author1"
9624         echo "set lustre special xattr ..."
9625         $LFS setstripe -c1 $testfile
9626         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
9627                 awk -F "=" '/trusted.lov/ { print $2 }' )
9628         setfattr -n "trusted.lov" -v $lovea $testfile ||
9629                 error "$testfile doesn't ignore setting trusted.lov again"
9630         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
9631                 error "$testfile allow setting invalid trusted.lov"
9632         rm -f $testfile
9633 }
9634 run_test 102a "user xattr test =================================="
9635
9636 check_102b_layout() {
9637         local layout="$*"
9638         local testfile=$DIR/$tfile
9639
9640         echo "test layout '$layout'"
9641         $LFS setstripe $layout $testfile || error "setstripe failed"
9642         $LFS getstripe -y $testfile
9643
9644         echo "get/set/list trusted.lov xattr ..." # b=10930
9645         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
9646         [[ "$value" =~ "trusted.lov" ]] ||
9647                 error "can't get trusted.lov from $testfile"
9648         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
9649                 error "getstripe failed"
9650
9651         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
9652
9653         value=$(cut -d= -f2 <<<$value)
9654         # LU-13168: truncated xattr should fail if short lov_user_md header
9655         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
9656                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
9657         for len in $lens; do
9658                 echo "setfattr $len $testfile.2"
9659                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
9660                         [ $len -lt 66 ] && error "short xattr len=$len worked"
9661         done
9662         local stripe_size=$($LFS getstripe -S $testfile.2)
9663         local stripe_count=$($LFS getstripe -c $testfile.2)
9664         [[ $stripe_size -eq 65536 ]] ||
9665                 error "stripe size $stripe_size != 65536"
9666         [[ $stripe_count -eq $stripe_count_orig ]] ||
9667                 error "stripe count $stripe_count != $stripe_count_orig"
9668         rm $testfile $testfile.2
9669 }
9670
9671 test_102b() {
9672         [ -z "$(which setfattr 2>/dev/null)" ] &&
9673                 skip_env "could not find setfattr"
9674         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9675
9676         # check plain layout
9677         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
9678
9679         # and also check composite layout
9680         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
9681
9682 }
9683 run_test 102b "getfattr/setfattr for trusted.lov EAs"
9684
9685 test_102c() {
9686         [ -z "$(which setfattr 2>/dev/null)" ] &&
9687                 skip_env "could not find setfattr"
9688         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9689
9690         # b10930: get/set/list lustre.lov xattr
9691         echo "get/set/list lustre.lov xattr ..."
9692         test_mkdir $DIR/$tdir
9693         chown $RUNAS_ID $DIR/$tdir
9694         local testfile=$DIR/$tdir/$tfile
9695         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
9696                 error "setstripe failed"
9697         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
9698                 error "getstripe failed"
9699         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
9700         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
9701
9702         local testfile2=${testfile}2
9703         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
9704                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
9705
9706         $RUNAS $MCREATE $testfile2
9707         $RUNAS setfattr -n lustre.lov -v $value $testfile2
9708         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
9709         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
9710         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
9711         [ $stripe_count -eq $STRIPECOUNT ] ||
9712                 error "stripe count $stripe_count != $STRIPECOUNT"
9713 }
9714 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
9715
9716 compare_stripe_info1() {
9717         local stripe_index_all_zero=true
9718
9719         for num in 1 2 3 4; do
9720                 for count in $(seq 1 $STRIPE_COUNT); do
9721                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
9722                                 local size=$((STRIPE_SIZE * num))
9723                                 local file=file"$num-$offset-$count"
9724                                 stripe_size=$($LFS getstripe -S $PWD/$file)
9725                                 [[ $stripe_size -ne $size ]] &&
9726                                     error "$file: size $stripe_size != $size"
9727                                 stripe_count=$($LFS getstripe -c $PWD/$file)
9728                                 # allow fewer stripes to be created, ORI-601
9729                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
9730                                     error "$file: count $stripe_count != $count"
9731                                 stripe_index=$($LFS getstripe -i $PWD/$file)
9732                                 [[ $stripe_index -ne 0 ]] &&
9733                                         stripe_index_all_zero=false
9734                         done
9735                 done
9736         done
9737         $stripe_index_all_zero &&
9738                 error "all files are being extracted starting from OST index 0"
9739         return 0
9740 }
9741
9742 have_xattrs_include() {
9743         tar --help | grep -q xattrs-include &&
9744                 echo --xattrs-include="lustre.*"
9745 }
9746
9747 test_102d() {
9748         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9749         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9750
9751         XINC=$(have_xattrs_include)
9752         setup_test102
9753         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
9754         cd $DIR/$tdir/$tdir
9755         compare_stripe_info1
9756 }
9757 run_test 102d "tar restore stripe info from tarfile,not keep osts"
9758
9759 test_102f() {
9760         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9761         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9762
9763         XINC=$(have_xattrs_include)
9764         setup_test102
9765         test_mkdir $DIR/$tdir.restore
9766         cd $DIR
9767         tar cf - --xattrs $tdir | tar xf - \
9768                 -C $DIR/$tdir.restore --xattrs $XINC
9769         cd $DIR/$tdir.restore/$tdir
9770         compare_stripe_info1
9771 }
9772 run_test 102f "tar copy files, not keep osts"
9773
9774 grow_xattr() {
9775         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
9776                 skip "must have user_xattr"
9777         [ -z "$(which setfattr 2>/dev/null)" ] &&
9778                 skip_env "could not find setfattr"
9779         [ -z "$(which getfattr 2>/dev/null)" ] &&
9780                 skip_env "could not find getfattr"
9781
9782         local xsize=${1:-1024}  # in bytes
9783         local file=$DIR/$tfile
9784         local value="$(generate_string $xsize)"
9785         local xbig=trusted.big
9786         local toobig=$2
9787
9788         touch $file
9789         log "save $xbig on $file"
9790         if [ -z "$toobig" ]
9791         then
9792                 setfattr -n $xbig -v $value $file ||
9793                         error "saving $xbig on $file failed"
9794         else
9795                 setfattr -n $xbig -v $value $file &&
9796                         error "saving $xbig on $file succeeded"
9797                 return 0
9798         fi
9799
9800         local orig=$(get_xattr_value $xbig $file)
9801         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
9802
9803         local xsml=trusted.sml
9804         log "save $xsml on $file"
9805         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
9806
9807         local new=$(get_xattr_value $xbig $file)
9808         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
9809
9810         log "grow $xsml on $file"
9811         setfattr -n $xsml -v "$value" $file ||
9812                 error "growing $xsml on $file failed"
9813
9814         new=$(get_xattr_value $xbig $file)
9815         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
9816         log "$xbig still valid after growing $xsml"
9817
9818         rm -f $file
9819 }
9820
9821 test_102h() { # bug 15777
9822         grow_xattr 1024
9823 }
9824 run_test 102h "grow xattr from inside inode to external block"
9825
9826 test_102ha() {
9827         large_xattr_enabled || skip_env "ea_inode feature disabled"
9828
9829         echo "setting xattr of max xattr size: $(max_xattr_size)"
9830         grow_xattr $(max_xattr_size)
9831
9832         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
9833         echo "This should fail:"
9834         grow_xattr $(($(max_xattr_size) + 10)) 1
9835 }
9836 run_test 102ha "grow xattr from inside inode to external inode"
9837
9838 test_102i() { # bug 17038
9839         [ -z "$(which getfattr 2>/dev/null)" ] &&
9840                 skip "could not find getfattr"
9841
9842         touch $DIR/$tfile
9843         ln -s $DIR/$tfile $DIR/${tfile}link
9844         getfattr -n trusted.lov $DIR/$tfile ||
9845                 error "lgetxattr on $DIR/$tfile failed"
9846         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
9847                 grep -i "no such attr" ||
9848                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
9849         rm -f $DIR/$tfile $DIR/${tfile}link
9850 }
9851 run_test 102i "lgetxattr test on symbolic link ============"
9852
9853 test_102j() {
9854         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9855         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9856
9857         XINC=$(have_xattrs_include)
9858         setup_test102 "$RUNAS"
9859         chown $RUNAS_ID $DIR/$tdir
9860         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
9861         cd $DIR/$tdir/$tdir
9862         compare_stripe_info1 "$RUNAS"
9863 }
9864 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
9865
9866 test_102k() {
9867         [ -z "$(which setfattr 2>/dev/null)" ] &&
9868                 skip "could not find setfattr"
9869
9870         touch $DIR/$tfile
9871         # b22187 just check that does not crash for regular file.
9872         setfattr -n trusted.lov $DIR/$tfile
9873         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
9874         local test_kdir=$DIR/$tdir
9875         test_mkdir $test_kdir
9876         local default_size=$($LFS getstripe -S $test_kdir)
9877         local default_count=$($LFS getstripe -c $test_kdir)
9878         local default_offset=$($LFS getstripe -i $test_kdir)
9879         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
9880                 error 'dir setstripe failed'
9881         setfattr -n trusted.lov $test_kdir
9882         local stripe_size=$($LFS getstripe -S $test_kdir)
9883         local stripe_count=$($LFS getstripe -c $test_kdir)
9884         local stripe_offset=$($LFS getstripe -i $test_kdir)
9885         [ $stripe_size -eq $default_size ] ||
9886                 error "stripe size $stripe_size != $default_size"
9887         [ $stripe_count -eq $default_count ] ||
9888                 error "stripe count $stripe_count != $default_count"
9889         [ $stripe_offset -eq $default_offset ] ||
9890                 error "stripe offset $stripe_offset != $default_offset"
9891         rm -rf $DIR/$tfile $test_kdir
9892 }
9893 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
9894
9895 test_102l() {
9896         [ -z "$(which getfattr 2>/dev/null)" ] &&
9897                 skip "could not find getfattr"
9898
9899         # LU-532 trusted. xattr is invisible to non-root
9900         local testfile=$DIR/$tfile
9901
9902         touch $testfile
9903
9904         echo "listxattr as user..."
9905         chown $RUNAS_ID $testfile
9906         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
9907             grep -q "trusted" &&
9908                 error "$testfile trusted xattrs are user visible"
9909
9910         return 0;
9911 }
9912 run_test 102l "listxattr size test =================================="
9913
9914 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
9915         local path=$DIR/$tfile
9916         touch $path
9917
9918         listxattr_size_check $path || error "listattr_size_check $path failed"
9919 }
9920 run_test 102m "Ensure listxattr fails on small bufffer ========"
9921
9922 cleanup_test102
9923
9924 getxattr() { # getxattr path name
9925         # Return the base64 encoding of the value of xattr name on path.
9926         local path=$1
9927         local name=$2
9928
9929         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
9930         # file: $path
9931         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
9932         #
9933         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
9934
9935         getfattr --absolute-names --encoding=base64 --name=$name $path |
9936                 awk -F= -v name=$name '$1 == name {
9937                         print substr($0, index($0, "=") + 1);
9938         }'
9939 }
9940
9941 test_102n() { # LU-4101 mdt: protect internal xattrs
9942         [ -z "$(which setfattr 2>/dev/null)" ] &&
9943                 skip "could not find setfattr"
9944         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
9945         then
9946                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
9947         fi
9948
9949         local file0=$DIR/$tfile.0
9950         local file1=$DIR/$tfile.1
9951         local xattr0=$TMP/$tfile.0
9952         local xattr1=$TMP/$tfile.1
9953         local namelist="lov lma lmv link fid version som hsm"
9954         local name
9955         local value
9956
9957         rm -rf $file0 $file1 $xattr0 $xattr1
9958         touch $file0 $file1
9959
9960         # Get 'before' xattrs of $file1.
9961         getfattr --absolute-names --dump --match=- $file1 > $xattr0
9962
9963         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
9964                 namelist+=" lfsck_namespace"
9965         for name in $namelist; do
9966                 # Try to copy xattr from $file0 to $file1.
9967                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
9968
9969                 setfattr --name=trusted.$name --value="$value" $file1 ||
9970                         error "setxattr 'trusted.$name' failed"
9971
9972                 # Try to set a garbage xattr.
9973                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
9974
9975                 if [[ x$name == "xlov" ]]; then
9976                         setfattr --name=trusted.lov --value="$value" $file1 &&
9977                         error "setxattr invalid 'trusted.lov' success"
9978                 else
9979                         setfattr --name=trusted.$name --value="$value" $file1 ||
9980                                 error "setxattr invalid 'trusted.$name' failed"
9981                 fi
9982
9983                 # Try to remove the xattr from $file1. We don't care if this
9984                 # appears to succeed or fail, we just don't want there to be
9985                 # any changes or crashes.
9986                 setfattr --remove=$trusted.$name $file1 2> /dev/null
9987         done
9988
9989         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
9990         then
9991                 name="lfsck_ns"
9992                 # Try to copy xattr from $file0 to $file1.
9993                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
9994
9995                 setfattr --name=trusted.$name --value="$value" $file1 ||
9996                         error "setxattr 'trusted.$name' failed"
9997
9998                 # Try to set a garbage xattr.
9999                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10000
10001                 setfattr --name=trusted.$name --value="$value" $file1 ||
10002                         error "setxattr 'trusted.$name' failed"
10003
10004                 # Try to remove the xattr from $file1. We don't care if this
10005                 # appears to succeed or fail, we just don't want there to be
10006                 # any changes or crashes.
10007                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10008         fi
10009
10010         # Get 'after' xattrs of file1.
10011         getfattr --absolute-names --dump --match=- $file1 > $xattr1
10012
10013         if ! diff $xattr0 $xattr1; then
10014                 error "before and after xattrs of '$file1' differ"
10015         fi
10016
10017         rm -rf $file0 $file1 $xattr0 $xattr1
10018
10019         return 0
10020 }
10021 run_test 102n "silently ignore setxattr on internal trusted xattrs"
10022
10023 test_102p() { # LU-4703 setxattr did not check ownership
10024         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
10025                 skip "MDS needs to be at least 2.5.56"
10026
10027         local testfile=$DIR/$tfile
10028
10029         touch $testfile
10030
10031         echo "setfacl as user..."
10032         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
10033         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
10034
10035         echo "setfattr as user..."
10036         setfacl -m "u:$RUNAS_ID:---" $testfile
10037         $RUNAS setfattr -x system.posix_acl_access $testfile
10038         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
10039 }
10040 run_test 102p "check setxattr(2) correctly fails without permission"
10041
10042 test_102q() {
10043         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
10044                 skip "MDS needs to be at least 2.6.92"
10045
10046         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
10047 }
10048 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
10049
10050 test_102r() {
10051         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
10052                 skip "MDS needs to be at least 2.6.93"
10053
10054         touch $DIR/$tfile || error "touch"
10055         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
10056         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
10057         rm $DIR/$tfile || error "rm"
10058
10059         #normal directory
10060         mkdir -p $DIR/$tdir || error "mkdir"
10061         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10062         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10063         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10064                 error "$testfile error deleting user.author1"
10065         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10066                 grep "user.$(basename $tdir)" &&
10067                 error "$tdir did not delete user.$(basename $tdir)"
10068         rmdir $DIR/$tdir || error "rmdir"
10069
10070         #striped directory
10071         test_mkdir $DIR/$tdir
10072         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10073         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10074         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10075                 error "$testfile error deleting user.author1"
10076         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10077                 grep "user.$(basename $tdir)" &&
10078                 error "$tdir did not delete user.$(basename $tdir)"
10079         rmdir $DIR/$tdir || error "rm striped dir"
10080 }
10081 run_test 102r "set EAs with empty values"
10082
10083 test_102s() {
10084         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10085                 skip "MDS needs to be at least 2.11.52"
10086
10087         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10088
10089         save_lustre_params client "llite.*.xattr_cache" > $save
10090
10091         for cache in 0 1; do
10092                 lctl set_param llite.*.xattr_cache=$cache
10093
10094                 rm -f $DIR/$tfile
10095                 touch $DIR/$tfile || error "touch"
10096                 for prefix in lustre security system trusted user; do
10097                         # Note getxattr() may fail with 'Operation not
10098                         # supported' or 'No such attribute' depending
10099                         # on prefix and cache.
10100                         getfattr -n $prefix.n102s $DIR/$tfile &&
10101                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
10102                 done
10103         done
10104
10105         restore_lustre_params < $save
10106 }
10107 run_test 102s "getting nonexistent xattrs should fail"
10108
10109 test_102t() {
10110         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10111                 skip "MDS needs to be at least 2.11.52"
10112
10113         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10114
10115         save_lustre_params client "llite.*.xattr_cache" > $save
10116
10117         for cache in 0 1; do
10118                 lctl set_param llite.*.xattr_cache=$cache
10119
10120                 for buf_size in 0 256; do
10121                         rm -f $DIR/$tfile
10122                         touch $DIR/$tfile || error "touch"
10123                         setfattr -n user.multiop $DIR/$tfile
10124                         $MULTIOP $DIR/$tfile oa$buf_size ||
10125                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
10126                 done
10127         done
10128
10129         restore_lustre_params < $save
10130 }
10131 run_test 102t "zero length xattr values handled correctly"
10132
10133 run_acl_subtest()
10134 {
10135     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
10136     return $?
10137 }
10138
10139 test_103a() {
10140         [ "$UID" != 0 ] && skip "must run as root"
10141         $GSS && skip_env "could not run under gss"
10142         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
10143                 skip_env "must have acl enabled"
10144         [ -z "$(which setfacl 2>/dev/null)" ] &&
10145                 skip_env "could not find setfacl"
10146         remote_mds_nodsh && skip "remote MDS with nodsh"
10147
10148         gpasswd -a daemon bin                           # LU-5641
10149         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
10150
10151         declare -a identity_old
10152
10153         for num in $(seq $MDSCOUNT); do
10154                 switch_identity $num true || identity_old[$num]=$?
10155         done
10156
10157         SAVE_UMASK=$(umask)
10158         umask 0022
10159         mkdir -p $DIR/$tdir
10160         cd $DIR/$tdir
10161
10162         echo "performing cp ..."
10163         run_acl_subtest cp || error "run_acl_subtest cp failed"
10164         echo "performing getfacl-noacl..."
10165         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
10166         echo "performing misc..."
10167         run_acl_subtest misc || error  "misc test failed"
10168         echo "performing permissions..."
10169         run_acl_subtest permissions || error "permissions failed"
10170         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
10171         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
10172                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
10173                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
10174         then
10175                 echo "performing permissions xattr..."
10176                 run_acl_subtest permissions_xattr ||
10177                         error "permissions_xattr failed"
10178         fi
10179         echo "performing setfacl..."
10180         run_acl_subtest setfacl || error  "setfacl test failed"
10181
10182         # inheritance test got from HP
10183         echo "performing inheritance..."
10184         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
10185         chmod +x make-tree || error "chmod +x failed"
10186         run_acl_subtest inheritance || error "inheritance test failed"
10187         rm -f make-tree
10188
10189         echo "LU-974 ignore umask when acl is enabled..."
10190         run_acl_subtest 974 || error "LU-974 umask test failed"
10191         if [ $MDSCOUNT -ge 2 ]; then
10192                 run_acl_subtest 974_remote ||
10193                         error "LU-974 umask test failed under remote dir"
10194         fi
10195
10196         echo "LU-2561 newly created file is same size as directory..."
10197         if [ "$mds1_FSTYPE" != "zfs" ]; then
10198                 run_acl_subtest 2561 || error "LU-2561 test failed"
10199         else
10200                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
10201         fi
10202
10203         run_acl_subtest 4924 || error "LU-4924 test failed"
10204
10205         cd $SAVE_PWD
10206         umask $SAVE_UMASK
10207
10208         for num in $(seq $MDSCOUNT); do
10209                 if [ "${identity_old[$num]}" = 1 ]; then
10210                         switch_identity $num false || identity_old[$num]=$?
10211                 fi
10212         done
10213 }
10214 run_test 103a "acl test"
10215
10216 test_103b() {
10217         declare -a pids
10218         local U
10219
10220         for U in {0..511}; do
10221                 {
10222                 local O=$(printf "%04o" $U)
10223
10224                 umask $(printf "%04o" $((511 ^ $O)))
10225                 $LFS setstripe -c 1 $DIR/$tfile.s$O
10226                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
10227
10228                 (( $S == ($O & 0666) )) ||
10229                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
10230
10231                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
10232                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
10233                 (( $S == ($O & 0666) )) ||
10234                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
10235
10236                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
10237                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
10238                 (( $S == ($O & 0666) )) ||
10239                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
10240                 rm -f $DIR/$tfile.[smp]$0
10241                 } &
10242                 local pid=$!
10243
10244                 # limit the concurrently running threads to 64. LU-11878
10245                 local idx=$((U % 64))
10246                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
10247                 pids[idx]=$pid
10248         done
10249         wait
10250 }
10251 run_test 103b "umask lfs setstripe"
10252
10253 test_103c() {
10254         mkdir -p $DIR/$tdir
10255         cp -rp $DIR/$tdir $DIR/$tdir.bak
10256
10257         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
10258                 error "$DIR/$tdir shouldn't contain default ACL"
10259         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
10260                 error "$DIR/$tdir.bak shouldn't contain default ACL"
10261         true
10262 }
10263 run_test 103c "'cp -rp' won't set empty acl"
10264
10265 test_104a() {
10266         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10267
10268         touch $DIR/$tfile
10269         lfs df || error "lfs df failed"
10270         lfs df -ih || error "lfs df -ih failed"
10271         lfs df -h $DIR || error "lfs df -h $DIR failed"
10272         lfs df -i $DIR || error "lfs df -i $DIR failed"
10273         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
10274         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
10275
10276         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
10277         lctl --device %$OSC deactivate
10278         lfs df || error "lfs df with deactivated OSC failed"
10279         lctl --device %$OSC activate
10280         # wait the osc back to normal
10281         wait_osc_import_ready client ost
10282
10283         lfs df || error "lfs df with reactivated OSC failed"
10284         rm -f $DIR/$tfile
10285 }
10286 run_test 104a "lfs df [-ih] [path] test ========================="
10287
10288 test_104b() {
10289         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10290         [ $RUNAS_ID -eq $UID ] &&
10291                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10292
10293         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
10294                         grep "Permission denied" | wc -l)))
10295         if [ $denied_cnt -ne 0 ]; then
10296                 error "lfs check servers test failed"
10297         fi
10298 }
10299 run_test 104b "$RUNAS lfs check servers test ===================="
10300
10301 test_105a() {
10302         # doesn't work on 2.4 kernels
10303         touch $DIR/$tfile
10304         if $(flock_is_enabled); then
10305                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
10306         else
10307                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
10308         fi
10309         rm -f $DIR/$tfile
10310 }
10311 run_test 105a "flock when mounted without -o flock test ========"
10312
10313 test_105b() {
10314         touch $DIR/$tfile
10315         if $(flock_is_enabled); then
10316                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
10317         else
10318                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
10319         fi
10320         rm -f $DIR/$tfile
10321 }
10322 run_test 105b "fcntl when mounted without -o flock test ========"
10323
10324 test_105c() {
10325         touch $DIR/$tfile
10326         if $(flock_is_enabled); then
10327                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
10328         else
10329                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
10330         fi
10331         rm -f $DIR/$tfile
10332 }
10333 run_test 105c "lockf when mounted without -o flock test"
10334
10335 test_105d() { # bug 15924
10336         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10337
10338         test_mkdir $DIR/$tdir
10339         flock_is_enabled || skip_env "mount w/o flock enabled"
10340         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
10341         $LCTL set_param fail_loc=0x80000315
10342         flocks_test 2 $DIR/$tdir
10343 }
10344 run_test 105d "flock race (should not freeze) ========"
10345
10346 test_105e() { # bug 22660 && 22040
10347         flock_is_enabled || skip_env "mount w/o flock enabled"
10348
10349         touch $DIR/$tfile
10350         flocks_test 3 $DIR/$tfile
10351 }
10352 run_test 105e "Two conflicting flocks from same process"
10353
10354 test_106() { #bug 10921
10355         test_mkdir $DIR/$tdir
10356         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
10357         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
10358 }
10359 run_test 106 "attempt exec of dir followed by chown of that dir"
10360
10361 test_107() {
10362         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10363
10364         CDIR=`pwd`
10365         local file=core
10366
10367         cd $DIR
10368         rm -f $file
10369
10370         local save_pattern=$(sysctl -n kernel.core_pattern)
10371         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
10372         sysctl -w kernel.core_pattern=$file
10373         sysctl -w kernel.core_uses_pid=0
10374
10375         ulimit -c unlimited
10376         sleep 60 &
10377         SLEEPPID=$!
10378
10379         sleep 1
10380
10381         kill -s 11 $SLEEPPID
10382         wait $SLEEPPID
10383         if [ -e $file ]; then
10384                 size=`stat -c%s $file`
10385                 [ $size -eq 0 ] && error "Fail to create core file $file"
10386         else
10387                 error "Fail to create core file $file"
10388         fi
10389         rm -f $file
10390         sysctl -w kernel.core_pattern=$save_pattern
10391         sysctl -w kernel.core_uses_pid=$save_uses_pid
10392         cd $CDIR
10393 }
10394 run_test 107 "Coredump on SIG"
10395
10396 test_110() {
10397         test_mkdir $DIR/$tdir
10398         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
10399         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
10400                 error "mkdir with 256 char should fail, but did not"
10401         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
10402                 error "create with 255 char failed"
10403         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
10404                 error "create with 256 char should fail, but did not"
10405
10406         ls -l $DIR/$tdir
10407         rm -rf $DIR/$tdir
10408 }
10409 run_test 110 "filename length checking"
10410
10411 #
10412 # Purpose: To verify dynamic thread (OSS) creation.
10413 #
10414 test_115() {
10415         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10416         remote_ost_nodsh && skip "remote OST with nodsh"
10417
10418         # Lustre does not stop service threads once they are started.
10419         # Reset number of running threads to default.
10420         stopall
10421         setupall
10422
10423         local OSTIO_pre
10424         local save_params="$TMP/sanity-$TESTNAME.parameters"
10425
10426         # Get ll_ost_io count before I/O
10427         OSTIO_pre=$(do_facet ost1 \
10428                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
10429         # Exit if lustre is not running (ll_ost_io not running).
10430         [ -z "$OSTIO_pre" ] && error "no OSS threads"
10431
10432         echo "Starting with $OSTIO_pre threads"
10433         local thread_max=$((OSTIO_pre * 2))
10434         local rpc_in_flight=$((thread_max * 2))
10435         # Number of I/O Process proposed to be started.
10436         local nfiles
10437         local facets=$(get_facets OST)
10438
10439         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
10440         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
10441
10442         # Set in_flight to $rpc_in_flight
10443         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
10444                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
10445         nfiles=${rpc_in_flight}
10446         # Set ost thread_max to $thread_max
10447         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
10448
10449         # 5 Minutes should be sufficient for max number of OSS
10450         # threads(thread_max) to be created.
10451         local timeout=300
10452
10453         # Start I/O.
10454         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
10455         test_mkdir $DIR/$tdir
10456         for i in $(seq $nfiles); do
10457                 local file=$DIR/$tdir/${tfile}-$i
10458                 $LFS setstripe -c -1 -i 0 $file
10459                 ($WTL $file $timeout)&
10460         done
10461
10462         # I/O Started - Wait for thread_started to reach thread_max or report
10463         # error if thread_started is more than thread_max.
10464         echo "Waiting for thread_started to reach thread_max"
10465         local thread_started=0
10466         local end_time=$((SECONDS + timeout))
10467
10468         while [ $SECONDS -le $end_time ] ; do
10469                 echo -n "."
10470                 # Get ost i/o thread_started count.
10471                 thread_started=$(do_facet ost1 \
10472                         "$LCTL get_param \
10473                         ost.OSS.ost_io.threads_started | cut -d= -f2")
10474                 # Break out if thread_started is equal/greater than thread_max
10475                 if [[ $thread_started -ge $thread_max ]]; then
10476                         echo ll_ost_io thread_started $thread_started, \
10477                                 equal/greater than thread_max $thread_max
10478                         break
10479                 fi
10480                 sleep 1
10481         done
10482
10483         # Cleanup - We have the numbers, Kill i/o jobs if running.
10484         jobcount=($(jobs -p))
10485         for i in $(seq 0 $((${#jobcount[@]}-1)))
10486         do
10487                 kill -9 ${jobcount[$i]}
10488                 if [ $? -ne 0 ] ; then
10489                         echo Warning: \
10490                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
10491                 fi
10492         done
10493
10494         # Cleanup files left by WTL binary.
10495         for i in $(seq $nfiles); do
10496                 local file=$DIR/$tdir/${tfile}-$i
10497                 rm -rf $file
10498                 if [ $? -ne 0 ] ; then
10499                         echo "Warning: Failed to delete file $file"
10500                 fi
10501         done
10502
10503         restore_lustre_params <$save_params
10504         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
10505
10506         # Error out if no new thread has started or Thread started is greater
10507         # than thread max.
10508         if [[ $thread_started -le $OSTIO_pre ||
10509                         $thread_started -gt $thread_max ]]; then
10510                 error "ll_ost_io: thread_started $thread_started" \
10511                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
10512                       "No new thread started or thread started greater " \
10513                       "than thread_max."
10514         fi
10515 }
10516 run_test 115 "verify dynamic thread creation===================="
10517
10518 free_min_max () {
10519         wait_delete_completed
10520         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
10521         echo "OST kbytes available: ${AVAIL[@]}"
10522         MAXV=${AVAIL[0]}
10523         MAXI=0
10524         MINV=${AVAIL[0]}
10525         MINI=0
10526         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
10527                 #echo OST $i: ${AVAIL[i]}kb
10528                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
10529                         MAXV=${AVAIL[i]}
10530                         MAXI=$i
10531                 fi
10532                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
10533                         MINV=${AVAIL[i]}
10534                         MINI=$i
10535                 fi
10536         done
10537         echo "Min free space: OST $MINI: $MINV"
10538         echo "Max free space: OST $MAXI: $MAXV"
10539 }
10540
10541 test_116a() { # was previously test_116()
10542         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10543         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10544         remote_mds_nodsh && skip "remote MDS with nodsh"
10545
10546         echo -n "Free space priority "
10547         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
10548                 head -n1
10549         declare -a AVAIL
10550         free_min_max
10551
10552         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
10553         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
10554         trap simple_cleanup_common EXIT
10555
10556         # Check if we need to generate uneven OSTs
10557         test_mkdir -p $DIR/$tdir/OST${MINI}
10558         local FILL=$((MINV / 4))
10559         local DIFF=$((MAXV - MINV))
10560         local DIFF2=$((DIFF * 100 / MINV))
10561
10562         local threshold=$(do_facet $SINGLEMDS \
10563                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
10564         threshold=${threshold%%%}
10565         echo -n "Check for uneven OSTs: "
10566         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
10567
10568         if [[ $DIFF2 -gt $threshold ]]; then
10569                 echo "ok"
10570                 echo "Don't need to fill OST$MINI"
10571         else
10572                 # generate uneven OSTs. Write 2% over the QOS threshold value
10573                 echo "no"
10574                 DIFF=$((threshold - DIFF2 + 2))
10575                 DIFF2=$((MINV * DIFF / 100))
10576                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
10577                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
10578                         error "setstripe failed"
10579                 DIFF=$((DIFF2 / 2048))
10580                 i=0
10581                 while [ $i -lt $DIFF ]; do
10582                         i=$((i + 1))
10583                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
10584                                 bs=2M count=1 2>/dev/null
10585                         echo -n .
10586                 done
10587                 echo .
10588                 sync
10589                 sleep_maxage
10590                 free_min_max
10591         fi
10592
10593         DIFF=$((MAXV - MINV))
10594         DIFF2=$((DIFF * 100 / MINV))
10595         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
10596         if [ $DIFF2 -gt $threshold ]; then
10597                 echo "ok"
10598         else
10599                 echo "failed - QOS mode won't be used"
10600                 simple_cleanup_common
10601                 skip "QOS imbalance criteria not met"
10602         fi
10603
10604         MINI1=$MINI
10605         MINV1=$MINV
10606         MAXI1=$MAXI
10607         MAXV1=$MAXV
10608
10609         # now fill using QOS
10610         $LFS setstripe -c 1 $DIR/$tdir
10611         FILL=$((FILL / 200))
10612         if [ $FILL -gt 600 ]; then
10613                 FILL=600
10614         fi
10615         echo "writing $FILL files to QOS-assigned OSTs"
10616         i=0
10617         while [ $i -lt $FILL ]; do
10618                 i=$((i + 1))
10619                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
10620                         count=1 2>/dev/null
10621                 echo -n .
10622         done
10623         echo "wrote $i 200k files"
10624         sync
10625         sleep_maxage
10626
10627         echo "Note: free space may not be updated, so measurements might be off"
10628         free_min_max
10629         DIFF2=$((MAXV - MINV))
10630         echo "free space delta: orig $DIFF final $DIFF2"
10631         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
10632         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
10633         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
10634         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
10635         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
10636         if [[ $DIFF -gt 0 ]]; then
10637                 FILL=$((DIFF2 * 100 / DIFF - 100))
10638                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
10639         fi
10640
10641         # Figure out which files were written where
10642         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10643                awk '/'$MINI1': / {print $2; exit}')
10644         echo $UUID
10645         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10646         echo "$MINC files created on smaller OST $MINI1"
10647         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10648                awk '/'$MAXI1': / {print $2; exit}')
10649         echo $UUID
10650         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10651         echo "$MAXC files created on larger OST $MAXI1"
10652         if [[ $MINC -gt 0 ]]; then
10653                 FILL=$((MAXC * 100 / MINC - 100))
10654                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
10655         fi
10656         [[ $MAXC -gt $MINC ]] ||
10657                 error_ignore LU-9 "stripe QOS didn't balance free space"
10658         simple_cleanup_common
10659 }
10660 run_test 116a "stripe QOS: free space balance ==================="
10661
10662 test_116b() { # LU-2093
10663         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10664         remote_mds_nodsh && skip "remote MDS with nodsh"
10665
10666 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
10667         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
10668                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
10669         [ -z "$old_rr" ] && skip "no QOS"
10670         do_facet $SINGLEMDS lctl set_param \
10671                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
10672         mkdir -p $DIR/$tdir
10673         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
10674         createmany -o $DIR/$tdir/f- 20 || error "can't create"
10675         do_facet $SINGLEMDS lctl set_param fail_loc=0
10676         rm -rf $DIR/$tdir
10677         do_facet $SINGLEMDS lctl set_param \
10678                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
10679 }
10680 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
10681
10682 test_117() # bug 10891
10683 {
10684         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10685
10686         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
10687         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
10688         lctl set_param fail_loc=0x21e
10689         > $DIR/$tfile || error "truncate failed"
10690         lctl set_param fail_loc=0
10691         echo "Truncate succeeded."
10692         rm -f $DIR/$tfile
10693 }
10694 run_test 117 "verify osd extend =========="
10695
10696 NO_SLOW_RESENDCOUNT=4
10697 export OLD_RESENDCOUNT=""
10698 set_resend_count () {
10699         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
10700         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
10701         lctl set_param -n $PROC_RESENDCOUNT $1
10702         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
10703 }
10704
10705 # for reduce test_118* time (b=14842)
10706 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
10707
10708 # Reset async IO behavior after error case
10709 reset_async() {
10710         FILE=$DIR/reset_async
10711
10712         # Ensure all OSCs are cleared
10713         $LFS setstripe -c -1 $FILE
10714         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
10715         sync
10716         rm $FILE
10717 }
10718
10719 test_118a() #bug 11710
10720 {
10721         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10722
10723         reset_async
10724
10725         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10726         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10727         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10728
10729         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10730                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10731                 return 1;
10732         fi
10733         rm -f $DIR/$tfile
10734 }
10735 run_test 118a "verify O_SYNC works =========="
10736
10737 test_118b()
10738 {
10739         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10740         remote_ost_nodsh && skip "remote OST with nodsh"
10741
10742         reset_async
10743
10744         #define OBD_FAIL_SRV_ENOENT 0x217
10745         set_nodes_failloc "$(osts_nodes)" 0x217
10746         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10747         RC=$?
10748         set_nodes_failloc "$(osts_nodes)" 0
10749         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10750         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10751                     grep -c writeback)
10752
10753         if [[ $RC -eq 0 ]]; then
10754                 error "Must return error due to dropped pages, rc=$RC"
10755                 return 1;
10756         fi
10757
10758         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10759                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10760                 return 1;
10761         fi
10762
10763         echo "Dirty pages not leaked on ENOENT"
10764
10765         # Due to the above error the OSC will issue all RPCs syncronously
10766         # until a subsequent RPC completes successfully without error.
10767         $MULTIOP $DIR/$tfile Ow4096yc
10768         rm -f $DIR/$tfile
10769
10770         return 0
10771 }
10772 run_test 118b "Reclaim dirty pages on fatal error =========="
10773
10774 test_118c()
10775 {
10776         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10777
10778         # for 118c, restore the original resend count, LU-1940
10779         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
10780                                 set_resend_count $OLD_RESENDCOUNT
10781         remote_ost_nodsh && skip "remote OST with nodsh"
10782
10783         reset_async
10784
10785         #define OBD_FAIL_OST_EROFS               0x216
10786         set_nodes_failloc "$(osts_nodes)" 0x216
10787
10788         # multiop should block due to fsync until pages are written
10789         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10790         MULTIPID=$!
10791         sleep 1
10792
10793         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
10794                 error "Multiop failed to block on fsync, pid=$MULTIPID"
10795         fi
10796
10797         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10798                     grep -c writeback)
10799         if [[ $WRITEBACK -eq 0 ]]; then
10800                 error "No page in writeback, writeback=$WRITEBACK"
10801         fi
10802
10803         set_nodes_failloc "$(osts_nodes)" 0
10804         wait $MULTIPID
10805         RC=$?
10806         if [[ $RC -ne 0 ]]; then
10807                 error "Multiop fsync failed, rc=$RC"
10808         fi
10809
10810         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10811         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10812                     grep -c writeback)
10813         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10814                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10815         fi
10816
10817         rm -f $DIR/$tfile
10818         echo "Dirty pages flushed via fsync on EROFS"
10819         return 0
10820 }
10821 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
10822
10823 # continue to use small resend count to reduce test_118* time (b=14842)
10824 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
10825
10826 test_118d()
10827 {
10828         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10829         remote_ost_nodsh && skip "remote OST with nodsh"
10830
10831         reset_async
10832
10833         #define OBD_FAIL_OST_BRW_PAUSE_BULK
10834         set_nodes_failloc "$(osts_nodes)" 0x214
10835         # multiop should block due to fsync until pages are written
10836         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10837         MULTIPID=$!
10838         sleep 1
10839
10840         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
10841                 error "Multiop failed to block on fsync, pid=$MULTIPID"
10842         fi
10843
10844         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10845                     grep -c writeback)
10846         if [[ $WRITEBACK -eq 0 ]]; then
10847                 error "No page in writeback, writeback=$WRITEBACK"
10848         fi
10849
10850         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
10851         set_nodes_failloc "$(osts_nodes)" 0
10852
10853         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10854         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10855                     grep -c writeback)
10856         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10857                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10858         fi
10859
10860         rm -f $DIR/$tfile
10861         echo "Dirty pages gaurenteed flushed via fsync"
10862         return 0
10863 }
10864 run_test 118d "Fsync validation inject a delay of the bulk =========="
10865
10866 test_118f() {
10867         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10868
10869         reset_async
10870
10871         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
10872         lctl set_param fail_loc=0x8000040a
10873
10874         # Should simulate EINVAL error which is fatal
10875         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10876         RC=$?
10877         if [[ $RC -eq 0 ]]; then
10878                 error "Must return error due to dropped pages, rc=$RC"
10879         fi
10880
10881         lctl set_param fail_loc=0x0
10882
10883         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10884         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10885         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10886                     grep -c writeback)
10887         if [[ $LOCKED -ne 0 ]]; then
10888                 error "Locked pages remain in cache, locked=$LOCKED"
10889         fi
10890
10891         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10892                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10893         fi
10894
10895         rm -f $DIR/$tfile
10896         echo "No pages locked after fsync"
10897
10898         reset_async
10899         return 0
10900 }
10901 run_test 118f "Simulate unrecoverable OSC side error =========="
10902
10903 test_118g() {
10904         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10905
10906         reset_async
10907
10908         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
10909         lctl set_param fail_loc=0x406
10910
10911         # simulate local -ENOMEM
10912         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10913         RC=$?
10914
10915         lctl set_param fail_loc=0
10916         if [[ $RC -eq 0 ]]; then
10917                 error "Must return error due to dropped pages, rc=$RC"
10918         fi
10919
10920         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10921         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10922         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10923                         grep -c writeback)
10924         if [[ $LOCKED -ne 0 ]]; then
10925                 error "Locked pages remain in cache, locked=$LOCKED"
10926         fi
10927
10928         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10929                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10930         fi
10931
10932         rm -f $DIR/$tfile
10933         echo "No pages locked after fsync"
10934
10935         reset_async
10936         return 0
10937 }
10938 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
10939
10940 test_118h() {
10941         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10942         remote_ost_nodsh && skip "remote OST with nodsh"
10943
10944         reset_async
10945
10946         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
10947         set_nodes_failloc "$(osts_nodes)" 0x20e
10948         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
10949         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10950         RC=$?
10951
10952         set_nodes_failloc "$(osts_nodes)" 0
10953         if [[ $RC -eq 0 ]]; then
10954                 error "Must return error due to dropped pages, rc=$RC"
10955         fi
10956
10957         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10958         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10959         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10960                     grep -c writeback)
10961         if [[ $LOCKED -ne 0 ]]; then
10962                 error "Locked pages remain in cache, locked=$LOCKED"
10963         fi
10964
10965         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10966                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10967         fi
10968
10969         rm -f $DIR/$tfile
10970         echo "No pages locked after fsync"
10971
10972         return 0
10973 }
10974 run_test 118h "Verify timeout in handling recoverables errors  =========="
10975
10976 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
10977
10978 test_118i() {
10979         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10980         remote_ost_nodsh && skip "remote OST with nodsh"
10981
10982         reset_async
10983
10984         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
10985         set_nodes_failloc "$(osts_nodes)" 0x20e
10986
10987         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
10988         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10989         PID=$!
10990         sleep 5
10991         set_nodes_failloc "$(osts_nodes)" 0
10992
10993         wait $PID
10994         RC=$?
10995         if [[ $RC -ne 0 ]]; then
10996                 error "got error, but should be not, rc=$RC"
10997         fi
10998
10999         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11000         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11001         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11002         if [[ $LOCKED -ne 0 ]]; then
11003                 error "Locked pages remain in cache, locked=$LOCKED"
11004         fi
11005
11006         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11007                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11008         fi
11009
11010         rm -f $DIR/$tfile
11011         echo "No pages locked after fsync"
11012
11013         return 0
11014 }
11015 run_test 118i "Fix error before timeout in recoverable error  =========="
11016
11017 [ "$SLOW" = "no" ] && set_resend_count 4
11018
11019 test_118j() {
11020         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11021         remote_ost_nodsh && skip "remote OST with nodsh"
11022
11023         reset_async
11024
11025         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
11026         set_nodes_failloc "$(osts_nodes)" 0x220
11027
11028         # return -EIO from OST
11029         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11030         RC=$?
11031         set_nodes_failloc "$(osts_nodes)" 0x0
11032         if [[ $RC -eq 0 ]]; then
11033                 error "Must return error due to dropped pages, rc=$RC"
11034         fi
11035
11036         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11037         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11038         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11039         if [[ $LOCKED -ne 0 ]]; then
11040                 error "Locked pages remain in cache, locked=$LOCKED"
11041         fi
11042
11043         # in recoverable error on OST we want resend and stay until it finished
11044         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11045                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11046         fi
11047
11048         rm -f $DIR/$tfile
11049         echo "No pages locked after fsync"
11050
11051         return 0
11052 }
11053 run_test 118j "Simulate unrecoverable OST side error =========="
11054
11055 test_118k()
11056 {
11057         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11058         remote_ost_nodsh && skip "remote OSTs with nodsh"
11059
11060         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11061         set_nodes_failloc "$(osts_nodes)" 0x20e
11062         test_mkdir $DIR/$tdir
11063
11064         for ((i=0;i<10;i++)); do
11065                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
11066                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
11067                 SLEEPPID=$!
11068                 sleep 0.500s
11069                 kill $SLEEPPID
11070                 wait $SLEEPPID
11071         done
11072
11073         set_nodes_failloc "$(osts_nodes)" 0
11074         rm -rf $DIR/$tdir
11075 }
11076 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
11077
11078 test_118l() # LU-646
11079 {
11080         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11081
11082         test_mkdir $DIR/$tdir
11083         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
11084         rm -rf $DIR/$tdir
11085 }
11086 run_test 118l "fsync dir"
11087
11088 test_118m() # LU-3066
11089 {
11090         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11091
11092         test_mkdir $DIR/$tdir
11093         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
11094         rm -rf $DIR/$tdir
11095 }
11096 run_test 118m "fdatasync dir ========="
11097
11098 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11099
11100 test_118n()
11101 {
11102         local begin
11103         local end
11104
11105         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11106         remote_ost_nodsh && skip "remote OSTs with nodsh"
11107
11108         # Sleep to avoid a cached response.
11109         #define OBD_STATFS_CACHE_SECONDS 1
11110         sleep 2
11111
11112         # Inject a 10 second delay in the OST_STATFS handler.
11113         #define OBD_FAIL_OST_STATFS_DELAY 0x242
11114         set_nodes_failloc "$(osts_nodes)" 0x242
11115
11116         begin=$SECONDS
11117         stat --file-system $MOUNT > /dev/null
11118         end=$SECONDS
11119
11120         set_nodes_failloc "$(osts_nodes)" 0
11121
11122         if ((end - begin > 20)); then
11123             error "statfs took $((end - begin)) seconds, expected 10"
11124         fi
11125 }
11126 run_test 118n "statfs() sends OST_STATFS requests in parallel"
11127
11128 test_119a() # bug 11737
11129 {
11130         BSIZE=$((512 * 1024))
11131         directio write $DIR/$tfile 0 1 $BSIZE
11132         # We ask to read two blocks, which is more than a file size.
11133         # directio will indicate an error when requested and actual
11134         # sizes aren't equeal (a normal situation in this case) and
11135         # print actual read amount.
11136         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
11137         if [ "$NOB" != "$BSIZE" ]; then
11138                 error "read $NOB bytes instead of $BSIZE"
11139         fi
11140         rm -f $DIR/$tfile
11141 }
11142 run_test 119a "Short directIO read must return actual read amount"
11143
11144 test_119b() # bug 11737
11145 {
11146         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11147
11148         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
11149         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
11150         sync
11151         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
11152                 error "direct read failed"
11153         rm -f $DIR/$tfile
11154 }
11155 run_test 119b "Sparse directIO read must return actual read amount"
11156
11157 test_119c() # bug 13099
11158 {
11159         BSIZE=1048576
11160         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
11161         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
11162         rm -f $DIR/$tfile
11163 }
11164 run_test 119c "Testing for direct read hitting hole"
11165
11166 test_119d() # bug 15950
11167 {
11168         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11169
11170         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
11171         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
11172         BSIZE=1048576
11173         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
11174         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
11175         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
11176         lctl set_param fail_loc=0x40d
11177         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
11178         pid_dio=$!
11179         sleep 1
11180         cat $DIR/$tfile > /dev/null &
11181         lctl set_param fail_loc=0
11182         pid_reads=$!
11183         wait $pid_dio
11184         log "the DIO writes have completed, now wait for the reads (should not block very long)"
11185         sleep 2
11186         [ -n "`ps h -p $pid_reads -o comm`" ] && \
11187         error "the read rpcs have not completed in 2s"
11188         rm -f $DIR/$tfile
11189         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
11190 }
11191 run_test 119d "The DIO path should try to send a new rpc once one is completed"
11192
11193 test_120a() {
11194         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11195         remote_mds_nodsh && skip "remote MDS with nodsh"
11196         test_mkdir -i0 -c1 $DIR/$tdir
11197         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11198                 skip_env "no early lock cancel on server"
11199
11200         lru_resize_disable mdc
11201         lru_resize_disable osc
11202         cancel_lru_locks mdc
11203         # asynchronous object destroy at MDT could cause bl ast to client
11204         cancel_lru_locks osc
11205
11206         stat $DIR/$tdir > /dev/null
11207         can1=$(do_facet mds1 \
11208                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11209                awk '/ldlm_cancel/ {print $2}')
11210         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11211                awk '/ldlm_bl_callback/ {print $2}')
11212         test_mkdir -i0 -c1 $DIR/$tdir/d1
11213         can2=$(do_facet mds1 \
11214                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11215                awk '/ldlm_cancel/ {print $2}')
11216         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11217                awk '/ldlm_bl_callback/ {print $2}')
11218         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11219         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11220         lru_resize_enable mdc
11221         lru_resize_enable osc
11222 }
11223 run_test 120a "Early Lock Cancel: mkdir test"
11224
11225 test_120b() {
11226         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11227         remote_mds_nodsh && skip "remote MDS with nodsh"
11228         test_mkdir $DIR/$tdir
11229         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11230                 skip_env "no early lock cancel on server"
11231
11232         lru_resize_disable mdc
11233         lru_resize_disable osc
11234         cancel_lru_locks mdc
11235         stat $DIR/$tdir > /dev/null
11236         can1=$(do_facet $SINGLEMDS \
11237                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11238                awk '/ldlm_cancel/ {print $2}')
11239         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11240                awk '/ldlm_bl_callback/ {print $2}')
11241         touch $DIR/$tdir/f1
11242         can2=$(do_facet $SINGLEMDS \
11243                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11244                awk '/ldlm_cancel/ {print $2}')
11245         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11246                awk '/ldlm_bl_callback/ {print $2}')
11247         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11248         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11249         lru_resize_enable mdc
11250         lru_resize_enable osc
11251 }
11252 run_test 120b "Early Lock Cancel: create test"
11253
11254 test_120c() {
11255         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11256         remote_mds_nodsh && skip "remote MDS with nodsh"
11257         test_mkdir -i0 -c1 $DIR/$tdir
11258         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11259                 skip "no early lock cancel on server"
11260
11261         lru_resize_disable mdc
11262         lru_resize_disable osc
11263         test_mkdir -i0 -c1 $DIR/$tdir/d1
11264         test_mkdir -i0 -c1 $DIR/$tdir/d2
11265         touch $DIR/$tdir/d1/f1
11266         cancel_lru_locks mdc
11267         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
11268         can1=$(do_facet mds1 \
11269                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11270                awk '/ldlm_cancel/ {print $2}')
11271         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11272                awk '/ldlm_bl_callback/ {print $2}')
11273         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11274         can2=$(do_facet mds1 \
11275                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11276                awk '/ldlm_cancel/ {print $2}')
11277         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11278                awk '/ldlm_bl_callback/ {print $2}')
11279         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11280         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11281         lru_resize_enable mdc
11282         lru_resize_enable osc
11283 }
11284 run_test 120c "Early Lock Cancel: link test"
11285
11286 test_120d() {
11287         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11288         remote_mds_nodsh && skip "remote MDS with nodsh"
11289         test_mkdir -i0 -c1 $DIR/$tdir
11290         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11291                 skip_env "no early lock cancel on server"
11292
11293         lru_resize_disable mdc
11294         lru_resize_disable osc
11295         touch $DIR/$tdir
11296         cancel_lru_locks mdc
11297         stat $DIR/$tdir > /dev/null
11298         can1=$(do_facet mds1 \
11299                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11300                awk '/ldlm_cancel/ {print $2}')
11301         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11302                awk '/ldlm_bl_callback/ {print $2}')
11303         chmod a+x $DIR/$tdir
11304         can2=$(do_facet mds1 \
11305                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11306                awk '/ldlm_cancel/ {print $2}')
11307         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11308                awk '/ldlm_bl_callback/ {print $2}')
11309         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11310         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11311         lru_resize_enable mdc
11312         lru_resize_enable osc
11313 }
11314 run_test 120d "Early Lock Cancel: setattr test"
11315
11316 test_120e() {
11317         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11318         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11319                 skip_env "no early lock cancel on server"
11320         remote_mds_nodsh && skip "remote MDS with nodsh"
11321
11322         local dlmtrace_set=false
11323
11324         test_mkdir -i0 -c1 $DIR/$tdir
11325         lru_resize_disable mdc
11326         lru_resize_disable osc
11327         ! $LCTL get_param debug | grep -q dlmtrace &&
11328                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
11329         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
11330         cancel_lru_locks mdc
11331         cancel_lru_locks osc
11332         dd if=$DIR/$tdir/f1 of=/dev/null
11333         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
11334         # XXX client can not do early lock cancel of OST lock
11335         # during unlink (LU-4206), so cancel osc lock now.
11336         sleep 2
11337         cancel_lru_locks osc
11338         can1=$(do_facet mds1 \
11339                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11340                awk '/ldlm_cancel/ {print $2}')
11341         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11342                awk '/ldlm_bl_callback/ {print $2}')
11343         unlink $DIR/$tdir/f1
11344         sleep 5
11345         can2=$(do_facet mds1 \
11346                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11347                awk '/ldlm_cancel/ {print $2}')
11348         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11349                awk '/ldlm_bl_callback/ {print $2}')
11350         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
11351                 $LCTL dk $TMP/cancel.debug.txt
11352         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
11353                 $LCTL dk $TMP/blocking.debug.txt
11354         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
11355         lru_resize_enable mdc
11356         lru_resize_enable osc
11357 }
11358 run_test 120e "Early Lock Cancel: unlink test"
11359
11360 test_120f() {
11361         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11362         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11363                 skip_env "no early lock cancel on server"
11364         remote_mds_nodsh && skip "remote MDS with nodsh"
11365
11366         test_mkdir -i0 -c1 $DIR/$tdir
11367         lru_resize_disable mdc
11368         lru_resize_disable osc
11369         test_mkdir -i0 -c1 $DIR/$tdir/d1
11370         test_mkdir -i0 -c1 $DIR/$tdir/d2
11371         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
11372         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
11373         cancel_lru_locks mdc
11374         cancel_lru_locks osc
11375         dd if=$DIR/$tdir/d1/f1 of=/dev/null
11376         dd if=$DIR/$tdir/d2/f2 of=/dev/null
11377         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
11378         # XXX client can not do early lock cancel of OST lock
11379         # during rename (LU-4206), so cancel osc lock now.
11380         sleep 2
11381         cancel_lru_locks osc
11382         can1=$(do_facet mds1 \
11383                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11384                awk '/ldlm_cancel/ {print $2}')
11385         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11386                awk '/ldlm_bl_callback/ {print $2}')
11387         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11388         sleep 5
11389         can2=$(do_facet mds1 \
11390                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11391                awk '/ldlm_cancel/ {print $2}')
11392         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11393                awk '/ldlm_bl_callback/ {print $2}')
11394         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11395         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11396         lru_resize_enable mdc
11397         lru_resize_enable osc
11398 }
11399 run_test 120f "Early Lock Cancel: rename test"
11400
11401 test_120g() {
11402         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11403         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11404                 skip_env "no early lock cancel on server"
11405         remote_mds_nodsh && skip "remote MDS with nodsh"
11406
11407         lru_resize_disable mdc
11408         lru_resize_disable osc
11409         count=10000
11410         echo create $count files
11411         test_mkdir $DIR/$tdir
11412         cancel_lru_locks mdc
11413         cancel_lru_locks osc
11414         t0=$(date +%s)
11415
11416         can0=$(do_facet $SINGLEMDS \
11417                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11418                awk '/ldlm_cancel/ {print $2}')
11419         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11420                awk '/ldlm_bl_callback/ {print $2}')
11421         createmany -o $DIR/$tdir/f $count
11422         sync
11423         can1=$(do_facet $SINGLEMDS \
11424                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11425                awk '/ldlm_cancel/ {print $2}')
11426         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11427                awk '/ldlm_bl_callback/ {print $2}')
11428         t1=$(date +%s)
11429         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
11430         echo rm $count files
11431         rm -r $DIR/$tdir
11432         sync
11433         can2=$(do_facet $SINGLEMDS \
11434                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11435                awk '/ldlm_cancel/ {print $2}')
11436         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11437                awk '/ldlm_bl_callback/ {print $2}')
11438         t2=$(date +%s)
11439         echo total: $count removes in $((t2-t1))
11440         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
11441         sleep 2
11442         # wait for commitment of removal
11443         lru_resize_enable mdc
11444         lru_resize_enable osc
11445 }
11446 run_test 120g "Early Lock Cancel: performance test"
11447
11448 test_121() { #bug #10589
11449         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11450
11451         rm -rf $DIR/$tfile
11452         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
11453 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
11454         lctl set_param fail_loc=0x310
11455         cancel_lru_locks osc > /dev/null
11456         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
11457         lctl set_param fail_loc=0
11458         [[ $reads -eq $writes ]] ||
11459                 error "read $reads blocks, must be $writes blocks"
11460 }
11461 run_test 121 "read cancel race ========="
11462
11463 test_123a_base() { # was test 123, statahead(bug 11401)
11464         local lsx="$1"
11465
11466         SLOWOK=0
11467         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
11468                 log "testing UP system. Performance may be lower than expected."
11469                 SLOWOK=1
11470         fi
11471
11472         rm -rf $DIR/$tdir
11473         test_mkdir $DIR/$tdir
11474         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
11475         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
11476         MULT=10
11477         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
11478                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
11479
11480                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
11481                 lctl set_param -n llite.*.statahead_max 0
11482                 lctl get_param llite.*.statahead_max
11483                 cancel_lru_locks mdc
11484                 cancel_lru_locks osc
11485                 stime=$(date +%s)
11486                 time $lsx $DIR/$tdir | wc -l
11487                 etime=$(date +%s)
11488                 delta=$((etime - stime))
11489                 log "$lsx $i files without statahead: $delta sec"
11490                 lctl set_param llite.*.statahead_max=$max
11491
11492                 swrong=$(lctl get_param -n llite.*.statahead_stats |
11493                         grep "statahead wrong:" | awk '{print $3}')
11494                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
11495                 cancel_lru_locks mdc
11496                 cancel_lru_locks osc
11497                 stime=$(date +%s)
11498                 time $lsx $DIR/$tdir | wc -l
11499                 etime=$(date +%s)
11500                 delta_sa=$((etime - stime))
11501                 log "$lsx $i files with statahead: $delta_sa sec"
11502                 lctl get_param -n llite.*.statahead_stats
11503                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
11504                         grep "statahead wrong:" | awk '{print $3}')
11505
11506                 [[ $swrong -lt $ewrong ]] &&
11507                         log "statahead was stopped, maybe too many locks held!"
11508                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
11509
11510                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
11511                         max=$(lctl get_param -n llite.*.statahead_max |
11512                                 head -n 1)
11513                         lctl set_param -n llite.*.statahead_max 0
11514                         lctl get_param llite.*.statahead_max
11515                         cancel_lru_locks mdc
11516                         cancel_lru_locks osc
11517                         stime=$(date +%s)
11518                         time $lsx $DIR/$tdir | wc -l
11519                         etime=$(date +%s)
11520                         delta=$((etime - stime))
11521                         log "$lsx $i files again without statahead: $delta sec"
11522                         lctl set_param llite.*.statahead_max=$max
11523                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
11524                                 if [  $SLOWOK -eq 0 ]; then
11525                                         error "$lsx $i files is slower with statahead!"
11526                                 else
11527                                         log "$lsx $i files is slower with statahead!"
11528                                 fi
11529                                 break
11530                         fi
11531                 fi
11532
11533                 [ $delta -gt 20 ] && break
11534                 [ $delta -gt 8 ] && MULT=$((50 / delta))
11535                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
11536         done
11537         log "$lsx done"
11538
11539         stime=$(date +%s)
11540         rm -r $DIR/$tdir
11541         sync
11542         etime=$(date +%s)
11543         delta=$((etime - stime))
11544         log "rm -r $DIR/$tdir/: $delta seconds"
11545         log "rm done"
11546         lctl get_param -n llite.*.statahead_stats
11547 }
11548
11549 test_123aa() {
11550         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11551
11552         test_123a_base "ls -l"
11553 }
11554 run_test 123aa "verify statahead work"
11555
11556 test_123ab() {
11557         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11558
11559         statx_supported || skip_env "Test must be statx() syscall supported"
11560
11561         test_123a_base "$STATX -l"
11562 }
11563 run_test 123ab "verify statahead work by using statx"
11564
11565 test_123ac() {
11566         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11567
11568         statx_supported || skip_env "Test must be statx() syscall supported"
11569
11570         local rpcs_before
11571         local rpcs_after
11572         local agl_before
11573         local agl_after
11574
11575         cancel_lru_locks $OSC
11576         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
11577         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
11578                 awk '/agl.total:/ {print $3}')
11579         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
11580         test_123a_base "$STATX --cached=always -D"
11581         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
11582                 awk '/agl.total:/ {print $3}')
11583         [ $agl_before -eq $agl_after ] ||
11584                 error "Should not trigger AGL thread - $agl_before:$agl_after"
11585         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
11586         [ $rpcs_after -eq $rpcs_before ] ||
11587                 error "$STATX should not send glimpse RPCs to $OSC"
11588 }
11589 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
11590
11591 test_123b () { # statahead(bug 15027)
11592         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11593
11594         test_mkdir $DIR/$tdir
11595         createmany -o $DIR/$tdir/$tfile-%d 1000
11596
11597         cancel_lru_locks mdc
11598         cancel_lru_locks osc
11599
11600 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
11601         lctl set_param fail_loc=0x80000803
11602         ls -lR $DIR/$tdir > /dev/null
11603         log "ls done"
11604         lctl set_param fail_loc=0x0
11605         lctl get_param -n llite.*.statahead_stats
11606         rm -r $DIR/$tdir
11607         sync
11608
11609 }
11610 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
11611
11612 test_123c() {
11613         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
11614
11615         test_mkdir -i 0 -c 1 $DIR/$tdir.0
11616         test_mkdir -i 1 -c 1 $DIR/$tdir.1
11617         touch $DIR/$tdir.1/{1..3}
11618         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
11619
11620         remount_client $MOUNT
11621
11622         $MULTIOP $DIR/$tdir.0 Q
11623
11624         # let statahead to complete
11625         ls -l $DIR/$tdir.0 > /dev/null
11626
11627         testid=$(echo $TESTNAME | tr '_' ' ')
11628         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
11629                 error "statahead warning" || true
11630 }
11631 run_test 123c "Can not initialize inode warning on DNE statahead"
11632
11633 test_124a() {
11634         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11635         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11636                 skip_env "no lru resize on server"
11637
11638         local NR=2000
11639
11640         test_mkdir $DIR/$tdir
11641
11642         log "create $NR files at $DIR/$tdir"
11643         createmany -o $DIR/$tdir/f $NR ||
11644                 error "failed to create $NR files in $DIR/$tdir"
11645
11646         cancel_lru_locks mdc
11647         ls -l $DIR/$tdir > /dev/null
11648
11649         local NSDIR=""
11650         local LRU_SIZE=0
11651         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
11652                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
11653                 LRU_SIZE=$($LCTL get_param -n $PARAM)
11654                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
11655                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
11656                         log "NSDIR=$NSDIR"
11657                         log "NS=$(basename $NSDIR)"
11658                         break
11659                 fi
11660         done
11661
11662         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
11663                 skip "Not enough cached locks created!"
11664         fi
11665         log "LRU=$LRU_SIZE"
11666
11667         local SLEEP=30
11668
11669         # We know that lru resize allows one client to hold $LIMIT locks
11670         # for 10h. After that locks begin to be killed by client.
11671         local MAX_HRS=10
11672         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
11673         log "LIMIT=$LIMIT"
11674         if [ $LIMIT -lt $LRU_SIZE ]; then
11675                 skip "Limit is too small $LIMIT"
11676         fi
11677
11678         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
11679         # killing locks. Some time was spent for creating locks. This means
11680         # that up to the moment of sleep finish we must have killed some of
11681         # them (10-100 locks). This depends on how fast ther were created.
11682         # Many of them were touched in almost the same moment and thus will
11683         # be killed in groups.
11684         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE))
11685
11686         # Use $LRU_SIZE_B here to take into account real number of locks
11687         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
11688         local LRU_SIZE_B=$LRU_SIZE
11689         log "LVF=$LVF"
11690         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
11691         log "OLD_LVF=$OLD_LVF"
11692         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
11693
11694         # Let's make sure that we really have some margin. Client checks
11695         # cached locks every 10 sec.
11696         SLEEP=$((SLEEP+20))
11697         log "Sleep ${SLEEP} sec"
11698         local SEC=0
11699         while ((SEC<$SLEEP)); do
11700                 echo -n "..."
11701                 sleep 5
11702                 SEC=$((SEC+5))
11703                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
11704                 echo -n "$LRU_SIZE"
11705         done
11706         echo ""
11707         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
11708         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
11709
11710         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
11711                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
11712                 unlinkmany $DIR/$tdir/f $NR
11713                 return
11714         }
11715
11716         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
11717         log "unlink $NR files at $DIR/$tdir"
11718         unlinkmany $DIR/$tdir/f $NR
11719 }
11720 run_test 124a "lru resize ======================================="
11721
11722 get_max_pool_limit()
11723 {
11724         local limit=$($LCTL get_param \
11725                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
11726         local max=0
11727         for l in $limit; do
11728                 if [[ $l -gt $max ]]; then
11729                         max=$l
11730                 fi
11731         done
11732         echo $max
11733 }
11734
11735 test_124b() {
11736         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11737         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11738                 skip_env "no lru resize on server"
11739
11740         LIMIT=$(get_max_pool_limit)
11741
11742         NR=$(($(default_lru_size)*20))
11743         if [[ $NR -gt $LIMIT ]]; then
11744                 log "Limit lock number by $LIMIT locks"
11745                 NR=$LIMIT
11746         fi
11747
11748         IFree=$(mdsrate_inodes_available)
11749         if [ $IFree -lt $NR ]; then
11750                 log "Limit lock number by $IFree inodes"
11751                 NR=$IFree
11752         fi
11753
11754         lru_resize_disable mdc
11755         test_mkdir -p $DIR/$tdir/disable_lru_resize
11756
11757         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
11758         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
11759         cancel_lru_locks mdc
11760         stime=`date +%s`
11761         PID=""
11762         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11763         PID="$PID $!"
11764         sleep 2
11765         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11766         PID="$PID $!"
11767         sleep 2
11768         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11769         PID="$PID $!"
11770         wait $PID
11771         etime=`date +%s`
11772         nolruresize_delta=$((etime-stime))
11773         log "ls -la time: $nolruresize_delta seconds"
11774         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
11775         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
11776
11777         lru_resize_enable mdc
11778         test_mkdir -p $DIR/$tdir/enable_lru_resize
11779
11780         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
11781         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
11782         cancel_lru_locks mdc
11783         stime=`date +%s`
11784         PID=""
11785         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11786         PID="$PID $!"
11787         sleep 2
11788         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11789         PID="$PID $!"
11790         sleep 2
11791         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11792         PID="$PID $!"
11793         wait $PID
11794         etime=`date +%s`
11795         lruresize_delta=$((etime-stime))
11796         log "ls -la time: $lruresize_delta seconds"
11797         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
11798
11799         if [ $lruresize_delta -gt $nolruresize_delta ]; then
11800                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
11801         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
11802                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
11803         else
11804                 log "lru resize performs the same with no lru resize"
11805         fi
11806         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
11807 }
11808 run_test 124b "lru resize (performance test) ======================="
11809
11810 test_124c() {
11811         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11812         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11813                 skip_env "no lru resize on server"
11814
11815         # cache ununsed locks on client
11816         local nr=100
11817         cancel_lru_locks mdc
11818         test_mkdir $DIR/$tdir
11819         createmany -o $DIR/$tdir/f $nr ||
11820                 error "failed to create $nr files in $DIR/$tdir"
11821         ls -l $DIR/$tdir > /dev/null
11822
11823         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
11824         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11825         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
11826         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
11827         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
11828
11829         # set lru_max_age to 1 sec
11830         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
11831         echo "sleep $((recalc_p * 2)) seconds..."
11832         sleep $((recalc_p * 2))
11833
11834         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
11835         # restore lru_max_age
11836         $LCTL set_param -n $nsdir.lru_max_age $max_age
11837         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
11838         unlinkmany $DIR/$tdir/f $nr
11839 }
11840 run_test 124c "LRUR cancel very aged locks"
11841
11842 test_124d() {
11843         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11844         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11845                 skip_env "no lru resize on server"
11846
11847         # cache ununsed locks on client
11848         local nr=100
11849
11850         lru_resize_disable mdc
11851         stack_trap "lru_resize_enable mdc" EXIT
11852
11853         cancel_lru_locks mdc
11854
11855         # asynchronous object destroy at MDT could cause bl ast to client
11856         test_mkdir $DIR/$tdir
11857         createmany -o $DIR/$tdir/f $nr ||
11858                 error "failed to create $nr files in $DIR/$tdir"
11859         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
11860
11861         ls -l $DIR/$tdir > /dev/null
11862
11863         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
11864         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11865         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
11866         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
11867
11868         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
11869
11870         # set lru_max_age to 1 sec
11871         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
11872         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
11873
11874         echo "sleep $((recalc_p * 2)) seconds..."
11875         sleep $((recalc_p * 2))
11876
11877         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
11878
11879         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
11880 }
11881 run_test 124d "cancel very aged locks if lru-resize diasbaled"
11882
11883 test_125() { # 13358
11884         $LCTL get_param -n llite.*.client_type | grep -q local ||
11885                 skip "must run as local client"
11886         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
11887                 skip_env "must have acl enabled"
11888         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
11889
11890         test_mkdir $DIR/$tdir
11891         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
11892         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
11893         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
11894 }
11895 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
11896
11897 test_126() { # bug 12829/13455
11898         $GSS && skip_env "must run as gss disabled"
11899         $LCTL get_param -n llite.*.client_type | grep -q local ||
11900                 skip "must run as local client"
11901         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
11902
11903         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
11904         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
11905         rm -f $DIR/$tfile
11906         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
11907 }
11908 run_test 126 "check that the fsgid provided by the client is taken into account"
11909
11910 test_127a() { # bug 15521
11911         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11912         local name count samp unit min max sum sumsq
11913
11914         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
11915         echo "stats before reset"
11916         $LCTL get_param osc.*.stats
11917         $LCTL set_param osc.*.stats=0
11918         local fsize=$((2048 * 1024))
11919
11920         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
11921         cancel_lru_locks osc
11922         dd if=$DIR/$tfile of=/dev/null bs=$fsize
11923
11924         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
11925         stack_trap "rm -f $TMP/$tfile.tmp"
11926         while read name count samp unit min max sum sumsq; do
11927                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
11928                 [ ! $min ] && error "Missing min value for $name proc entry"
11929                 eval $name=$count || error "Wrong proc format"
11930
11931                 case $name in
11932                 read_bytes|write_bytes)
11933                         [[ "$unit" =~ "bytes" ]] ||
11934                                 error "unit is not 'bytes': $unit"
11935                         (( $min >= 4096 )) || error "min is too small: $min"
11936                         (( $min <= $fsize )) || error "min is too big: $min"
11937                         (( $max >= 4096 )) || error "max is too small: $max"
11938                         (( $max <= $fsize )) || error "max is too big: $max"
11939                         (( $sum == $fsize )) || error "sum is wrong: $sum"
11940                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
11941                                 error "sumsquare is too small: $sumsq"
11942                         (( $sumsq <= $fsize * $fsize )) ||
11943                                 error "sumsquare is too big: $sumsq"
11944                         ;;
11945                 ost_read|ost_write)
11946                         [[ "$unit" =~ "usec" ]] ||
11947                                 error "unit is not 'usec': $unit"
11948                         ;;
11949                 *)      ;;
11950                 esac
11951         done < $DIR/$tfile.tmp
11952
11953         #check that we actually got some stats
11954         [ "$read_bytes" ] || error "Missing read_bytes stats"
11955         [ "$write_bytes" ] || error "Missing write_bytes stats"
11956         [ "$read_bytes" != 0 ] || error "no read done"
11957         [ "$write_bytes" != 0 ] || error "no write done"
11958 }
11959 run_test 127a "verify the client stats are sane"
11960
11961 test_127b() { # bug LU-333
11962         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11963         local name count samp unit min max sum sumsq
11964
11965         echo "stats before reset"
11966         $LCTL get_param llite.*.stats
11967         $LCTL set_param llite.*.stats=0
11968
11969         # perform 2 reads and writes so MAX is different from SUM.
11970         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
11971         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
11972         cancel_lru_locks osc
11973         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
11974         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
11975
11976         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
11977         stack_trap "rm -f $TMP/$tfile.tmp"
11978         while read name count samp unit min max sum sumsq; do
11979                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
11980                 eval $name=$count || error "Wrong proc format"
11981
11982                 case $name in
11983                 read_bytes|write_bytes)
11984                         [[ "$unit" =~ "bytes" ]] ||
11985                                 error "unit is not 'bytes': $unit"
11986                         (( $count == 2 )) || error "count is not 2: $count"
11987                         (( $min == $PAGE_SIZE )) ||
11988                                 error "min is not $PAGE_SIZE: $min"
11989                         (( $max == $PAGE_SIZE )) ||
11990                                 error "max is not $PAGE_SIZE: $max"
11991                         (( $sum == $PAGE_SIZE * 2 )) ||
11992                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
11993                         ;;
11994                 read|write)
11995                         [[ "$unit" =~ "usec" ]] ||
11996                                 error "unit is not 'usec': $unit"
11997                         ;;
11998                 *)      ;;
11999                 esac
12000         done < $TMP/$tfile.tmp
12001
12002         #check that we actually got some stats
12003         [ "$read_bytes" ] || error "Missing read_bytes stats"
12004         [ "$write_bytes" ] || error "Missing write_bytes stats"
12005         [ "$read_bytes" != 0 ] || error "no read done"
12006         [ "$write_bytes" != 0 ] || error "no write done"
12007 }
12008 run_test 127b "verify the llite client stats are sane"
12009
12010 test_127c() { # LU-12394
12011         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12012         local size
12013         local bsize
12014         local reads
12015         local writes
12016         local count
12017
12018         $LCTL set_param llite.*.extents_stats=1
12019         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
12020
12021         # Use two stripes so there is enough space in default config
12022         $LFS setstripe -c 2 $DIR/$tfile
12023
12024         # Extent stats start at 0-4K and go in power of two buckets
12025         # LL_HIST_START = 12 --> 2^12 = 4K
12026         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
12027         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
12028         # small configs
12029         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
12030                 do
12031                 # Write and read, 2x each, second time at a non-zero offset
12032                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
12033                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
12034                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
12035                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
12036                 rm -f $DIR/$tfile
12037         done
12038
12039         $LCTL get_param llite.*.extents_stats
12040
12041         count=2
12042         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
12043                 do
12044                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
12045                                 grep -m 1 $bsize)
12046                 reads=$(echo $bucket | awk '{print $5}')
12047                 writes=$(echo $bucket | awk '{print $9}')
12048                 [ "$reads" -eq $count ] ||
12049                         error "$reads reads in < $bsize bucket, expect $count"
12050                 [ "$writes" -eq $count ] ||
12051                         error "$writes writes in < $bsize bucket, expect $count"
12052         done
12053
12054         # Test mmap write and read
12055         $LCTL set_param llite.*.extents_stats=c
12056         size=512
12057         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
12058         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
12059         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
12060
12061         $LCTL get_param llite.*.extents_stats
12062
12063         count=$(((size*1024) / PAGE_SIZE))
12064
12065         bsize=$((2 * PAGE_SIZE / 1024))K
12066
12067         bucket=$($LCTL get_param -n llite.*.extents_stats |
12068                         grep -m 1 $bsize)
12069         reads=$(echo $bucket | awk '{print $5}')
12070         writes=$(echo $bucket | awk '{print $9}')
12071         # mmap writes fault in the page first, creating an additonal read
12072         [ "$reads" -eq $((2 * count)) ] ||
12073                 error "$reads reads in < $bsize bucket, expect $count"
12074         [ "$writes" -eq $count ] ||
12075                 error "$writes writes in < $bsize bucket, expect $count"
12076 }
12077 run_test 127c "test llite extent stats with regular & mmap i/o"
12078
12079 test_128() { # bug 15212
12080         touch $DIR/$tfile
12081         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
12082                 find $DIR/$tfile
12083                 find $DIR/$tfile
12084         EOF
12085
12086         result=$(grep error $TMP/$tfile.log)
12087         rm -f $DIR/$tfile $TMP/$tfile.log
12088         [ -z "$result" ] ||
12089                 error "consecutive find's under interactive lfs failed"
12090 }
12091 run_test 128 "interactive lfs for 2 consecutive find's"
12092
12093 set_dir_limits () {
12094         local mntdev
12095         local canondev
12096         local node
12097
12098         local ldproc=/proc/fs/ldiskfs
12099         local facets=$(get_facets MDS)
12100
12101         for facet in ${facets//,/ }; do
12102                 canondev=$(ldiskfs_canon \
12103                            *.$(convert_facet2label $facet).mntdev $facet)
12104                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
12105                         ldproc=/sys/fs/ldiskfs
12106                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
12107                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
12108         done
12109 }
12110
12111 check_mds_dmesg() {
12112         local facets=$(get_facets MDS)
12113         for facet in ${facets//,/ }; do
12114                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
12115         done
12116         return 1
12117 }
12118
12119 test_129() {
12120         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12121         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
12122                 skip "Need MDS version with at least 2.5.56"
12123         if [ "$mds1_FSTYPE" != ldiskfs ]; then
12124                 skip_env "ldiskfs only test"
12125         fi
12126         remote_mds_nodsh && skip "remote MDS with nodsh"
12127
12128         local ENOSPC=28
12129         local has_warning=false
12130
12131         rm -rf $DIR/$tdir
12132         mkdir -p $DIR/$tdir
12133
12134         # block size of mds1
12135         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
12136         set_dir_limits $maxsize $((maxsize * 6 / 8))
12137         stack_trap "set_dir_limits 0 0"
12138         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
12139         local dirsize=$(stat -c%s "$DIR/$tdir")
12140         local nfiles=0
12141         while (( $dirsize <= $maxsize )); do
12142                 $MCREATE $DIR/$tdir/file_base_$nfiles
12143                 rc=$?
12144                 # check two errors:
12145                 # ENOSPC for ext4 max_dir_size, which has been used since
12146                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
12147                 if (( rc == ENOSPC )); then
12148                         set_dir_limits 0 0
12149                         echo "rc=$rc returned as expected after $nfiles files"
12150
12151                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
12152                                 error "create failed w/o dir size limit"
12153
12154                         # messages may be rate limited if test is run repeatedly
12155                         check_mds_dmesg '"is approaching max"' ||
12156                                 echo "warning message should be output"
12157                         check_mds_dmesg '"has reached max"' ||
12158                                 echo "reached message should be output"
12159
12160                         dirsize=$(stat -c%s "$DIR/$tdir")
12161
12162                         [[ $dirsize -ge $maxsize ]] && return 0
12163                         error "dirsize $dirsize < $maxsize after $nfiles files"
12164                 elif (( rc != 0 )); then
12165                         break
12166                 fi
12167                 nfiles=$((nfiles + 1))
12168                 dirsize=$(stat -c%s "$DIR/$tdir")
12169         done
12170
12171         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
12172 }
12173 run_test 129 "test directory size limit ========================"
12174
12175 OLDIFS="$IFS"
12176 cleanup_130() {
12177         trap 0
12178         IFS="$OLDIFS"
12179 }
12180
12181 test_130a() {
12182         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12183         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12184
12185         trap cleanup_130 EXIT RETURN
12186
12187         local fm_file=$DIR/$tfile
12188         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
12189         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
12190                 error "dd failed for $fm_file"
12191
12192         # LU-1795: test filefrag/FIEMAP once, even if unsupported
12193         filefrag -ves $fm_file
12194         RC=$?
12195         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12196                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12197         [ $RC != 0 ] && error "filefrag $fm_file failed"
12198
12199         filefrag_op=$(filefrag -ve -k $fm_file |
12200                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12201         lun=$($LFS getstripe -i $fm_file)
12202
12203         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
12204         IFS=$'\n'
12205         tot_len=0
12206         for line in $filefrag_op
12207         do
12208                 frag_lun=`echo $line | cut -d: -f5`
12209                 ext_len=`echo $line | cut -d: -f4`
12210                 if (( $frag_lun != $lun )); then
12211                         cleanup_130
12212                         error "FIEMAP on 1-stripe file($fm_file) failed"
12213                         return
12214                 fi
12215                 (( tot_len += ext_len ))
12216         done
12217
12218         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
12219                 cleanup_130
12220                 error "FIEMAP on 1-stripe file($fm_file) failed;"
12221                 return
12222         fi
12223
12224         cleanup_130
12225
12226         echo "FIEMAP on single striped file succeeded"
12227 }
12228 run_test 130a "FIEMAP (1-stripe file)"
12229
12230 test_130b() {
12231         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12232
12233         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12234         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12235
12236         trap cleanup_130 EXIT RETURN
12237
12238         local fm_file=$DIR/$tfile
12239         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12240                         error "setstripe on $fm_file"
12241         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12242                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12243
12244         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
12245                 error "dd failed on $fm_file"
12246
12247         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12248         filefrag_op=$(filefrag -ve -k $fm_file |
12249                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12250
12251         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12252                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12253
12254         IFS=$'\n'
12255         tot_len=0
12256         num_luns=1
12257         for line in $filefrag_op
12258         do
12259                 frag_lun=$(echo $line | cut -d: -f5 |
12260                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12261                 ext_len=$(echo $line | cut -d: -f4)
12262                 if (( $frag_lun != $last_lun )); then
12263                         if (( tot_len != 1024 )); then
12264                                 cleanup_130
12265                                 error "FIEMAP on $fm_file failed; returned " \
12266                                 "len $tot_len for OST $last_lun instead of 1024"
12267                                 return
12268                         else
12269                                 (( num_luns += 1 ))
12270                                 tot_len=0
12271                         fi
12272                 fi
12273                 (( tot_len += ext_len ))
12274                 last_lun=$frag_lun
12275         done
12276         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
12277                 cleanup_130
12278                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12279                         "luns or wrong len for OST $last_lun"
12280                 return
12281         fi
12282
12283         cleanup_130
12284
12285         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
12286 }
12287 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
12288
12289 test_130c() {
12290         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12291
12292         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12293         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12294
12295         trap cleanup_130 EXIT RETURN
12296
12297         local fm_file=$DIR/$tfile
12298         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
12299         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12300                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12301
12302         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
12303                         error "dd failed on $fm_file"
12304
12305         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12306         filefrag_op=$(filefrag -ve -k $fm_file |
12307                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12308
12309         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12310                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12311
12312         IFS=$'\n'
12313         tot_len=0
12314         num_luns=1
12315         for line in $filefrag_op
12316         do
12317                 frag_lun=$(echo $line | cut -d: -f5 |
12318                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12319                 ext_len=$(echo $line | cut -d: -f4)
12320                 if (( $frag_lun != $last_lun )); then
12321                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
12322                         if (( logical != 512 )); then
12323                                 cleanup_130
12324                                 error "FIEMAP on $fm_file failed; returned " \
12325                                 "logical start for lun $logical instead of 512"
12326                                 return
12327                         fi
12328                         if (( tot_len != 512 )); then
12329                                 cleanup_130
12330                                 error "FIEMAP on $fm_file failed; returned " \
12331                                 "len $tot_len for OST $last_lun instead of 1024"
12332                                 return
12333                         else
12334                                 (( num_luns += 1 ))
12335                                 tot_len=0
12336                         fi
12337                 fi
12338                 (( tot_len += ext_len ))
12339                 last_lun=$frag_lun
12340         done
12341         if (( num_luns != 2 || tot_len != 512 )); then
12342                 cleanup_130
12343                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12344                         "luns or wrong len for OST $last_lun"
12345                 return
12346         fi
12347
12348         cleanup_130
12349
12350         echo "FIEMAP on 2-stripe file with hole succeeded"
12351 }
12352 run_test 130c "FIEMAP (2-stripe file with hole)"
12353
12354 test_130d() {
12355         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
12356
12357         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12358         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12359
12360         trap cleanup_130 EXIT RETURN
12361
12362         local fm_file=$DIR/$tfile
12363         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12364                         error "setstripe on $fm_file"
12365         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12366                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12367
12368         local actual_stripe_count=$($LFS getstripe -c $fm_file)
12369         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
12370                 error "dd failed on $fm_file"
12371
12372         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12373         filefrag_op=$(filefrag -ve -k $fm_file |
12374                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12375
12376         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12377                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12378
12379         IFS=$'\n'
12380         tot_len=0
12381         num_luns=1
12382         for line in $filefrag_op
12383         do
12384                 frag_lun=$(echo $line | cut -d: -f5 |
12385                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12386                 ext_len=$(echo $line | cut -d: -f4)
12387                 if (( $frag_lun != $last_lun )); then
12388                         if (( tot_len != 1024 )); then
12389                                 cleanup_130
12390                                 error "FIEMAP on $fm_file failed; returned " \
12391                                 "len $tot_len for OST $last_lun instead of 1024"
12392                                 return
12393                         else
12394                                 (( num_luns += 1 ))
12395                                 tot_len=0
12396                         fi
12397                 fi
12398                 (( tot_len += ext_len ))
12399                 last_lun=$frag_lun
12400         done
12401         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
12402                 cleanup_130
12403                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12404                         "luns or wrong len for OST $last_lun"
12405                 return
12406         fi
12407
12408         cleanup_130
12409
12410         echo "FIEMAP on N-stripe file succeeded"
12411 }
12412 run_test 130d "FIEMAP (N-stripe file)"
12413
12414 test_130e() {
12415         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12416
12417         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12418         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12419
12420         trap cleanup_130 EXIT RETURN
12421
12422         local fm_file=$DIR/$tfile
12423         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
12424         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12425                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12426
12427         NUM_BLKS=512
12428         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
12429         for ((i = 0; i < $NUM_BLKS; i++))
12430         do
12431                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) conv=notrunc > /dev/null 2>&1
12432         done
12433
12434         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12435         filefrag_op=$(filefrag -ve -k $fm_file |
12436                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12437
12438         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12439                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12440
12441         IFS=$'\n'
12442         tot_len=0
12443         num_luns=1
12444         for line in $filefrag_op
12445         do
12446                 frag_lun=$(echo $line | cut -d: -f5 |
12447                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12448                 ext_len=$(echo $line | cut -d: -f4)
12449                 if (( $frag_lun != $last_lun )); then
12450                         if (( tot_len != $EXPECTED_LEN )); then
12451                                 cleanup_130
12452                                 error "FIEMAP on $fm_file failed; returned " \
12453                                 "len $tot_len for OST $last_lun instead " \
12454                                 "of $EXPECTED_LEN"
12455                                 return
12456                         else
12457                                 (( num_luns += 1 ))
12458                                 tot_len=0
12459                         fi
12460                 fi
12461                 (( tot_len += ext_len ))
12462                 last_lun=$frag_lun
12463         done
12464         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
12465                 cleanup_130
12466                 error "FIEMAP on $fm_file failed; returned wrong number " \
12467                         "of luns or wrong len for OST $last_lun"
12468                 return
12469         fi
12470
12471         cleanup_130
12472
12473         echo "FIEMAP with continuation calls succeeded"
12474 }
12475 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
12476
12477 test_130f() {
12478         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12479         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12480
12481         local fm_file=$DIR/$tfile
12482         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
12483                 error "multiop create with lov_delay_create on $fm_file"
12484
12485         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12486         filefrag_extents=$(filefrag -vek $fm_file |
12487                            awk '/extents? found/ { print $2 }')
12488         if [[ "$filefrag_extents" != "0" ]]; then
12489                 error "FIEMAP on $fm_file failed; " \
12490                       "returned $filefrag_extents expected 0"
12491         fi
12492
12493         rm -f $fm_file
12494 }
12495 run_test 130f "FIEMAP (unstriped file)"
12496
12497 # Test for writev/readv
12498 test_131a() {
12499         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
12500                 error "writev test failed"
12501         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
12502                 error "readv failed"
12503         rm -f $DIR/$tfile
12504 }
12505 run_test 131a "test iov's crossing stripe boundary for writev/readv"
12506
12507 test_131b() {
12508         local fsize=$((524288 + 1048576 + 1572864))
12509         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
12510                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12511                         error "append writev test failed"
12512
12513         ((fsize += 1572864 + 1048576))
12514         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
12515                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12516                         error "append writev test failed"
12517         rm -f $DIR/$tfile
12518 }
12519 run_test 131b "test append writev"
12520
12521 test_131c() {
12522         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
12523         error "NOT PASS"
12524 }
12525 run_test 131c "test read/write on file w/o objects"
12526
12527 test_131d() {
12528         rwv -f $DIR/$tfile -w -n 1 1572864
12529         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
12530         if [ "$NOB" != 1572864 ]; then
12531                 error "Short read filed: read $NOB bytes instead of 1572864"
12532         fi
12533         rm -f $DIR/$tfile
12534 }
12535 run_test 131d "test short read"
12536
12537 test_131e() {
12538         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
12539         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
12540         error "read hitting hole failed"
12541         rm -f $DIR/$tfile
12542 }
12543 run_test 131e "test read hitting hole"
12544
12545 check_stats() {
12546         local facet=$1
12547         local op=$2
12548         local want=${3:-0}
12549         local res
12550
12551         case $facet in
12552         mds*) res=$(do_facet $facet \
12553                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
12554                  ;;
12555         ost*) res=$(do_facet $facet \
12556                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
12557                  ;;
12558         *) error "Wrong facet '$facet'" ;;
12559         esac
12560         [ "$res" ] || error "The counter for $op on $facet was not incremented"
12561         # if the argument $3 is zero, it means any stat increment is ok.
12562         if [[ $want -gt 0 ]]; then
12563                 local count=$(echo $res | awk '{ print $2 }')
12564                 [[ $count -ne $want ]] &&
12565                         error "The $op counter on $facet is $count, not $want"
12566         fi
12567 }
12568
12569 test_133a() {
12570         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12571         remote_ost_nodsh && skip "remote OST with nodsh"
12572         remote_mds_nodsh && skip "remote MDS with nodsh"
12573         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
12574                 skip_env "MDS doesn't support rename stats"
12575
12576         local testdir=$DIR/${tdir}/stats_testdir
12577
12578         mkdir -p $DIR/${tdir}
12579
12580         # clear stats.
12581         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12582         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12583
12584         # verify mdt stats first.
12585         mkdir ${testdir} || error "mkdir failed"
12586         check_stats $SINGLEMDS "mkdir" 1
12587         touch ${testdir}/${tfile} || error "touch failed"
12588         check_stats $SINGLEMDS "open" 1
12589         check_stats $SINGLEMDS "close" 1
12590         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
12591                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
12592                 check_stats $SINGLEMDS "mknod" 2
12593         }
12594         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
12595         check_stats $SINGLEMDS "unlink" 1
12596         rm -f ${testdir}/${tfile} || error "file remove failed"
12597         check_stats $SINGLEMDS "unlink" 2
12598
12599         # remove working dir and check mdt stats again.
12600         rmdir ${testdir} || error "rmdir failed"
12601         check_stats $SINGLEMDS "rmdir" 1
12602
12603         local testdir1=$DIR/${tdir}/stats_testdir1
12604         mkdir -p ${testdir}
12605         mkdir -p ${testdir1}
12606         touch ${testdir1}/test1
12607         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
12608         check_stats $SINGLEMDS "crossdir_rename" 1
12609
12610         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
12611         check_stats $SINGLEMDS "samedir_rename" 1
12612
12613         rm -rf $DIR/${tdir}
12614 }
12615 run_test 133a "Verifying MDT stats ========================================"
12616
12617 test_133b() {
12618         local res
12619
12620         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12621         remote_ost_nodsh && skip "remote OST with nodsh"
12622         remote_mds_nodsh && skip "remote MDS with nodsh"
12623
12624         local testdir=$DIR/${tdir}/stats_testdir
12625
12626         mkdir -p ${testdir} || error "mkdir failed"
12627         touch ${testdir}/${tfile} || error "touch failed"
12628         cancel_lru_locks mdc
12629
12630         # clear stats.
12631         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12632         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12633
12634         # extra mdt stats verification.
12635         chmod 444 ${testdir}/${tfile} || error "chmod failed"
12636         check_stats $SINGLEMDS "setattr" 1
12637         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12638         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
12639         then            # LU-1740
12640                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
12641                 check_stats $SINGLEMDS "getattr" 1
12642         fi
12643         rm -rf $DIR/${tdir}
12644
12645         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
12646         # so the check below is not reliable
12647         [ $MDSCOUNT -eq 1 ] || return 0
12648
12649         # Sleep to avoid a cached response.
12650         #define OBD_STATFS_CACHE_SECONDS 1
12651         sleep 2
12652         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12653         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12654         $LFS df || error "lfs failed"
12655         check_stats $SINGLEMDS "statfs" 1
12656
12657         # check aggregated statfs (LU-10018)
12658         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
12659                 return 0
12660         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
12661                 return 0
12662         sleep 2
12663         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12664         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12665         df $DIR
12666         check_stats $SINGLEMDS "statfs" 1
12667
12668         # We want to check that the client didn't send OST_STATFS to
12669         # ost1 but the MDT also uses OST_STATFS for precreate. So some
12670         # extra care is needed here.
12671         if remote_mds; then
12672                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
12673                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
12674
12675                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
12676                 [ "$res" ] && error "OST got STATFS"
12677         fi
12678
12679         return 0
12680 }
12681 run_test 133b "Verifying extra MDT stats =================================="
12682
12683 test_133c() {
12684         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12685         remote_ost_nodsh && skip "remote OST with nodsh"
12686         remote_mds_nodsh && skip "remote MDS with nodsh"
12687
12688         local testdir=$DIR/$tdir/stats_testdir
12689
12690         test_mkdir -p $testdir
12691
12692         # verify obdfilter stats.
12693         $LFS setstripe -c 1 -i 0 $testdir/$tfile
12694         sync
12695         cancel_lru_locks osc
12696         wait_delete_completed
12697
12698         # clear stats.
12699         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12700         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12701
12702         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
12703                 error "dd failed"
12704         sync
12705         cancel_lru_locks osc
12706         check_stats ost1 "write" 1
12707
12708         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
12709         check_stats ost1 "read" 1
12710
12711         > $testdir/$tfile || error "truncate failed"
12712         check_stats ost1 "punch" 1
12713
12714         rm -f $testdir/$tfile || error "file remove failed"
12715         wait_delete_completed
12716         check_stats ost1 "destroy" 1
12717
12718         rm -rf $DIR/$tdir
12719 }
12720 run_test 133c "Verifying OST stats ========================================"
12721
12722 order_2() {
12723         local value=$1
12724         local orig=$value
12725         local order=1
12726
12727         while [ $value -ge 2 ]; do
12728                 order=$((order*2))
12729                 value=$((value/2))
12730         done
12731
12732         if [ $orig -gt $order ]; then
12733                 order=$((order*2))
12734         fi
12735         echo $order
12736 }
12737
12738 size_in_KMGT() {
12739     local value=$1
12740     local size=('K' 'M' 'G' 'T');
12741     local i=0
12742     local size_string=$value
12743
12744     while [ $value -ge 1024 ]; do
12745         if [ $i -gt 3 ]; then
12746             #T is the biggest unit we get here, if that is bigger,
12747             #just return XXXT
12748             size_string=${value}T
12749             break
12750         fi
12751         value=$((value >> 10))
12752         if [ $value -lt 1024 ]; then
12753             size_string=${value}${size[$i]}
12754             break
12755         fi
12756         i=$((i + 1))
12757     done
12758
12759     echo $size_string
12760 }
12761
12762 get_rename_size() {
12763         local size=$1
12764         local context=${2:-.}
12765         local sample=$(do_facet $SINGLEMDS $LCTL \
12766                 get_param mdt.$FSNAME-MDT0000.rename_stats |
12767                 grep -A1 $context |
12768                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
12769         echo $sample
12770 }
12771
12772 test_133d() {
12773         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12774         remote_ost_nodsh && skip "remote OST with nodsh"
12775         remote_mds_nodsh && skip "remote MDS with nodsh"
12776         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
12777                 skip_env "MDS doesn't support rename stats"
12778
12779         local testdir1=$DIR/${tdir}/stats_testdir1
12780         local testdir2=$DIR/${tdir}/stats_testdir2
12781         mkdir -p $DIR/${tdir}
12782
12783         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
12784
12785         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
12786         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
12787
12788         createmany -o $testdir1/test 512 || error "createmany failed"
12789
12790         # check samedir rename size
12791         mv ${testdir1}/test0 ${testdir1}/test_0
12792
12793         local testdir1_size=$(ls -l $DIR/${tdir} |
12794                 awk '/stats_testdir1/ {print $5}')
12795         local testdir2_size=$(ls -l $DIR/${tdir} |
12796                 awk '/stats_testdir2/ {print $5}')
12797
12798         testdir1_size=$(order_2 $testdir1_size)
12799         testdir2_size=$(order_2 $testdir2_size)
12800
12801         testdir1_size=$(size_in_KMGT $testdir1_size)
12802         testdir2_size=$(size_in_KMGT $testdir2_size)
12803
12804         echo "source rename dir size: ${testdir1_size}"
12805         echo "target rename dir size: ${testdir2_size}"
12806
12807         local cmd="do_facet $SINGLEMDS $LCTL "
12808         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
12809
12810         eval $cmd || error "$cmd failed"
12811         local samedir=$($cmd | grep 'same_dir')
12812         local same_sample=$(get_rename_size $testdir1_size)
12813         [ -z "$samedir" ] && error "samedir_rename_size count error"
12814         [[ $same_sample -eq 1 ]] ||
12815                 error "samedir_rename_size error $same_sample"
12816         echo "Check same dir rename stats success"
12817
12818         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
12819
12820         # check crossdir rename size
12821         mv ${testdir1}/test_0 ${testdir2}/test_0
12822
12823         testdir1_size=$(ls -l $DIR/${tdir} |
12824                 awk '/stats_testdir1/ {print $5}')
12825         testdir2_size=$(ls -l $DIR/${tdir} |
12826                 awk '/stats_testdir2/ {print $5}')
12827
12828         testdir1_size=$(order_2 $testdir1_size)
12829         testdir2_size=$(order_2 $testdir2_size)
12830
12831         testdir1_size=$(size_in_KMGT $testdir1_size)
12832         testdir2_size=$(size_in_KMGT $testdir2_size)
12833
12834         echo "source rename dir size: ${testdir1_size}"
12835         echo "target rename dir size: ${testdir2_size}"
12836
12837         eval $cmd || error "$cmd failed"
12838         local crossdir=$($cmd | grep 'crossdir')
12839         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
12840         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
12841         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
12842         [[ $src_sample -eq 1 ]] ||
12843                 error "crossdir_rename_size error $src_sample"
12844         [[ $tgt_sample -eq 1 ]] ||
12845                 error "crossdir_rename_size error $tgt_sample"
12846         echo "Check cross dir rename stats success"
12847         rm -rf $DIR/${tdir}
12848 }
12849 run_test 133d "Verifying rename_stats ========================================"
12850
12851 test_133e() {
12852         remote_mds_nodsh && skip "remote MDS with nodsh"
12853         remote_ost_nodsh && skip "remote OST with nodsh"
12854         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12855
12856         local testdir=$DIR/${tdir}/stats_testdir
12857         local ctr f0 f1 bs=32768 count=42 sum
12858
12859         mkdir -p ${testdir} || error "mkdir failed"
12860
12861         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
12862
12863         for ctr in {write,read}_bytes; do
12864                 sync
12865                 cancel_lru_locks osc
12866
12867                 do_facet ost1 $LCTL set_param -n \
12868                         "obdfilter.*.exports.clear=clear"
12869
12870                 if [ $ctr = write_bytes ]; then
12871                         f0=/dev/zero
12872                         f1=${testdir}/${tfile}
12873                 else
12874                         f0=${testdir}/${tfile}
12875                         f1=/dev/null
12876                 fi
12877
12878                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
12879                         error "dd failed"
12880                 sync
12881                 cancel_lru_locks osc
12882
12883                 sum=$(do_facet ost1 $LCTL get_param \
12884                         "obdfilter.*.exports.*.stats" |
12885                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
12886                                 $1 == ctr { sum += $7 }
12887                                 END { printf("%0.0f", sum) }')
12888
12889                 if ((sum != bs * count)); then
12890                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
12891                 fi
12892         done
12893
12894         rm -rf $DIR/${tdir}
12895 }
12896 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
12897
12898 test_133f() {
12899         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
12900                 skip "too old lustre for get_param -R ($facet_ver)"
12901
12902         # verifying readability.
12903         $LCTL get_param -R '*' &> /dev/null
12904
12905         # Verifing writability with badarea_io.
12906         $LCTL list_param -FR '*' | grep '=' | tr -d = |
12907                 egrep -v 'force_lbug|changelog_mask' | xargs badarea_io ||
12908                 error "client badarea_io failed"
12909
12910         # remount the FS in case writes/reads /proc break the FS
12911         cleanup || error "failed to unmount"
12912         setup || error "failed to setup"
12913 }
12914 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
12915
12916 test_133g() {
12917         remote_mds_nodsh && skip "remote MDS with nodsh"
12918         remote_ost_nodsh && skip "remote OST with nodsh"
12919
12920         local facet
12921         for facet in mds1 ost1; do
12922                 local facet_ver=$(lustre_version_code $facet)
12923                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
12924                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
12925                 else
12926                         log "$facet: too old lustre for get_param -R"
12927                 fi
12928                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
12929                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
12930                                 tr -d = | egrep -v 'force_lbug|changelog_mask' |
12931                                 xargs badarea_io" ||
12932                                         error "$facet badarea_io failed"
12933                 else
12934                         skip_noexit "$facet: too old lustre for get_param -R"
12935                 fi
12936         done
12937
12938         # remount the FS in case writes/reads /proc break the FS
12939         cleanup || error "failed to unmount"
12940         setup || error "failed to setup"
12941 }
12942 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
12943
12944 test_133h() {
12945         remote_mds_nodsh && skip "remote MDS with nodsh"
12946         remote_ost_nodsh && skip "remote OST with nodsh"
12947         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
12948                 skip "Need MDS version at least 2.9.54"
12949
12950         local facet
12951         for facet in client mds1 ost1; do
12952                 # Get the list of files that are missing the terminating newline
12953                 local plist=$(do_facet $facet
12954                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
12955                 local ent
12956                 for ent in $plist; do
12957                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
12958                                 awk -v FS='\v' -v RS='\v\v' \
12959                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
12960                                         print FILENAME}'" 2>/dev/null)
12961                         [ -z $missing ] || {
12962                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
12963                                 error "file does not end with newline: $facet-$ent"
12964                         }
12965                 done
12966         done
12967 }
12968 run_test 133h "Proc files should end with newlines"
12969
12970 test_134a() {
12971         remote_mds_nodsh && skip "remote MDS with nodsh"
12972         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
12973                 skip "Need MDS version at least 2.7.54"
12974
12975         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
12976         cancel_lru_locks mdc
12977
12978         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12979         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12980         [ $unused -eq 0 ] || error "$unused locks are not cleared"
12981
12982         local nr=1000
12983         createmany -o $DIR/$tdir/f $nr ||
12984                 error "failed to create $nr files in $DIR/$tdir"
12985         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12986
12987         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
12988         do_facet mds1 $LCTL set_param fail_loc=0x327
12989         do_facet mds1 $LCTL set_param fail_val=500
12990         touch $DIR/$tdir/m
12991
12992         echo "sleep 10 seconds ..."
12993         sleep 10
12994         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
12995
12996         do_facet mds1 $LCTL set_param fail_loc=0
12997         do_facet mds1 $LCTL set_param fail_val=0
12998         [ $lck_cnt -lt $unused ] ||
12999                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
13000
13001         rm $DIR/$tdir/m
13002         unlinkmany $DIR/$tdir/f $nr
13003 }
13004 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
13005
13006 test_134b() {
13007         remote_mds_nodsh && skip "remote MDS with nodsh"
13008         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13009                 skip "Need MDS version at least 2.7.54"
13010
13011         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13012         cancel_lru_locks mdc
13013
13014         local low_wm=$(do_facet mds1 $LCTL get_param -n \
13015                         ldlm.lock_reclaim_threshold_mb)
13016         # disable reclaim temporarily
13017         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
13018
13019         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
13020         do_facet mds1 $LCTL set_param fail_loc=0x328
13021         do_facet mds1 $LCTL set_param fail_val=500
13022
13023         $LCTL set_param debug=+trace
13024
13025         local nr=600
13026         createmany -o $DIR/$tdir/f $nr &
13027         local create_pid=$!
13028
13029         echo "Sleep $TIMEOUT seconds ..."
13030         sleep $TIMEOUT
13031         if ! ps -p $create_pid  > /dev/null 2>&1; then
13032                 do_facet mds1 $LCTL set_param fail_loc=0
13033                 do_facet mds1 $LCTL set_param fail_val=0
13034                 do_facet mds1 $LCTL set_param \
13035                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
13036                 error "createmany finished incorrectly!"
13037         fi
13038         do_facet mds1 $LCTL set_param fail_loc=0
13039         do_facet mds1 $LCTL set_param fail_val=0
13040         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
13041         wait $create_pid || return 1
13042
13043         unlinkmany $DIR/$tdir/f $nr
13044 }
13045 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
13046
13047 test_135() {
13048         remote_mds_nodsh && skip "remote MDS with nodsh"
13049         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13050                 skip "Need MDS version at least 2.13.50"
13051         local fname
13052
13053         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13054
13055 #define OBD_FAIL_PLAIN_RECORDS 0x1319
13056         #set only one record at plain llog
13057         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
13058
13059         #fill already existed plain llog each 64767
13060         #wrapping whole catalog
13061         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13062
13063         createmany -o $DIR/$tdir/$tfile_ 64700
13064         for (( i = 0; i < 64700; i = i + 2 ))
13065         do
13066                 rm $DIR/$tdir/$tfile_$i &
13067                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13068                 local pid=$!
13069                 wait $pid
13070         done
13071
13072         #waiting osp synchronization
13073         wait_delete_completed
13074 }
13075 run_test 135 "Race catalog processing"
13076
13077 test_136() {
13078         remote_mds_nodsh && skip "remote MDS with nodsh"
13079         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13080                 skip "Need MDS version at least 2.13.50"
13081         local fname
13082
13083         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13084         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
13085         #set only one record at plain llog
13086 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
13087         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
13088
13089         #fill already existed 2 plain llogs each 64767
13090         #wrapping whole catalog
13091         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13092         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
13093         wait_delete_completed
13094
13095         createmany -o $DIR/$tdir/$tfile_ 10
13096         sleep 25
13097
13098         do_facet $SINGLEMDS $LCTL set_param fail_val=3
13099         for (( i = 0; i < 10; i = i + 3 ))
13100         do
13101                 rm $DIR/$tdir/$tfile_$i &
13102                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13103                 local pid=$!
13104                 wait $pid
13105                 sleep 7
13106                 rm $DIR/$tdir/$tfile_$((i + 2)) &
13107         done
13108
13109         #waiting osp synchronization
13110         wait_delete_completed
13111 }
13112 run_test 136 "Race catalog processing 2"
13113
13114 test_140() { #bug-17379
13115         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13116
13117         test_mkdir $DIR/$tdir
13118         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
13119         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
13120
13121         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
13122         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
13123         local i=0
13124         while i=$((i + 1)); do
13125                 test_mkdir $i
13126                 cd $i || error "Changing to $i"
13127                 ln -s ../stat stat || error "Creating stat symlink"
13128                 # Read the symlink until ELOOP present,
13129                 # not LBUGing the system is considered success,
13130                 # we didn't overrun the stack.
13131                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
13132                 if [ $ret -ne 0 ]; then
13133                         if [ $ret -eq 40 ]; then
13134                                 break  # -ELOOP
13135                         else
13136                                 error "Open stat symlink"
13137                                         return
13138                         fi
13139                 fi
13140         done
13141         i=$((i - 1))
13142         echo "The symlink depth = $i"
13143         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
13144                 error "Invalid symlink depth"
13145
13146         # Test recursive symlink
13147         ln -s symlink_self symlink_self
13148         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
13149         echo "open symlink_self returns $ret"
13150         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
13151 }
13152 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
13153
13154 test_150a() {
13155         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13156
13157         local TF="$TMP/$tfile"
13158
13159         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13160         cp $TF $DIR/$tfile
13161         cancel_lru_locks $OSC
13162         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
13163         remount_client $MOUNT
13164         df -P $MOUNT
13165         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
13166
13167         $TRUNCATE $TF 6000
13168         $TRUNCATE $DIR/$tfile 6000
13169         cancel_lru_locks $OSC
13170         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
13171
13172         echo "12345" >>$TF
13173         echo "12345" >>$DIR/$tfile
13174         cancel_lru_locks $OSC
13175         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
13176
13177         echo "12345" >>$TF
13178         echo "12345" >>$DIR/$tfile
13179         cancel_lru_locks $OSC
13180         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
13181
13182         rm -f $TF
13183         true
13184 }
13185 run_test 150a "truncate/append tests"
13186
13187 test_150b() {
13188         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13189         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13190                 skip "Need OST version at least 2.13.53"
13191         touch $DIR/$tfile
13192         check_fallocate $DIR/$tfile || error "fallocate failed"
13193 }
13194 run_test 150b "Verify fallocate (prealloc) functionality"
13195
13196 test_150c() {
13197         local bytes
13198         local want
13199
13200         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13201         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13202                 skip "Need OST version at least 2.13.53"
13203
13204         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
13205         fallocate -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
13206         sync; sync_all_data
13207         cancel_lru_locks $OSC
13208         sleep 5
13209         bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
13210         want=$((OSTCOUNT * 1048576))
13211
13212         # Must allocate all requested space, not more than 5% extra
13213         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13214                 error "bytes $bytes is not $want"
13215 }
13216 run_test 150c "Verify fallocate Size and Blocks"
13217
13218 test_150d() {
13219         local bytes
13220         local want
13221
13222         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13223         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13224                 skip "Need OST version at least 2.13.53"
13225
13226         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
13227         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
13228         sync; sync_all_data
13229         cancel_lru_locks $OSC
13230         sleep 5
13231         bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
13232         want=$((OSTCOUNT * 1048576))
13233
13234         # Must allocate all requested space, not more than 5% extra
13235         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13236                 error "bytes $bytes is not $want"
13237 }
13238 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
13239
13240 #LU-2902 roc_hit was not able to read all values from lproc
13241 function roc_hit_init() {
13242         local list=$(comma_list $(osts_nodes))
13243         local dir=$DIR/$tdir-check
13244         local file=$dir/$tfile
13245         local BEFORE
13246         local AFTER
13247         local idx
13248
13249         test_mkdir $dir
13250         #use setstripe to do a write to every ost
13251         for i in $(seq 0 $((OSTCOUNT-1))); do
13252                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
13253                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
13254                 idx=$(printf %04x $i)
13255                 BEFORE=$(get_osd_param $list *OST*$idx stats |
13256                         awk '$1 == "cache_access" {sum += $7}
13257                                 END { printf("%0.0f", sum) }')
13258
13259                 cancel_lru_locks osc
13260                 cat $file >/dev/null
13261
13262                 AFTER=$(get_osd_param $list *OST*$idx stats |
13263                         awk '$1 == "cache_access" {sum += $7}
13264                                 END { printf("%0.0f", sum) }')
13265
13266                 echo BEFORE:$BEFORE AFTER:$AFTER
13267                 if ! let "AFTER - BEFORE == 4"; then
13268                         rm -rf $dir
13269                         error "roc_hit is not safe to use"
13270                 fi
13271                 rm $file
13272         done
13273
13274         rm -rf $dir
13275 }
13276
13277 function roc_hit() {
13278         local list=$(comma_list $(osts_nodes))
13279         echo $(get_osd_param $list '' stats |
13280                 awk '$1 == "cache_hit" {sum += $7}
13281                         END { printf("%0.0f", sum) }')
13282 }
13283
13284 function set_cache() {
13285         local on=1
13286
13287         if [ "$2" == "off" ]; then
13288                 on=0;
13289         fi
13290         local list=$(comma_list $(osts_nodes))
13291         set_osd_param $list '' $1_cache_enable $on
13292
13293         cancel_lru_locks osc
13294 }
13295
13296 test_151() {
13297         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13298         remote_ost_nodsh && skip "remote OST with nodsh"
13299
13300         local CPAGES=3
13301         local list=$(comma_list $(osts_nodes))
13302
13303         # check whether obdfilter is cache capable at all
13304         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
13305                 skip "not cache-capable obdfilter"
13306         fi
13307
13308         # check cache is enabled on all obdfilters
13309         if get_osd_param $list '' read_cache_enable | grep 0; then
13310                 skip "oss cache is disabled"
13311         fi
13312
13313         set_osd_param $list '' writethrough_cache_enable 1
13314
13315         # check write cache is enabled on all obdfilters
13316         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
13317                 skip "oss write cache is NOT enabled"
13318         fi
13319
13320         roc_hit_init
13321
13322         #define OBD_FAIL_OBD_NO_LRU  0x609
13323         do_nodes $list $LCTL set_param fail_loc=0x609
13324
13325         # pages should be in the case right after write
13326         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
13327                 error "dd failed"
13328
13329         local BEFORE=$(roc_hit)
13330         cancel_lru_locks osc
13331         cat $DIR/$tfile >/dev/null
13332         local AFTER=$(roc_hit)
13333
13334         do_nodes $list $LCTL set_param fail_loc=0
13335
13336         if ! let "AFTER - BEFORE == CPAGES"; then
13337                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
13338         fi
13339
13340         cancel_lru_locks osc
13341         # invalidates OST cache
13342         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
13343         set_osd_param $list '' read_cache_enable 0
13344         cat $DIR/$tfile >/dev/null
13345
13346         # now data shouldn't be found in the cache
13347         BEFORE=$(roc_hit)
13348         cancel_lru_locks osc
13349         cat $DIR/$tfile >/dev/null
13350         AFTER=$(roc_hit)
13351         if let "AFTER - BEFORE != 0"; then
13352                 error "IN CACHE: before: $BEFORE, after: $AFTER"
13353         fi
13354
13355         set_osd_param $list '' read_cache_enable 1
13356         rm -f $DIR/$tfile
13357 }
13358 run_test 151 "test cache on oss and controls ==============================="
13359
13360 test_152() {
13361         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13362
13363         local TF="$TMP/$tfile"
13364
13365         # simulate ENOMEM during write
13366 #define OBD_FAIL_OST_NOMEM      0x226
13367         lctl set_param fail_loc=0x80000226
13368         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13369         cp $TF $DIR/$tfile
13370         sync || error "sync failed"
13371         lctl set_param fail_loc=0
13372
13373         # discard client's cache
13374         cancel_lru_locks osc
13375
13376         # simulate ENOMEM during read
13377         lctl set_param fail_loc=0x80000226
13378         cmp $TF $DIR/$tfile || error "cmp failed"
13379         lctl set_param fail_loc=0
13380
13381         rm -f $TF
13382 }
13383 run_test 152 "test read/write with enomem ============================"
13384
13385 test_153() {
13386         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
13387 }
13388 run_test 153 "test if fdatasync does not crash ======================="
13389
13390 dot_lustre_fid_permission_check() {
13391         local fid=$1
13392         local ffid=$MOUNT/.lustre/fid/$fid
13393         local test_dir=$2
13394
13395         echo "stat fid $fid"
13396         stat $ffid > /dev/null || error "stat $ffid failed."
13397         echo "touch fid $fid"
13398         touch $ffid || error "touch $ffid failed."
13399         echo "write to fid $fid"
13400         cat /etc/hosts > $ffid || error "write $ffid failed."
13401         echo "read fid $fid"
13402         diff /etc/hosts $ffid || error "read $ffid failed."
13403         echo "append write to fid $fid"
13404         cat /etc/hosts >> $ffid || error "append write $ffid failed."
13405         echo "rename fid $fid"
13406         mv $ffid $test_dir/$tfile.1 &&
13407                 error "rename $ffid to $tfile.1 should fail."
13408         touch $test_dir/$tfile.1
13409         mv $test_dir/$tfile.1 $ffid &&
13410                 error "rename $tfile.1 to $ffid should fail."
13411         rm -f $test_dir/$tfile.1
13412         echo "truncate fid $fid"
13413         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
13414         echo "link fid $fid"
13415         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
13416         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
13417                 echo "setfacl fid $fid"
13418                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
13419                 echo "getfacl fid $fid"
13420                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
13421         fi
13422         echo "unlink fid $fid"
13423         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
13424         echo "mknod fid $fid"
13425         mknod $ffid c 1 3 && error "mknod $ffid should fail."
13426
13427         fid=[0xf00000400:0x1:0x0]
13428         ffid=$MOUNT/.lustre/fid/$fid
13429
13430         echo "stat non-exist fid $fid"
13431         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
13432         echo "write to non-exist fid $fid"
13433         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
13434         echo "link new fid $fid"
13435         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
13436
13437         mkdir -p $test_dir/$tdir
13438         touch $test_dir/$tdir/$tfile
13439         fid=$($LFS path2fid $test_dir/$tdir)
13440         rc=$?
13441         [ $rc -ne 0 ] &&
13442                 error "error: could not get fid for $test_dir/$dir/$tfile."
13443
13444         ffid=$MOUNT/.lustre/fid/$fid
13445
13446         echo "ls $fid"
13447         ls $ffid > /dev/null || error "ls $ffid failed."
13448         echo "touch $fid/$tfile.1"
13449         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
13450
13451         echo "touch $MOUNT/.lustre/fid/$tfile"
13452         touch $MOUNT/.lustre/fid/$tfile && \
13453                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
13454
13455         echo "setxattr to $MOUNT/.lustre/fid"
13456         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
13457
13458         echo "listxattr for $MOUNT/.lustre/fid"
13459         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
13460
13461         echo "delxattr from $MOUNT/.lustre/fid"
13462         setfattr -x trusted.name1 $MOUNT/.lustre/fid
13463
13464         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
13465         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
13466                 error "touch invalid fid should fail."
13467
13468         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
13469         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
13470                 error "touch non-normal fid should fail."
13471
13472         echo "rename $tdir to $MOUNT/.lustre/fid"
13473         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
13474                 error "rename to $MOUNT/.lustre/fid should fail."
13475
13476         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
13477         then            # LU-3547
13478                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
13479                 local new_obf_mode=777
13480
13481                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
13482                 chmod $new_obf_mode $DIR/.lustre/fid ||
13483                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
13484
13485                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
13486                 [ $obf_mode -eq $new_obf_mode ] ||
13487                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
13488
13489                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
13490                 chmod $old_obf_mode $DIR/.lustre/fid ||
13491                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
13492         fi
13493
13494         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
13495         fid=$($LFS path2fid $test_dir/$tfile-2)
13496
13497         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
13498         then # LU-5424
13499                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
13500                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
13501                         error "create lov data thru .lustre failed"
13502         fi
13503         echo "cp /etc/passwd $test_dir/$tfile-2"
13504         cp /etc/passwd $test_dir/$tfile-2 ||
13505                 error "copy to $test_dir/$tfile-2 failed."
13506         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
13507         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
13508                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
13509
13510         rm -rf $test_dir/tfile.lnk
13511         rm -rf $test_dir/$tfile-2
13512 }
13513
13514 test_154A() {
13515         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13516                 skip "Need MDS version at least 2.4.1"
13517
13518         local tf=$DIR/$tfile
13519         touch $tf
13520
13521         local fid=$($LFS path2fid $tf)
13522         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
13523
13524         # check that we get the same pathname back
13525         local found=$($LFS fid2path $MOUNT "$fid")
13526         [ -z "$found" ] && error "fid2path unable to get '$fid' path"
13527         [ "$found" == "$tf" ] ||
13528                 error "fid2path($fid=path2fid($tf)) = $found != $tf"
13529 }
13530 run_test 154A "lfs path2fid and fid2path basic checks"
13531
13532 test_154B() {
13533         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13534                 skip "Need MDS version at least 2.4.1"
13535
13536         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
13537         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
13538         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
13539         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
13540
13541         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
13542         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
13543
13544         # check that we get the same pathname
13545         echo "PFID: $PFID, name: $name"
13546         local FOUND=$($LFS fid2path $MOUNT "$PFID")
13547         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
13548         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
13549                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
13550
13551         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
13552 }
13553 run_test 154B "verify the ll_decode_linkea tool"
13554
13555 test_154a() {
13556         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13557         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13558         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
13559                 skip "Need MDS version at least 2.2.51"
13560         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13561
13562         cp /etc/hosts $DIR/$tfile
13563
13564         fid=$($LFS path2fid $DIR/$tfile)
13565         rc=$?
13566         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
13567
13568         dot_lustre_fid_permission_check "$fid" $DIR ||
13569                 error "dot lustre permission check $fid failed"
13570
13571         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
13572
13573         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
13574
13575         touch $MOUNT/.lustre/file &&
13576                 error "creation is not allowed under .lustre"
13577
13578         mkdir $MOUNT/.lustre/dir &&
13579                 error "mkdir is not allowed under .lustre"
13580
13581         rm -rf $DIR/$tfile
13582 }
13583 run_test 154a "Open-by-FID"
13584
13585 test_154b() {
13586         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13587         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13588         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13589         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
13590                 skip "Need MDS version at least 2.2.51"
13591
13592         local remote_dir=$DIR/$tdir/remote_dir
13593         local MDTIDX=1
13594         local rc=0
13595
13596         mkdir -p $DIR/$tdir
13597         $LFS mkdir -i $MDTIDX $remote_dir ||
13598                 error "create remote directory failed"
13599
13600         cp /etc/hosts $remote_dir/$tfile
13601
13602         fid=$($LFS path2fid $remote_dir/$tfile)
13603         rc=$?
13604         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
13605
13606         dot_lustre_fid_permission_check "$fid" $remote_dir ||
13607                 error "dot lustre permission check $fid failed"
13608         rm -rf $DIR/$tdir
13609 }
13610 run_test 154b "Open-by-FID for remote directory"
13611
13612 test_154c() {
13613         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13614                 skip "Need MDS version at least 2.4.1"
13615
13616         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
13617         local FID1=$($LFS path2fid $DIR/$tfile.1)
13618         local FID2=$($LFS path2fid $DIR/$tfile.2)
13619         local FID3=$($LFS path2fid $DIR/$tfile.3)
13620
13621         local N=1
13622         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
13623                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
13624                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
13625                 local want=FID$N
13626                 [ "$FID" = "${!want}" ] ||
13627                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
13628                 N=$((N + 1))
13629         done
13630
13631         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
13632         do
13633                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
13634                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
13635                 N=$((N + 1))
13636         done
13637 }
13638 run_test 154c "lfs path2fid and fid2path multiple arguments"
13639
13640 test_154d() {
13641         remote_mds_nodsh && skip "remote MDS with nodsh"
13642         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
13643                 skip "Need MDS version at least 2.5.53"
13644
13645         if remote_mds; then
13646                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
13647         else
13648                 nid="0@lo"
13649         fi
13650         local proc_ofile="mdt.*.exports.'$nid'.open_files"
13651         local fd
13652         local cmd
13653
13654         rm -f $DIR/$tfile
13655         touch $DIR/$tfile
13656
13657         local fid=$($LFS path2fid $DIR/$tfile)
13658         # Open the file
13659         fd=$(free_fd)
13660         cmd="exec $fd<$DIR/$tfile"
13661         eval $cmd
13662         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
13663         echo "$fid_list" | grep "$fid"
13664         rc=$?
13665
13666         cmd="exec $fd>/dev/null"
13667         eval $cmd
13668         if [ $rc -ne 0 ]; then
13669                 error "FID $fid not found in open files list $fid_list"
13670         fi
13671 }
13672 run_test 154d "Verify open file fid"
13673
13674 test_154e()
13675 {
13676         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
13677                 skip "Need MDS version at least 2.6.50"
13678
13679         if ls -a $MOUNT | grep -q '^\.lustre$'; then
13680                 error ".lustre returned by readdir"
13681         fi
13682 }
13683 run_test 154e ".lustre is not returned by readdir"
13684
13685 test_154f() {
13686         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13687
13688         # create parent directory on a single MDT to avoid cross-MDT hardlinks
13689         test_mkdir -p -c1 $DIR/$tdir/d
13690         # test dirs inherit from its stripe
13691         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
13692         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
13693         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
13694         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
13695         touch $DIR/f
13696
13697         # get fid of parents
13698         local FID0=$($LFS path2fid $DIR/$tdir/d)
13699         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
13700         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
13701         local FID3=$($LFS path2fid $DIR)
13702
13703         # check that path2fid --parents returns expected <parent_fid>/name
13704         # 1) test for a directory (single parent)
13705         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
13706         [ "$parent" == "$FID0/foo1" ] ||
13707                 error "expected parent: $FID0/foo1, got: $parent"
13708
13709         # 2) test for a file with nlink > 1 (multiple parents)
13710         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
13711         echo "$parent" | grep -F "$FID1/$tfile" ||
13712                 error "$FID1/$tfile not returned in parent list"
13713         echo "$parent" | grep -F "$FID2/link" ||
13714                 error "$FID2/link not returned in parent list"
13715
13716         # 3) get parent by fid
13717         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
13718         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13719         echo "$parent" | grep -F "$FID1/$tfile" ||
13720                 error "$FID1/$tfile not returned in parent list (by fid)"
13721         echo "$parent" | grep -F "$FID2/link" ||
13722                 error "$FID2/link not returned in parent list (by fid)"
13723
13724         # 4) test for entry in root directory
13725         parent=$($LFS path2fid --parents $DIR/f)
13726         echo "$parent" | grep -F "$FID3/f" ||
13727                 error "$FID3/f not returned in parent list"
13728
13729         # 5) test it on root directory
13730         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
13731                 error "$MOUNT should not have parents"
13732
13733         # enable xattr caching and check that linkea is correctly updated
13734         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
13735         save_lustre_params client "llite.*.xattr_cache" > $save
13736         lctl set_param llite.*.xattr_cache 1
13737
13738         # 6.1) linkea update on rename
13739         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
13740
13741         # get parents by fid
13742         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13743         # foo1 should no longer be returned in parent list
13744         echo "$parent" | grep -F "$FID1" &&
13745                 error "$FID1 should no longer be in parent list"
13746         # the new path should appear
13747         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
13748                 error "$FID2/$tfile.moved is not in parent list"
13749
13750         # 6.2) linkea update on unlink
13751         rm -f $DIR/$tdir/d/foo2/link
13752         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13753         # foo2/link should no longer be returned in parent list
13754         echo "$parent" | grep -F "$FID2/link" &&
13755                 error "$FID2/link should no longer be in parent list"
13756         true
13757
13758         rm -f $DIR/f
13759         restore_lustre_params < $save
13760         rm -f $save
13761 }
13762 run_test 154f "get parent fids by reading link ea"
13763
13764 test_154g()
13765 {
13766         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13767         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
13768            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
13769                 skip "Need MDS version at least 2.6.92"
13770
13771         mkdir -p $DIR/$tdir
13772         llapi_fid_test -d $DIR/$tdir
13773 }
13774 run_test 154g "various llapi FID tests"
13775
13776 test_155_small_load() {
13777     local temp=$TMP/$tfile
13778     local file=$DIR/$tfile
13779
13780     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
13781         error "dd of=$temp bs=6096 count=1 failed"
13782     cp $temp $file
13783     cancel_lru_locks $OSC
13784     cmp $temp $file || error "$temp $file differ"
13785
13786     $TRUNCATE $temp 6000
13787     $TRUNCATE $file 6000
13788     cmp $temp $file || error "$temp $file differ (truncate1)"
13789
13790     echo "12345" >>$temp
13791     echo "12345" >>$file
13792     cmp $temp $file || error "$temp $file differ (append1)"
13793
13794     echo "12345" >>$temp
13795     echo "12345" >>$file
13796     cmp $temp $file || error "$temp $file differ (append2)"
13797
13798     rm -f $temp $file
13799     true
13800 }
13801
13802 test_155_big_load() {
13803         remote_ost_nodsh && skip "remote OST with nodsh"
13804
13805         local temp=$TMP/$tfile
13806         local file=$DIR/$tfile
13807
13808         free_min_max
13809         local cache_size=$(do_facet ost$((MAXI+1)) \
13810                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
13811         local large_file_size=$((cache_size * 2))
13812
13813         echo "OSS cache size: $cache_size KB"
13814         echo "Large file size: $large_file_size KB"
13815
13816         [ $MAXV -le $large_file_size ] &&
13817                 skip_env "max available OST size needs > $large_file_size KB"
13818
13819         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
13820
13821         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
13822                 error "dd of=$temp bs=$large_file_size count=1k failed"
13823         cp $temp $file
13824         ls -lh $temp $file
13825         cancel_lru_locks osc
13826         cmp $temp $file || error "$temp $file differ"
13827
13828         rm -f $temp $file
13829         true
13830 }
13831
13832 save_writethrough() {
13833         local facets=$(get_facets OST)
13834
13835         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
13836 }
13837
13838 test_155a() {
13839         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13840
13841         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13842
13843         save_writethrough $p
13844
13845         set_cache read on
13846         set_cache writethrough on
13847         test_155_small_load
13848         restore_lustre_params < $p
13849         rm -f $p
13850 }
13851 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
13852
13853 test_155b() {
13854         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13855
13856         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13857
13858         save_writethrough $p
13859
13860         set_cache read on
13861         set_cache writethrough off
13862         test_155_small_load
13863         restore_lustre_params < $p
13864         rm -f $p
13865 }
13866 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
13867
13868 test_155c() {
13869         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13870
13871         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13872
13873         save_writethrough $p
13874
13875         set_cache read off
13876         set_cache writethrough on
13877         test_155_small_load
13878         restore_lustre_params < $p
13879         rm -f $p
13880 }
13881 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
13882
13883 test_155d() {
13884         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13885
13886         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13887
13888         save_writethrough $p
13889
13890         set_cache read off
13891         set_cache writethrough off
13892         test_155_small_load
13893         restore_lustre_params < $p
13894         rm -f $p
13895 }
13896 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
13897
13898 test_155e() {
13899         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13900
13901         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13902
13903         save_writethrough $p
13904
13905         set_cache read on
13906         set_cache writethrough on
13907         test_155_big_load
13908         restore_lustre_params < $p
13909         rm -f $p
13910 }
13911 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
13912
13913 test_155f() {
13914         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13915
13916         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13917
13918         save_writethrough $p
13919
13920         set_cache read on
13921         set_cache writethrough off
13922         test_155_big_load
13923         restore_lustre_params < $p
13924         rm -f $p
13925 }
13926 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
13927
13928 test_155g() {
13929         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13930
13931         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13932
13933         save_writethrough $p
13934
13935         set_cache read off
13936         set_cache writethrough on
13937         test_155_big_load
13938         restore_lustre_params < $p
13939         rm -f $p
13940 }
13941 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
13942
13943 test_155h() {
13944         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13945
13946         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13947
13948         save_writethrough $p
13949
13950         set_cache read off
13951         set_cache writethrough off
13952         test_155_big_load
13953         restore_lustre_params < $p
13954         rm -f $p
13955 }
13956 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
13957
13958 test_156() {
13959         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13960         remote_ost_nodsh && skip "remote OST with nodsh"
13961         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
13962                 skip "stats not implemented on old servers"
13963         [ "$ost1_FSTYPE" = "zfs" ] &&
13964                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
13965
13966         local CPAGES=3
13967         local BEFORE
13968         local AFTER
13969         local file="$DIR/$tfile"
13970         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13971
13972         save_writethrough $p
13973         roc_hit_init
13974
13975         log "Turn on read and write cache"
13976         set_cache read on
13977         set_cache writethrough on
13978
13979         log "Write data and read it back."
13980         log "Read should be satisfied from the cache."
13981         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
13982         BEFORE=$(roc_hit)
13983         cancel_lru_locks osc
13984         cat $file >/dev/null
13985         AFTER=$(roc_hit)
13986         if ! let "AFTER - BEFORE == CPAGES"; then
13987                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
13988         else
13989                 log "cache hits: before: $BEFORE, after: $AFTER"
13990         fi
13991
13992         log "Read again; it should be satisfied from the cache."
13993         BEFORE=$AFTER
13994         cancel_lru_locks osc
13995         cat $file >/dev/null
13996         AFTER=$(roc_hit)
13997         if ! let "AFTER - BEFORE == CPAGES"; then
13998                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
13999         else
14000                 log "cache hits:: before: $BEFORE, after: $AFTER"
14001         fi
14002
14003         log "Turn off the read cache and turn on the write cache"
14004         set_cache read off
14005         set_cache writethrough on
14006
14007         log "Read again; it should be satisfied from the cache."
14008         BEFORE=$(roc_hit)
14009         cancel_lru_locks osc
14010         cat $file >/dev/null
14011         AFTER=$(roc_hit)
14012         if ! let "AFTER - BEFORE == CPAGES"; then
14013                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
14014         else
14015                 log "cache hits:: before: $BEFORE, after: $AFTER"
14016         fi
14017
14018         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14019                 # > 2.12.56 uses pagecache if cached
14020                 log "Read again; it should not be satisfied from the cache."
14021                 BEFORE=$AFTER
14022                 cancel_lru_locks osc
14023                 cat $file >/dev/null
14024                 AFTER=$(roc_hit)
14025                 if ! let "AFTER - BEFORE == 0"; then
14026                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
14027                 else
14028                         log "cache hits:: before: $BEFORE, after: $AFTER"
14029                 fi
14030         fi
14031
14032         log "Write data and read it back."
14033         log "Read should be satisfied from the cache."
14034         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14035         BEFORE=$(roc_hit)
14036         cancel_lru_locks osc
14037         cat $file >/dev/null
14038         AFTER=$(roc_hit)
14039         if ! let "AFTER - BEFORE == CPAGES"; then
14040                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
14041         else
14042                 log "cache hits:: before: $BEFORE, after: $AFTER"
14043         fi
14044
14045         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14046                 # > 2.12.56 uses pagecache if cached
14047                 log "Read again; it should not be satisfied from the cache."
14048                 BEFORE=$AFTER
14049                 cancel_lru_locks osc
14050                 cat $file >/dev/null
14051                 AFTER=$(roc_hit)
14052                 if ! let "AFTER - BEFORE == 0"; then
14053                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
14054                 else
14055                         log "cache hits:: before: $BEFORE, after: $AFTER"
14056                 fi
14057         fi
14058
14059         log "Turn off read and write cache"
14060         set_cache read off
14061         set_cache writethrough off
14062
14063         log "Write data and read it back"
14064         log "It should not be satisfied from the cache."
14065         rm -f $file
14066         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14067         cancel_lru_locks osc
14068         BEFORE=$(roc_hit)
14069         cat $file >/dev/null
14070         AFTER=$(roc_hit)
14071         if ! let "AFTER - BEFORE == 0"; then
14072                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
14073         else
14074                 log "cache hits:: before: $BEFORE, after: $AFTER"
14075         fi
14076
14077         log "Turn on the read cache and turn off the write cache"
14078         set_cache read on
14079         set_cache writethrough off
14080
14081         log "Write data and read it back"
14082         log "It should not be satisfied from the cache."
14083         rm -f $file
14084         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14085         BEFORE=$(roc_hit)
14086         cancel_lru_locks osc
14087         cat $file >/dev/null
14088         AFTER=$(roc_hit)
14089         if ! let "AFTER - BEFORE == 0"; then
14090                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
14091         else
14092                 log "cache hits:: before: $BEFORE, after: $AFTER"
14093         fi
14094
14095         log "Read again; it should be satisfied from the cache."
14096         BEFORE=$(roc_hit)
14097         cancel_lru_locks osc
14098         cat $file >/dev/null
14099         AFTER=$(roc_hit)
14100         if ! let "AFTER - BEFORE == CPAGES"; then
14101                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
14102         else
14103                 log "cache hits:: before: $BEFORE, after: $AFTER"
14104         fi
14105
14106         restore_lustre_params < $p
14107         rm -f $p $file
14108 }
14109 run_test 156 "Verification of tunables"
14110
14111 test_160a() {
14112         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14113         remote_mds_nodsh && skip "remote MDS with nodsh"
14114         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14115                 skip "Need MDS version at least 2.2.0"
14116
14117         changelog_register || error "changelog_register failed"
14118         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14119         changelog_users $SINGLEMDS | grep -q $cl_user ||
14120                 error "User $cl_user not found in changelog_users"
14121
14122         # change something
14123         test_mkdir -p $DIR/$tdir/pics/2008/zachy
14124         changelog_clear 0 || error "changelog_clear failed"
14125         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
14126         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
14127         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
14128         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
14129         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
14130         rm $DIR/$tdir/pics/desktop.jpg
14131
14132         changelog_dump | tail -10
14133
14134         echo "verifying changelog mask"
14135         changelog_chmask "-MKDIR"
14136         changelog_chmask "-CLOSE"
14137
14138         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
14139         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
14140
14141         changelog_chmask "+MKDIR"
14142         changelog_chmask "+CLOSE"
14143
14144         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
14145         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
14146
14147         changelog_dump | tail -10
14148         MKDIRS=$(changelog_dump | grep -c "MKDIR")
14149         CLOSES=$(changelog_dump | grep -c "CLOSE")
14150         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
14151         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
14152
14153         # verify contents
14154         echo "verifying target fid"
14155         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
14156         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
14157         [ "$fidc" == "$fidf" ] ||
14158                 error "changelog '$tfile' fid $fidc != file fid $fidf"
14159         echo "verifying parent fid"
14160         # The FID returned from the Changelog may be the directory shard on
14161         # a different MDT, and not the FID returned by path2fid on the parent.
14162         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
14163         # since this is what will matter when recreating this file in the tree.
14164         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
14165         local pathp=$($LFS fid2path $MOUNT "$fidp")
14166         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
14167                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
14168
14169         echo "getting records for $cl_user"
14170         changelog_users $SINGLEMDS
14171         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
14172         local nclr=3
14173         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
14174                 error "changelog_clear failed"
14175         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
14176         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
14177         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
14178                 error "user index expect $user_rec1 + $nclr != $user_rec2"
14179
14180         local min0_rec=$(changelog_users $SINGLEMDS |
14181                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
14182         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
14183                           awk '{ print $1; exit; }')
14184
14185         changelog_dump | tail -n 5
14186         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
14187         [ $first_rec == $((min0_rec + 1)) ] ||
14188                 error "first index should be $min0_rec + 1 not $first_rec"
14189
14190         # LU-3446 changelog index reset on MDT restart
14191         local cur_rec1=$(changelog_users $SINGLEMDS |
14192                          awk '/^current.index:/ { print $NF }')
14193         changelog_clear 0 ||
14194                 error "clear all changelog records for $cl_user failed"
14195         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
14196         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
14197                 error "Fail to start $SINGLEMDS"
14198         local cur_rec2=$(changelog_users $SINGLEMDS |
14199                          awk '/^current.index:/ { print $NF }')
14200         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
14201         [ $cur_rec1 == $cur_rec2 ] ||
14202                 error "current index should be $cur_rec1 not $cur_rec2"
14203
14204         echo "verifying users from this test are deregistered"
14205         changelog_deregister || error "changelog_deregister failed"
14206         changelog_users $SINGLEMDS | grep -q $cl_user &&
14207                 error "User '$cl_user' still in changelog_users"
14208
14209         # lctl get_param -n mdd.*.changelog_users
14210         # current index: 144
14211         # ID    index (idle seconds)
14212         # cl3   144 (2)
14213         if ! changelog_users $SINGLEMDS | grep "^cl"; then
14214                 # this is the normal case where all users were deregistered
14215                 # make sure no new records are added when no users are present
14216                 local last_rec1=$(changelog_users $SINGLEMDS |
14217                                   awk '/^current.index:/ { print $NF }')
14218                 touch $DIR/$tdir/chloe
14219                 local last_rec2=$(changelog_users $SINGLEMDS |
14220                                   awk '/^current.index:/ { print $NF }')
14221                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
14222                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
14223         else
14224                 # any changelog users must be leftovers from a previous test
14225                 changelog_users $SINGLEMDS
14226                 echo "other changelog users; can't verify off"
14227         fi
14228 }
14229 run_test 160a "changelog sanity"
14230
14231 test_160b() { # LU-3587
14232         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14233         remote_mds_nodsh && skip "remote MDS with nodsh"
14234         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14235                 skip "Need MDS version at least 2.2.0"
14236
14237         changelog_register || error "changelog_register failed"
14238         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14239         changelog_users $SINGLEMDS | grep -q $cl_user ||
14240                 error "User '$cl_user' not found in changelog_users"
14241
14242         local longname1=$(str_repeat a 255)
14243         local longname2=$(str_repeat b 255)
14244
14245         cd $DIR
14246         echo "creating very long named file"
14247         touch $longname1 || error "create of '$longname1' failed"
14248         echo "renaming very long named file"
14249         mv $longname1 $longname2
14250
14251         changelog_dump | grep RENME | tail -n 5
14252         rm -f $longname2
14253 }
14254 run_test 160b "Verify that very long rename doesn't crash in changelog"
14255
14256 test_160c() {
14257         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14258         remote_mds_nodsh && skip "remote MDS with nodsh"
14259
14260         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
14261                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
14262                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
14263                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
14264
14265         local rc=0
14266
14267         # Registration step
14268         changelog_register || error "changelog_register failed"
14269
14270         rm -rf $DIR/$tdir
14271         mkdir -p $DIR/$tdir
14272         $MCREATE $DIR/$tdir/foo_160c
14273         changelog_chmask "-TRUNC"
14274         $TRUNCATE $DIR/$tdir/foo_160c 200
14275         changelog_chmask "+TRUNC"
14276         $TRUNCATE $DIR/$tdir/foo_160c 199
14277         changelog_dump | tail -n 5
14278         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
14279         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
14280 }
14281 run_test 160c "verify that changelog log catch the truncate event"
14282
14283 test_160d() {
14284         remote_mds_nodsh && skip "remote MDS with nodsh"
14285         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14286         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14287         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
14288                 skip "Need MDS version at least 2.7.60"
14289
14290         # Registration step
14291         changelog_register || error "changelog_register failed"
14292
14293         mkdir -p $DIR/$tdir/migrate_dir
14294         changelog_clear 0 || error "changelog_clear failed"
14295
14296         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
14297         changelog_dump | tail -n 5
14298         local migrates=$(changelog_dump | grep -c "MIGRT")
14299         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
14300 }
14301 run_test 160d "verify that changelog log catch the migrate event"
14302
14303 test_160e() {
14304         remote_mds_nodsh && skip "remote MDS with nodsh"
14305
14306         # Create a user
14307         changelog_register || error "changelog_register failed"
14308
14309         # Delete a future user (expect fail)
14310         local MDT0=$(facet_svc $SINGLEMDS)
14311         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
14312         local rc=$?
14313
14314         if [ $rc -eq 0 ]; then
14315                 error "Deleted non-existant user cl77"
14316         elif [ $rc -ne 2 ]; then
14317                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
14318         fi
14319
14320         # Clear to a bad index (1 billion should be safe)
14321         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
14322         rc=$?
14323
14324         if [ $rc -eq 0 ]; then
14325                 error "Successfully cleared to invalid CL index"
14326         elif [ $rc -ne 22 ]; then
14327                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
14328         fi
14329 }
14330 run_test 160e "changelog negative testing (should return errors)"
14331
14332 test_160f() {
14333         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14334         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14335                 skip "Need MDS version at least 2.10.56"
14336
14337         local mdts=$(comma_list $(mdts_nodes))
14338
14339         # Create a user
14340         changelog_register || error "first changelog_register failed"
14341         changelog_register || error "second changelog_register failed"
14342         local cl_users
14343         declare -A cl_user1
14344         declare -A cl_user2
14345         local user_rec1
14346         local user_rec2
14347         local i
14348
14349         # generate some changelog records to accumulate on each MDT
14350         # use fnv1a because created files should be evenly distributed
14351         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14352                 error "test_mkdir $tdir failed"
14353         log "$(date +%s): creating first files"
14354         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14355                 error "create $DIR/$tdir/$tfile failed"
14356
14357         # check changelogs have been generated
14358         local start=$SECONDS
14359         local idle_time=$((MDSCOUNT * 5 + 5))
14360         local nbcl=$(changelog_dump | wc -l)
14361         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14362
14363         for param in "changelog_max_idle_time=$idle_time" \
14364                      "changelog_gc=1" \
14365                      "changelog_min_gc_interval=2" \
14366                      "changelog_min_free_cat_entries=3"; do
14367                 local MDT0=$(facet_svc $SINGLEMDS)
14368                 local var="${param%=*}"
14369                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14370
14371                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14372                 do_nodes $mdts $LCTL set_param mdd.*.$param
14373         done
14374
14375         # force cl_user2 to be idle (1st part), but also cancel the
14376         # cl_user1 records so that it is not evicted later in the test.
14377         local sleep1=$((idle_time / 2))
14378         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
14379         sleep $sleep1
14380
14381         # simulate changelog catalog almost full
14382         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
14383         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
14384
14385         for i in $(seq $MDSCOUNT); do
14386                 cl_users=(${CL_USERS[mds$i]})
14387                 cl_user1[mds$i]="${cl_users[0]}"
14388                 cl_user2[mds$i]="${cl_users[1]}"
14389
14390                 [ -n "${cl_user1[mds$i]}" ] ||
14391                         error "mds$i: no user registered"
14392                 [ -n "${cl_user2[mds$i]}" ] ||
14393                         error "mds$i: only ${cl_user2[mds$i]} is registered"
14394
14395                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14396                 [ -n "$user_rec1" ] ||
14397                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14398                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14399                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14400                 [ -n "$user_rec2" ] ||
14401                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14402                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14403                      "$user_rec1 + 2 == $user_rec2"
14404                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14405                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14406                               "$user_rec1 + 2, but is $user_rec2"
14407                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14408                 [ -n "$user_rec2" ] ||
14409                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14410                 [ $user_rec1 == $user_rec2 ] ||
14411                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14412                               "$user_rec1, but is $user_rec2"
14413         done
14414
14415         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
14416         local sleep2=$((idle_time - (SECONDS - start) + 1))
14417         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
14418         sleep $sleep2
14419
14420         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
14421         # cl_user1 should be OK because it recently processed records.
14422         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
14423         createmany -m $DIR/$tdir/${tfile}b $((MDSCOUNT * 2)) ||
14424                 error "create $DIR/$tdir/${tfile}b failed"
14425
14426         # ensure gc thread is done
14427         for i in $(mdts_nodes); do
14428                 wait_update $i \
14429                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
14430                         error "$i: GC-thread not done"
14431         done
14432
14433         local first_rec
14434         for i in $(seq $MDSCOUNT); do
14435                 # check cl_user1 still registered
14436                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14437                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14438                 # check cl_user2 unregistered
14439                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14440                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14441
14442                 # check changelogs are present and starting at $user_rec1 + 1
14443                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14444                 [ -n "$user_rec1" ] ||
14445                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14446                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14447                             awk '{ print $1; exit; }')
14448
14449                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14450                 [ $((user_rec1 + 1)) == $first_rec ] ||
14451                         error "mds$i: first index should be $user_rec1 + 1, " \
14452                               "but is $first_rec"
14453         done
14454 }
14455 run_test 160f "changelog garbage collect (timestamped users)"
14456
14457 test_160g() {
14458         remote_mds_nodsh && skip "remote MDS with nodsh"
14459         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14460                 skip "Need MDS version at least 2.10.56"
14461
14462         local mdts=$(comma_list $(mdts_nodes))
14463
14464         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
14465         do_nodes $mdts $LCTL set_param fail_loc=0x1314
14466
14467         # Create a user
14468         changelog_register || error "first changelog_register failed"
14469         changelog_register || error "second changelog_register failed"
14470         local cl_users
14471         declare -A cl_user1
14472         declare -A cl_user2
14473         local user_rec1
14474         local user_rec2
14475         local i
14476
14477         # generate some changelog records to accumulate on each MDT
14478         # use fnv1a because created files should be evenly distributed
14479         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14480                 error "mkdir $tdir failed"
14481         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14482                 error "create $DIR/$tdir/$tfile failed"
14483
14484         # check changelogs have been generated
14485         local nbcl=$(changelog_dump | wc -l)
14486         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14487
14488         # reduce the max_idle_indexes value to make sure we exceed it
14489         max_ndx=$((nbcl / 2 - 1))
14490
14491         for param in "changelog_max_idle_indexes=$max_ndx" \
14492                      "changelog_gc=1" \
14493                      "changelog_min_gc_interval=2" \
14494                      "changelog_min_free_cat_entries=3"; do
14495                 local MDT0=$(facet_svc $SINGLEMDS)
14496                 local var="${param%=*}"
14497                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14498
14499                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14500                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
14501                         error "unable to set mdd.*.$param"
14502         done
14503
14504         # simulate changelog catalog almost full
14505         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
14506         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
14507
14508         for i in $(seq $MDSCOUNT); do
14509                 cl_users=(${CL_USERS[mds$i]})
14510                 cl_user1[mds$i]="${cl_users[0]}"
14511                 cl_user2[mds$i]="${cl_users[1]}"
14512
14513                 [ -n "${cl_user1[mds$i]}" ] ||
14514                         error "mds$i: no user registered"
14515                 [ -n "${cl_user2[mds$i]}" ] ||
14516                         error "mds$i: only ${cl_user1[mds$i]} is registered"
14517
14518                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14519                 [ -n "$user_rec1" ] ||
14520                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14521                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14522                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14523                 [ -n "$user_rec2" ] ||
14524                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14525                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14526                      "$user_rec1 + 2 == $user_rec2"
14527                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14528                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14529                               "$user_rec1 + 2, but is $user_rec2"
14530                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14531                 [ -n "$user_rec2" ] ||
14532                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14533                 [ $user_rec1 == $user_rec2 ] ||
14534                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14535                               "$user_rec1, but is $user_rec2"
14536         done
14537
14538         # ensure we are past the previous changelog_min_gc_interval set above
14539         sleep 2
14540
14541         # generate one more changelog to trigger fail_loc
14542         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14543                 error "create $DIR/$tdir/${tfile}bis failed"
14544
14545         # ensure gc thread is done
14546         for i in $(mdts_nodes); do
14547                 wait_update $i \
14548                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
14549                         error "$i: GC-thread not done"
14550         done
14551
14552         local first_rec
14553         for i in $(seq $MDSCOUNT); do
14554                 # check cl_user1 still registered
14555                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14556                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14557                 # check cl_user2 unregistered
14558                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14559                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14560
14561                 # check changelogs are present and starting at $user_rec1 + 1
14562                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14563                 [ -n "$user_rec1" ] ||
14564                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14565                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14566                             awk '{ print $1; exit; }')
14567
14568                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14569                 [ $((user_rec1 + 1)) == $first_rec ] ||
14570                         error "mds$i: first index should be $user_rec1 + 1, " \
14571                               "but is $first_rec"
14572         done
14573 }
14574 run_test 160g "changelog garbage collect (old users)"
14575
14576 test_160h() {
14577         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14578         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14579                 skip "Need MDS version at least 2.10.56"
14580
14581         local mdts=$(comma_list $(mdts_nodes))
14582
14583         # Create a user
14584         changelog_register || error "first changelog_register failed"
14585         changelog_register || error "second changelog_register failed"
14586         local cl_users
14587         declare -A cl_user1
14588         declare -A cl_user2
14589         local user_rec1
14590         local user_rec2
14591         local i
14592
14593         # generate some changelog records to accumulate on each MDT
14594         # use fnv1a because created files should be evenly distributed
14595         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14596                 error "test_mkdir $tdir failed"
14597         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14598                 error "create $DIR/$tdir/$tfile failed"
14599
14600         # check changelogs have been generated
14601         local nbcl=$(changelog_dump | wc -l)
14602         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14603
14604         for param in "changelog_max_idle_time=10" \
14605                      "changelog_gc=1" \
14606                      "changelog_min_gc_interval=2"; do
14607                 local MDT0=$(facet_svc $SINGLEMDS)
14608                 local var="${param%=*}"
14609                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14610
14611                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14612                 do_nodes $mdts $LCTL set_param mdd.*.$param
14613         done
14614
14615         # force cl_user2 to be idle (1st part)
14616         sleep 9
14617
14618         for i in $(seq $MDSCOUNT); do
14619                 cl_users=(${CL_USERS[mds$i]})
14620                 cl_user1[mds$i]="${cl_users[0]}"
14621                 cl_user2[mds$i]="${cl_users[1]}"
14622
14623                 [ -n "${cl_user1[mds$i]}" ] ||
14624                         error "mds$i: no user registered"
14625                 [ -n "${cl_user2[mds$i]}" ] ||
14626                         error "mds$i: only ${cl_user2[mds$i]} is registered"
14627
14628                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14629                 [ -n "$user_rec1" ] ||
14630                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14631                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14632                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14633                 [ -n "$user_rec2" ] ||
14634                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14635                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14636                      "$user_rec1 + 2 == $user_rec2"
14637                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14638                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14639                               "$user_rec1 + 2, but is $user_rec2"
14640                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14641                 [ -n "$user_rec2" ] ||
14642                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14643                 [ $user_rec1 == $user_rec2 ] ||
14644                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14645                               "$user_rec1, but is $user_rec2"
14646         done
14647
14648         # force cl_user2 to be idle (2nd part) and to reach
14649         # changelog_max_idle_time
14650         sleep 2
14651
14652         # force each GC-thread start and block then
14653         # one per MDT/MDD, set fail_val accordingly
14654         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
14655         do_nodes $mdts $LCTL set_param fail_loc=0x1316
14656
14657         # generate more changelogs to trigger fail_loc
14658         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14659                 error "create $DIR/$tdir/${tfile}bis failed"
14660
14661         # stop MDT to stop GC-thread, should be done in back-ground as it will
14662         # block waiting for the thread to be released and exit
14663         declare -A stop_pids
14664         for i in $(seq $MDSCOUNT); do
14665                 stop mds$i &
14666                 stop_pids[mds$i]=$!
14667         done
14668
14669         for i in $(mdts_nodes); do
14670                 local facet
14671                 local nb=0
14672                 local facets=$(facets_up_on_host $i)
14673
14674                 for facet in ${facets//,/ }; do
14675                         if [[ $facet == mds* ]]; then
14676                                 nb=$((nb + 1))
14677                         fi
14678                 done
14679                 # ensure each MDS's gc threads are still present and all in "R"
14680                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
14681                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
14682                         error "$i: expected $nb GC-thread"
14683                 wait_update $i \
14684                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
14685                         "R" 20 ||
14686                         error "$i: GC-thread not found in R-state"
14687                 # check umounts of each MDT on MDS have reached kthread_stop()
14688                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
14689                         error "$i: expected $nb umount"
14690                 wait_update $i \
14691                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
14692                         error "$i: umount not found in D-state"
14693         done
14694
14695         # release all GC-threads
14696         do_nodes $mdts $LCTL set_param fail_loc=0
14697
14698         # wait for MDT stop to complete
14699         for i in $(seq $MDSCOUNT); do
14700                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
14701         done
14702
14703         # XXX
14704         # may try to check if any orphan changelog records are present
14705         # via ldiskfs/zfs and llog_reader...
14706
14707         # re-start/mount MDTs
14708         for i in $(seq $MDSCOUNT); do
14709                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
14710                         error "Fail to start mds$i"
14711         done
14712
14713         local first_rec
14714         for i in $(seq $MDSCOUNT); do
14715                 # check cl_user1 still registered
14716                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14717                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14718                 # check cl_user2 unregistered
14719                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14720                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14721
14722                 # check changelogs are present and starting at $user_rec1 + 1
14723                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14724                 [ -n "$user_rec1" ] ||
14725                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14726                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14727                             awk '{ print $1; exit; }')
14728
14729                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14730                 [ $((user_rec1 + 1)) == $first_rec ] ||
14731                         error "mds$i: first index should be $user_rec1 + 1, " \
14732                               "but is $first_rec"
14733         done
14734 }
14735 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
14736               "during mount"
14737
14738 test_160i() {
14739
14740         local mdts=$(comma_list $(mdts_nodes))
14741
14742         changelog_register || error "first changelog_register failed"
14743
14744         # generate some changelog records to accumulate on each MDT
14745         # use fnv1a because created files should be evenly distributed
14746         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14747                 error "mkdir $tdir failed"
14748         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14749                 error "create $DIR/$tdir/$tfile failed"
14750
14751         # check changelogs have been generated
14752         local nbcl=$(changelog_dump | wc -l)
14753         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14754
14755         # simulate race between register and unregister
14756         # XXX as fail_loc is set per-MDS, with DNE configs the race
14757         # simulation will only occur for one MDT per MDS and for the
14758         # others the normal race scenario will take place
14759         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
14760         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
14761         do_nodes $mdts $LCTL set_param fail_val=1
14762
14763         # unregister 1st user
14764         changelog_deregister &
14765         local pid1=$!
14766         # wait some time for deregister work to reach race rdv
14767         sleep 2
14768         # register 2nd user
14769         changelog_register || error "2nd user register failed"
14770
14771         wait $pid1 || error "1st user deregister failed"
14772
14773         local i
14774         local last_rec
14775         declare -A LAST_REC
14776         for i in $(seq $MDSCOUNT); do
14777                 if changelog_users mds$i | grep "^cl"; then
14778                         # make sure new records are added with one user present
14779                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
14780                                           awk '/^current.index:/ { print $NF }')
14781                 else
14782                         error "mds$i has no user registered"
14783                 fi
14784         done
14785
14786         # generate more changelog records to accumulate on each MDT
14787         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14788                 error "create $DIR/$tdir/${tfile}bis failed"
14789
14790         for i in $(seq $MDSCOUNT); do
14791                 last_rec=$(changelog_users $SINGLEMDS |
14792                            awk '/^current.index:/ { print $NF }')
14793                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
14794                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
14795                         error "changelogs are off on mds$i"
14796         done
14797 }
14798 run_test 160i "changelog user register/unregister race"
14799
14800 test_160j() {
14801         remote_mds_nodsh && skip "remote MDS with nodsh"
14802         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
14803                 skip "Need MDS version at least 2.12.56"
14804
14805         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
14806         stack_trap "umount $MOUNT2" EXIT
14807
14808         changelog_register || error "first changelog_register failed"
14809         stack_trap "changelog_deregister" EXIT
14810
14811         # generate some changelog
14812         # use fnv1a because created files should be evenly distributed
14813         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14814                 error "mkdir $tdir failed"
14815         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14816                 error "create $DIR/$tdir/${tfile}bis failed"
14817
14818         # open the changelog device
14819         exec 3>/dev/changelog-$FSNAME-MDT0000
14820         stack_trap "exec 3>&-" EXIT
14821         exec 4</dev/changelog-$FSNAME-MDT0000
14822         stack_trap "exec 4<&-" EXIT
14823
14824         # umount the first lustre mount
14825         umount $MOUNT
14826         stack_trap "mount_client $MOUNT" EXIT
14827
14828         # read changelog
14829         cat <&4 >/dev/null || error "read changelog failed"
14830
14831         # clear changelog
14832         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14833         changelog_users $SINGLEMDS | grep -q $cl_user ||
14834                 error "User $cl_user not found in changelog_users"
14835
14836         printf 'clear:'$cl_user':0' >&3
14837 }
14838 run_test 160j "client can be umounted  while its chanangelog is being used"
14839
14840 test_160k() {
14841         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14842         remote_mds_nodsh && skip "remote MDS with nodsh"
14843
14844         mkdir -p $DIR/$tdir/1/1
14845
14846         changelog_register || error "changelog_register failed"
14847         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14848
14849         changelog_users $SINGLEMDS | grep -q $cl_user ||
14850                 error "User '$cl_user' not found in changelog_users"
14851 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
14852         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
14853         rmdir $DIR/$tdir/1/1 & sleep 1
14854         mkdir $DIR/$tdir/2
14855         touch $DIR/$tdir/2/2
14856         rm -rf $DIR/$tdir/2
14857
14858         wait
14859         sleep 4
14860
14861         changelog_dump | grep rmdir || error "rmdir not recorded"
14862
14863         rm -rf $DIR/$tdir
14864         changelog_deregister
14865 }
14866 run_test 160k "Verify that changelog records are not lost"
14867
14868 test_161a() {
14869         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14870
14871         test_mkdir -c1 $DIR/$tdir
14872         cp /etc/hosts $DIR/$tdir/$tfile
14873         test_mkdir -c1 $DIR/$tdir/foo1
14874         test_mkdir -c1 $DIR/$tdir/foo2
14875         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
14876         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
14877         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
14878         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
14879         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
14880         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
14881                 $LFS fid2path $DIR $FID
14882                 error "bad link ea"
14883         fi
14884         # middle
14885         rm $DIR/$tdir/foo2/zachary
14886         # last
14887         rm $DIR/$tdir/foo2/thor
14888         # first
14889         rm $DIR/$tdir/$tfile
14890         # rename
14891         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
14892         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
14893                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
14894         rm $DIR/$tdir/foo2/maggie
14895
14896         # overflow the EA
14897         local longname=$tfile.avg_len_is_thirty_two_
14898         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
14899                 error_noexit 'failed to unlink many hardlinks'" EXIT
14900         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
14901                 error "failed to hardlink many files"
14902         links=$($LFS fid2path $DIR $FID | wc -l)
14903         echo -n "${links}/1000 links in link EA"
14904         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
14905 }
14906 run_test 161a "link ea sanity"
14907
14908 test_161b() {
14909         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14910         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
14911
14912         local MDTIDX=1
14913         local remote_dir=$DIR/$tdir/remote_dir
14914
14915         mkdir -p $DIR/$tdir
14916         $LFS mkdir -i $MDTIDX $remote_dir ||
14917                 error "create remote directory failed"
14918
14919         cp /etc/hosts $remote_dir/$tfile
14920         mkdir -p $remote_dir/foo1
14921         mkdir -p $remote_dir/foo2
14922         ln $remote_dir/$tfile $remote_dir/foo1/sofia
14923         ln $remote_dir/$tfile $remote_dir/foo2/zachary
14924         ln $remote_dir/$tfile $remote_dir/foo1/luna
14925         ln $remote_dir/$tfile $remote_dir/foo2/thor
14926
14927         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
14928                      tr -d ']')
14929         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
14930                 $LFS fid2path $DIR $FID
14931                 error "bad link ea"
14932         fi
14933         # middle
14934         rm $remote_dir/foo2/zachary
14935         # last
14936         rm $remote_dir/foo2/thor
14937         # first
14938         rm $remote_dir/$tfile
14939         # rename
14940         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
14941         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
14942         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
14943                 $LFS fid2path $DIR $FID
14944                 error "bad link rename"
14945         fi
14946         rm $remote_dir/foo2/maggie
14947
14948         # overflow the EA
14949         local longname=filename_avg_len_is_thirty_two_
14950         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
14951                 error "failed to hardlink many files"
14952         links=$($LFS fid2path $DIR $FID | wc -l)
14953         echo -n "${links}/1000 links in link EA"
14954         [[ ${links} -gt 60 ]] ||
14955                 error "expected at least 60 links in link EA"
14956         unlinkmany $remote_dir/foo2/$longname 1000 ||
14957         error "failed to unlink many hardlinks"
14958 }
14959 run_test 161b "link ea sanity under remote directory"
14960
14961 test_161c() {
14962         remote_mds_nodsh && skip "remote MDS with nodsh"
14963         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14964         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
14965                 skip "Need MDS version at least 2.1.5"
14966
14967         # define CLF_RENAME_LAST 0x0001
14968         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
14969         changelog_register || error "changelog_register failed"
14970
14971         rm -rf $DIR/$tdir
14972         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
14973         touch $DIR/$tdir/foo_161c
14974         touch $DIR/$tdir/bar_161c
14975         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
14976         changelog_dump | grep RENME | tail -n 5
14977         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
14978         changelog_clear 0 || error "changelog_clear failed"
14979         if [ x$flags != "x0x1" ]; then
14980                 error "flag $flags is not 0x1"
14981         fi
14982
14983         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
14984         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
14985         touch $DIR/$tdir/foo_161c
14986         touch $DIR/$tdir/bar_161c
14987         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
14988         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
14989         changelog_dump | grep RENME | tail -n 5
14990         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
14991         changelog_clear 0 || error "changelog_clear failed"
14992         if [ x$flags != "x0x0" ]; then
14993                 error "flag $flags is not 0x0"
14994         fi
14995         echo "rename overwrite a target having nlink > 1," \
14996                 "changelog record has flags of $flags"
14997
14998         # rename doesn't overwrite a target (changelog flag 0x0)
14999         touch $DIR/$tdir/foo_161c
15000         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
15001         changelog_dump | grep RENME | tail -n 5
15002         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
15003         changelog_clear 0 || error "changelog_clear failed"
15004         if [ x$flags != "x0x0" ]; then
15005                 error "flag $flags is not 0x0"
15006         fi
15007         echo "rename doesn't overwrite a target," \
15008                 "changelog record has flags of $flags"
15009
15010         # define CLF_UNLINK_LAST 0x0001
15011         # unlink a file having nlink = 1 (changelog flag 0x1)
15012         rm -f $DIR/$tdir/foo2_161c
15013         changelog_dump | grep UNLNK | tail -n 5
15014         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15015         changelog_clear 0 || error "changelog_clear failed"
15016         if [ x$flags != "x0x1" ]; then
15017                 error "flag $flags is not 0x1"
15018         fi
15019         echo "unlink a file having nlink = 1," \
15020                 "changelog record has flags of $flags"
15021
15022         # unlink a file having nlink > 1 (changelog flag 0x0)
15023         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15024         rm -f $DIR/$tdir/foobar_161c
15025         changelog_dump | grep UNLNK | tail -n 5
15026         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15027         changelog_clear 0 || error "changelog_clear failed"
15028         if [ x$flags != "x0x0" ]; then
15029                 error "flag $flags is not 0x0"
15030         fi
15031         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
15032 }
15033 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
15034
15035 test_161d() {
15036         remote_mds_nodsh && skip "remote MDS with nodsh"
15037         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
15038
15039         local pid
15040         local fid
15041
15042         changelog_register || error "changelog_register failed"
15043
15044         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
15045         # interfer with $MOUNT/.lustre/fid/ access
15046         mkdir $DIR/$tdir
15047         [[ $? -eq 0 ]] || error "mkdir failed"
15048
15049         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
15050         $LCTL set_param fail_loc=0x8000140c
15051         # 5s pause
15052         $LCTL set_param fail_val=5
15053
15054         # create file
15055         echo foofoo > $DIR/$tdir/$tfile &
15056         pid=$!
15057
15058         # wait for create to be delayed
15059         sleep 2
15060
15061         ps -p $pid
15062         [[ $? -eq 0 ]] || error "create should be blocked"
15063
15064         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
15065         stack_trap "rm -f $tempfile"
15066         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
15067         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
15068         # some delay may occur during ChangeLog publishing and file read just
15069         # above, that could allow file write to happen finally
15070         [[ -s $tempfile ]] && echo "file should be empty"
15071
15072         $LCTL set_param fail_loc=0
15073
15074         wait $pid
15075         [[ $? -eq 0 ]] || error "create failed"
15076 }
15077 run_test 161d "create with concurrent .lustre/fid access"
15078
15079 check_path() {
15080         local expected="$1"
15081         shift
15082         local fid="$2"
15083
15084         local path
15085         path=$($LFS fid2path "$@")
15086         local rc=$?
15087
15088         if [ $rc -ne 0 ]; then
15089                 error "path looked up of '$expected' failed: rc=$rc"
15090         elif [ "$path" != "$expected" ]; then
15091                 error "path looked up '$path' instead of '$expected'"
15092         else
15093                 echo "FID '$fid' resolves to path '$path' as expected"
15094         fi
15095 }
15096
15097 test_162a() { # was test_162
15098         test_mkdir -p -c1 $DIR/$tdir/d2
15099         touch $DIR/$tdir/d2/$tfile
15100         touch $DIR/$tdir/d2/x1
15101         touch $DIR/$tdir/d2/x2
15102         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
15103         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
15104         # regular file
15105         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
15106         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
15107
15108         # softlink
15109         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
15110         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
15111         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
15112
15113         # softlink to wrong file
15114         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
15115         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
15116         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
15117
15118         # hardlink
15119         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
15120         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
15121         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
15122         # fid2path dir/fsname should both work
15123         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
15124         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
15125
15126         # hardlink count: check that there are 2 links
15127         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
15128         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
15129
15130         # hardlink indexing: remove the first link
15131         rm $DIR/$tdir/d2/p/q/r/hlink
15132         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
15133 }
15134 run_test 162a "path lookup sanity"
15135
15136 test_162b() {
15137         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15138         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15139
15140         mkdir $DIR/$tdir
15141         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
15142                                 error "create striped dir failed"
15143
15144         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
15145                                         tail -n 1 | awk '{print $2}')
15146         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
15147
15148         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
15149         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
15150
15151         # regular file
15152         for ((i=0;i<5;i++)); do
15153                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
15154                         error "get fid for f$i failed"
15155                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
15156
15157                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
15158                         error "get fid for d$i failed"
15159                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
15160         done
15161
15162         return 0
15163 }
15164 run_test 162b "striped directory path lookup sanity"
15165
15166 # LU-4239: Verify fid2path works with paths 100 or more directories deep
15167 test_162c() {
15168         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
15169                 skip "Need MDS version at least 2.7.51"
15170
15171         local lpath=$tdir.local
15172         local rpath=$tdir.remote
15173
15174         test_mkdir $DIR/$lpath
15175         test_mkdir $DIR/$rpath
15176
15177         for ((i = 0; i <= 101; i++)); do
15178                 lpath="$lpath/$i"
15179                 mkdir $DIR/$lpath
15180                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
15181                         error "get fid for local directory $DIR/$lpath failed"
15182                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
15183
15184                 rpath="$rpath/$i"
15185                 test_mkdir $DIR/$rpath
15186                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
15187                         error "get fid for remote directory $DIR/$rpath failed"
15188                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
15189         done
15190
15191         return 0
15192 }
15193 run_test 162c "fid2path works with paths 100 or more directories deep"
15194
15195 oalr_event_count() {
15196         local event="${1}"
15197         local trace="${2}"
15198
15199         awk -v name="${FSNAME}-OST0000" \
15200             -v event="${event}" \
15201             '$1 == "TRACE" && $2 == event && $3 == name' \
15202             "${trace}" |
15203         wc -l
15204 }
15205
15206 oalr_expect_event_count() {
15207         local event="${1}"
15208         local trace="${2}"
15209         local expect="${3}"
15210         local count
15211
15212         count=$(oalr_event_count "${event}" "${trace}")
15213         if ((count == expect)); then
15214                 return 0
15215         fi
15216
15217         error_noexit "${event} event count was '${count}', expected ${expect}"
15218         cat "${trace}" >&2
15219         exit 1
15220 }
15221
15222 cleanup_165() {
15223         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
15224         stop ost1
15225         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
15226 }
15227
15228 setup_165() {
15229         sync # Flush previous IOs so we can count log entries.
15230         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
15231         stack_trap cleanup_165 EXIT
15232 }
15233
15234 test_165a() {
15235         local trace="/tmp/${tfile}.trace"
15236         local rc
15237         local count
15238
15239         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15240         setup_165
15241         sleep 5
15242
15243         do_facet ost1 ofd_access_log_reader --list
15244         stop ost1
15245
15246         do_facet ost1 killall -TERM ofd_access_log_reader
15247         wait
15248         rc=$?
15249
15250         if ((rc != 0)); then
15251                 error "ofd_access_log_reader exited with rc = '${rc}'"
15252         fi
15253
15254         # Parse trace file for discovery events:
15255         oalr_expect_event_count alr_log_add "${trace}" 1
15256         oalr_expect_event_count alr_log_eof "${trace}" 1
15257         oalr_expect_event_count alr_log_free "${trace}" 1
15258 }
15259 run_test 165a "ofd access log discovery"
15260
15261 test_165b() {
15262         local trace="/tmp/${tfile}.trace"
15263         local file="${DIR}/${tfile}"
15264         local pfid1
15265         local pfid2
15266         local -a entry
15267         local rc
15268         local count
15269         local size
15270         local flags
15271
15272         setup_165
15273
15274         lfs setstripe -c 1 -i 0 "${file}"
15275         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15276         do_facet ost1 ofd_access_log_reader --list
15277
15278         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15279         sleep 5
15280         do_facet ost1 killall -TERM ofd_access_log_reader
15281         wait
15282         rc=$?
15283
15284         if ((rc != 0)); then
15285                 error "ofd_access_log_reader exited with rc = '${rc}'"
15286         fi
15287
15288         oalr_expect_event_count alr_log_entry "${trace}" 1
15289
15290         pfid1=$($LFS path2fid "${file}")
15291
15292         # 1     2             3   4    5     6   7    8    9     10
15293         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
15294         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
15295
15296         echo "entry = '${entry[*]}'" >&2
15297
15298         pfid2=${entry[4]}
15299         if [[ "${pfid1}" != "${pfid2}" ]]; then
15300                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
15301         fi
15302
15303         size=${entry[8]}
15304         if ((size != 1048576)); then
15305                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
15306         fi
15307
15308         flags=${entry[10]}
15309         if [[ "${flags}" != "w" ]]; then
15310                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
15311         fi
15312
15313         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15314         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c || error "cannot read '${file}'"
15315         sleep 5
15316         do_facet ost1 killall -TERM ofd_access_log_reader
15317         wait
15318         rc=$?
15319
15320         if ((rc != 0)); then
15321                 error "ofd_access_log_reader exited with rc = '${rc}'"
15322         fi
15323
15324         oalr_expect_event_count alr_log_entry "${trace}" 1
15325
15326         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
15327         echo "entry = '${entry[*]}'" >&2
15328
15329         pfid2=${entry[4]}
15330         if [[ "${pfid1}" != "${pfid2}" ]]; then
15331                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
15332         fi
15333
15334         size=${entry[8]}
15335         if ((size != 524288)); then
15336                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
15337         fi
15338
15339         flags=${entry[10]}
15340         if [[ "${flags}" != "r" ]]; then
15341                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
15342         fi
15343 }
15344 run_test 165b "ofd access log entries are produced and consumed"
15345
15346 test_165c() {
15347         local file="${DIR}/${tdir}/${tfile}"
15348         test_mkdir "${DIR}/${tdir}"
15349
15350         setup_165
15351
15352         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
15353
15354         # 4096 / 64 = 64. Create twice as many entries.
15355         for ((i = 0; i < 128; i++)); do
15356                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c || error "cannot create file"
15357         done
15358
15359         sync
15360         do_facet ost1 ofd_access_log_reader --list
15361         unlinkmany  "${file}-%d" 128
15362 }
15363 run_test 165c "full ofd access logs do not block IOs"
15364
15365 oal_peek_entry_count() {
15366         do_facet ost1 ofd_access_log_reader --list | awk '$1 == "_entry_count:" { print $2; }'
15367 }
15368
15369 oal_expect_entry_count() {
15370         local entry_count=$(oal_peek_entry_count)
15371         local expect="$1"
15372
15373         if ((entry_count == expect)); then
15374                 return 0
15375         fi
15376
15377         error_noexit "bad entry count, got ${entry_count}, expected ${expect}"
15378         do_facet ost1 ofd_access_log_reader --list >&2
15379         exit 1
15380 }
15381
15382 test_165d() {
15383         local trace="/tmp/${tfile}.trace"
15384         local file="${DIR}/${tdir}/${tfile}"
15385         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
15386         local entry_count
15387         test_mkdir "${DIR}/${tdir}"
15388
15389         setup_165
15390         lfs setstripe -c 1 -i 0 "${file}"
15391
15392         do_facet ost1 lctl set_param "${param}=rw"
15393         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15394         oal_expect_entry_count 1
15395
15396         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15397         oal_expect_entry_count 2
15398
15399         do_facet ost1 lctl set_param "${param}=r"
15400         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15401         oal_expect_entry_count 2
15402
15403         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15404         oal_expect_entry_count 3
15405
15406         do_facet ost1 lctl set_param "${param}=w"
15407         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15408         oal_expect_entry_count 4
15409
15410         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15411         oal_expect_entry_count 4
15412
15413         do_facet ost1 lctl set_param "${param}=0"
15414         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15415         oal_expect_entry_count 4
15416
15417         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15418         oal_expect_entry_count 4
15419 }
15420 run_test 165d "ofd_access_log mask works"
15421
15422 test_169() {
15423         # do directio so as not to populate the page cache
15424         log "creating a 10 Mb file"
15425         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
15426         log "starting reads"
15427         dd if=$DIR/$tfile of=/dev/null bs=4096 &
15428         log "truncating the file"
15429         $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
15430         log "killing dd"
15431         kill %+ || true # reads might have finished
15432         echo "wait until dd is finished"
15433         wait
15434         log "removing the temporary file"
15435         rm -rf $DIR/$tfile || error "tmp file removal failed"
15436 }
15437 run_test 169 "parallel read and truncate should not deadlock"
15438
15439 test_170() {
15440         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15441
15442         $LCTL clear     # bug 18514
15443         $LCTL debug_daemon start $TMP/${tfile}_log_good
15444         touch $DIR/$tfile
15445         $LCTL debug_daemon stop
15446         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
15447                 error "sed failed to read log_good"
15448
15449         $LCTL debug_daemon start $TMP/${tfile}_log_good
15450         rm -rf $DIR/$tfile
15451         $LCTL debug_daemon stop
15452
15453         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
15454                error "lctl df log_bad failed"
15455
15456         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
15457         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
15458
15459         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
15460         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
15461
15462         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
15463                 error "bad_line good_line1 good_line2 are empty"
15464
15465         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
15466         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
15467         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
15468
15469         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
15470         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
15471         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
15472
15473         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
15474                 error "bad_line_new good_line_new are empty"
15475
15476         local expected_good=$((good_line1 + good_line2*2))
15477
15478         rm -f $TMP/${tfile}*
15479         # LU-231, short malformed line may not be counted into bad lines
15480         if [ $bad_line -ne $bad_line_new ] &&
15481                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
15482                 error "expected $bad_line bad lines, but got $bad_line_new"
15483                 return 1
15484         fi
15485
15486         if [ $expected_good -ne $good_line_new ]; then
15487                 error "expected $expected_good good lines, but got $good_line_new"
15488                 return 2
15489         fi
15490         true
15491 }
15492 run_test 170 "test lctl df to handle corrupted log ====================="
15493
15494 test_171() { # bug20592
15495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15496
15497         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
15498         $LCTL set_param fail_loc=0x50e
15499         $LCTL set_param fail_val=3000
15500         multiop_bg_pause $DIR/$tfile O_s || true
15501         local MULTIPID=$!
15502         kill -USR1 $MULTIPID
15503         # cause log dump
15504         sleep 3
15505         wait $MULTIPID
15506         if dmesg | grep "recursive fault"; then
15507                 error "caught a recursive fault"
15508         fi
15509         $LCTL set_param fail_loc=0
15510         true
15511 }
15512 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
15513
15514 # it would be good to share it with obdfilter-survey/iokit-libecho code
15515 setup_obdecho_osc () {
15516         local rc=0
15517         local ost_nid=$1
15518         local obdfilter_name=$2
15519         echo "Creating new osc for $obdfilter_name on $ost_nid"
15520         # make sure we can find loopback nid
15521         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
15522
15523         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
15524                            ${obdfilter_name}_osc_UUID || rc=2; }
15525         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
15526                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
15527         return $rc
15528 }
15529
15530 cleanup_obdecho_osc () {
15531         local obdfilter_name=$1
15532         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
15533         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
15534         return 0
15535 }
15536
15537 obdecho_test() {
15538         local OBD=$1
15539         local node=$2
15540         local pages=${3:-64}
15541         local rc=0
15542         local id
15543
15544         local count=10
15545         local obd_size=$(get_obd_size $node $OBD)
15546         local page_size=$(get_page_size $node)
15547         if [[ -n "$obd_size" ]]; then
15548                 local new_count=$((obd_size / (pages * page_size / 1024)))
15549                 [[ $new_count -ge $count ]] || count=$new_count
15550         fi
15551
15552         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
15553         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
15554                            rc=2; }
15555         if [ $rc -eq 0 ]; then
15556             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
15557             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
15558         fi
15559         echo "New object id is $id"
15560         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
15561                            rc=4; }
15562         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
15563                            "test_brw $count w v $pages $id" || rc=4; }
15564         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
15565                            rc=4; }
15566         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
15567                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
15568         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
15569                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
15570         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
15571         return $rc
15572 }
15573
15574 test_180a() {
15575         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15576
15577         if ! module_loaded obdecho; then
15578                 load_module obdecho/obdecho &&
15579                         stack_trap "rmmod obdecho" EXIT ||
15580                         error "unable to load obdecho on client"
15581         fi
15582
15583         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
15584         local host=$($LCTL get_param -n osc.$osc.import |
15585                      awk '/current_connection:/ { print $2 }' )
15586         local target=$($LCTL get_param -n osc.$osc.import |
15587                        awk '/target:/ { print $2 }' )
15588         target=${target%_UUID}
15589
15590         if [ -n "$target" ]; then
15591                 setup_obdecho_osc $host $target &&
15592                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
15593                         { error "obdecho setup failed with $?"; return; }
15594
15595                 obdecho_test ${target}_osc client ||
15596                         error "obdecho_test failed on ${target}_osc"
15597         else
15598                 $LCTL get_param osc.$osc.import
15599                 error "there is no osc.$osc.import target"
15600         fi
15601 }
15602 run_test 180a "test obdecho on osc"
15603
15604 test_180b() {
15605         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15606         remote_ost_nodsh && skip "remote OST with nodsh"
15607
15608         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
15609                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
15610                 error "failed to load module obdecho"
15611
15612         local target=$(do_facet ost1 $LCTL dl |
15613                        awk '/obdfilter/ { print $4; exit; }')
15614
15615         if [ -n "$target" ]; then
15616                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
15617         else
15618                 do_facet ost1 $LCTL dl
15619                 error "there is no obdfilter target on ost1"
15620         fi
15621 }
15622 run_test 180b "test obdecho directly on obdfilter"
15623
15624 test_180c() { # LU-2598
15625         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15626         remote_ost_nodsh && skip "remote OST with nodsh"
15627         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
15628                 skip "Need MDS version at least 2.4.0"
15629
15630         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
15631                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
15632                 error "failed to load module obdecho"
15633
15634         local target=$(do_facet ost1 $LCTL dl |
15635                        awk '/obdfilter/ { print $4; exit; }')
15636
15637         if [ -n "$target" ]; then
15638                 local pages=16384 # 64MB bulk I/O RPC size
15639
15640                 obdecho_test "$target" ost1 "$pages" ||
15641                         error "obdecho_test with pages=$pages failed with $?"
15642         else
15643                 do_facet ost1 $LCTL dl
15644                 error "there is no obdfilter target on ost1"
15645         fi
15646 }
15647 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
15648
15649 test_181() { # bug 22177
15650         test_mkdir $DIR/$tdir
15651         # create enough files to index the directory
15652         createmany -o $DIR/$tdir/foobar 4000
15653         # print attributes for debug purpose
15654         lsattr -d .
15655         # open dir
15656         multiop_bg_pause $DIR/$tdir D_Sc || return 1
15657         MULTIPID=$!
15658         # remove the files & current working dir
15659         unlinkmany $DIR/$tdir/foobar 4000
15660         rmdir $DIR/$tdir
15661         kill -USR1 $MULTIPID
15662         wait $MULTIPID
15663         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
15664         return 0
15665 }
15666 run_test 181 "Test open-unlinked dir ========================"
15667
15668 test_182() {
15669         local fcount=1000
15670         local tcount=10
15671
15672         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
15673
15674         $LCTL set_param mdc.*.rpc_stats=clear
15675
15676         for (( i = 0; i < $tcount; i++ )) ; do
15677                 mkdir $DIR/$tdir/$i
15678         done
15679
15680         for (( i = 0; i < $tcount; i++ )) ; do
15681                 createmany -o $DIR/$tdir/$i/f- $fcount &
15682         done
15683         wait
15684
15685         for (( i = 0; i < $tcount; i++ )) ; do
15686                 unlinkmany $DIR/$tdir/$i/f- $fcount &
15687         done
15688         wait
15689
15690         $LCTL get_param mdc.*.rpc_stats
15691
15692         rm -rf $DIR/$tdir
15693 }
15694 run_test 182 "Test parallel modify metadata operations ================"
15695
15696 test_183() { # LU-2275
15697         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15698         remote_mds_nodsh && skip "remote MDS with nodsh"
15699         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
15700                 skip "Need MDS version at least 2.3.56"
15701
15702         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
15703         echo aaa > $DIR/$tdir/$tfile
15704
15705 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
15706         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
15707
15708         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
15709         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
15710
15711         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
15712
15713         # Flush negative dentry cache
15714         touch $DIR/$tdir/$tfile
15715
15716         # We are not checking for any leaked references here, they'll
15717         # become evident next time we do cleanup with module unload.
15718         rm -rf $DIR/$tdir
15719 }
15720 run_test 183 "No crash or request leak in case of strange dispositions ========"
15721
15722 # test suite 184 is for LU-2016, LU-2017
15723 test_184a() {
15724         check_swap_layouts_support
15725
15726         dir0=$DIR/$tdir/$testnum
15727         test_mkdir -p -c1 $dir0
15728         ref1=/etc/passwd
15729         ref2=/etc/group
15730         file1=$dir0/f1
15731         file2=$dir0/f2
15732         $LFS setstripe -c1 $file1
15733         cp $ref1 $file1
15734         $LFS setstripe -c2 $file2
15735         cp $ref2 $file2
15736         gen1=$($LFS getstripe -g $file1)
15737         gen2=$($LFS getstripe -g $file2)
15738
15739         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
15740         gen=$($LFS getstripe -g $file1)
15741         [[ $gen1 != $gen ]] ||
15742                 "Layout generation on $file1 does not change"
15743         gen=$($LFS getstripe -g $file2)
15744         [[ $gen2 != $gen ]] ||
15745                 "Layout generation on $file2 does not change"
15746
15747         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
15748         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
15749
15750         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
15751 }
15752 run_test 184a "Basic layout swap"
15753
15754 test_184b() {
15755         check_swap_layouts_support
15756
15757         dir0=$DIR/$tdir/$testnum
15758         mkdir -p $dir0 || error "creating dir $dir0"
15759         file1=$dir0/f1
15760         file2=$dir0/f2
15761         file3=$dir0/f3
15762         dir1=$dir0/d1
15763         dir2=$dir0/d2
15764         mkdir $dir1 $dir2
15765         $LFS setstripe -c1 $file1
15766         $LFS setstripe -c2 $file2
15767         $LFS setstripe -c1 $file3
15768         chown $RUNAS_ID $file3
15769         gen1=$($LFS getstripe -g $file1)
15770         gen2=$($LFS getstripe -g $file2)
15771
15772         $LFS swap_layouts $dir1 $dir2 &&
15773                 error "swap of directories layouts should fail"
15774         $LFS swap_layouts $dir1 $file1 &&
15775                 error "swap of directory and file layouts should fail"
15776         $RUNAS $LFS swap_layouts $file1 $file2 &&
15777                 error "swap of file we cannot write should fail"
15778         $LFS swap_layouts $file1 $file3 &&
15779                 error "swap of file with different owner should fail"
15780         /bin/true # to clear error code
15781 }
15782 run_test 184b "Forbidden layout swap (will generate errors)"
15783
15784 test_184c() {
15785         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
15786         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
15787         check_swap_layouts_support
15788
15789         local dir0=$DIR/$tdir/$testnum
15790         mkdir -p $dir0 || error "creating dir $dir0"
15791
15792         local ref1=$dir0/ref1
15793         local ref2=$dir0/ref2
15794         local file1=$dir0/file1
15795         local file2=$dir0/file2
15796         # create a file large enough for the concurrent test
15797         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
15798         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
15799         echo "ref file size: ref1($(stat -c %s $ref1))," \
15800              "ref2($(stat -c %s $ref2))"
15801
15802         cp $ref2 $file2
15803         dd if=$ref1 of=$file1 bs=16k &
15804         local DD_PID=$!
15805
15806         # Make sure dd starts to copy file
15807         while [ ! -f $file1 ]; do sleep 0.1; done
15808
15809         $LFS swap_layouts $file1 $file2
15810         local rc=$?
15811         wait $DD_PID
15812         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
15813         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
15814
15815         # how many bytes copied before swapping layout
15816         local copied=$(stat -c %s $file2)
15817         local remaining=$(stat -c %s $ref1)
15818         remaining=$((remaining - copied))
15819         echo "Copied $copied bytes before swapping layout..."
15820
15821         cmp -n $copied $file1 $ref2 | grep differ &&
15822                 error "Content mismatch [0, $copied) of ref2 and file1"
15823         cmp -n $copied $file2 $ref1 ||
15824                 error "Content mismatch [0, $copied) of ref1 and file2"
15825         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
15826                 error "Content mismatch [$copied, EOF) of ref1 and file1"
15827
15828         # clean up
15829         rm -f $ref1 $ref2 $file1 $file2
15830 }
15831 run_test 184c "Concurrent write and layout swap"
15832
15833 test_184d() {
15834         check_swap_layouts_support
15835         [ -z "$(which getfattr 2>/dev/null)" ] &&
15836                 skip_env "no getfattr command"
15837
15838         local file1=$DIR/$tdir/$tfile-1
15839         local file2=$DIR/$tdir/$tfile-2
15840         local file3=$DIR/$tdir/$tfile-3
15841         local lovea1
15842         local lovea2
15843
15844         mkdir -p $DIR/$tdir
15845         touch $file1 || error "create $file1 failed"
15846         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
15847                 error "create $file2 failed"
15848         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
15849                 error "create $file3 failed"
15850         lovea1=$(get_layout_param $file1)
15851
15852         $LFS swap_layouts $file2 $file3 ||
15853                 error "swap $file2 $file3 layouts failed"
15854         $LFS swap_layouts $file1 $file2 ||
15855                 error "swap $file1 $file2 layouts failed"
15856
15857         lovea2=$(get_layout_param $file2)
15858         echo "$lovea1"
15859         echo "$lovea2"
15860         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
15861
15862         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
15863         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
15864 }
15865 run_test 184d "allow stripeless layouts swap"
15866
15867 test_184e() {
15868         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
15869                 skip "Need MDS version at least 2.6.94"
15870         check_swap_layouts_support
15871         [ -z "$(which getfattr 2>/dev/null)" ] &&
15872                 skip_env "no getfattr command"
15873
15874         local file1=$DIR/$tdir/$tfile-1
15875         local file2=$DIR/$tdir/$tfile-2
15876         local file3=$DIR/$tdir/$tfile-3
15877         local lovea
15878
15879         mkdir -p $DIR/$tdir
15880         touch $file1 || error "create $file1 failed"
15881         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
15882                 error "create $file2 failed"
15883         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
15884                 error "create $file3 failed"
15885
15886         $LFS swap_layouts $file1 $file2 ||
15887                 error "swap $file1 $file2 layouts failed"
15888
15889         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
15890         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
15891
15892         echo 123 > $file1 || error "Should be able to write into $file1"
15893
15894         $LFS swap_layouts $file1 $file3 ||
15895                 error "swap $file1 $file3 layouts failed"
15896
15897         echo 123 > $file1 || error "Should be able to write into $file1"
15898
15899         rm -rf $file1 $file2 $file3
15900 }
15901 run_test 184e "Recreate layout after stripeless layout swaps"
15902
15903 test_184f() {
15904         # Create a file with name longer than sizeof(struct stat) ==
15905         # 144 to see if we can get chars from the file name to appear
15906         # in the returned striping. Note that 'f' == 0x66.
15907         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
15908
15909         mkdir -p $DIR/$tdir
15910         mcreate $DIR/$tdir/$file
15911         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
15912                 error "IOC_MDC_GETFILEINFO returned garbage striping"
15913         fi
15914 }
15915 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
15916
15917 test_185() { # LU-2441
15918         # LU-3553 - no volatile file support in old servers
15919         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
15920                 skip "Need MDS version at least 2.3.60"
15921
15922         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
15923         touch $DIR/$tdir/spoo
15924         local mtime1=$(stat -c "%Y" $DIR/$tdir)
15925         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
15926                 error "cannot create/write a volatile file"
15927         [ "$FILESET" == "" ] &&
15928         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
15929                 error "FID is still valid after close"
15930
15931         multiop_bg_pause $DIR/$tdir vVw4096_c
15932         local multi_pid=$!
15933
15934         local OLD_IFS=$IFS
15935         IFS=":"
15936         local fidv=($fid)
15937         IFS=$OLD_IFS
15938         # assume that the next FID for this client is sequential, since stdout
15939         # is unfortunately eaten by multiop_bg_pause
15940         local n=$((${fidv[1]} + 1))
15941         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
15942         if [ "$FILESET" == "" ]; then
15943                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
15944                         error "FID is missing before close"
15945         fi
15946         kill -USR1 $multi_pid
15947         # 1 second delay, so if mtime change we will see it
15948         sleep 1
15949         local mtime2=$(stat -c "%Y" $DIR/$tdir)
15950         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
15951 }
15952 run_test 185 "Volatile file support"
15953
15954 function create_check_volatile() {
15955         local idx=$1
15956         local tgt
15957
15958         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
15959         local PID=$!
15960         sleep 1
15961         local FID=$(cat /tmp/${tfile}.fid)
15962         [ "$FID" == "" ] && error "can't get FID for volatile"
15963         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
15964         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
15965         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
15966         kill -USR1 $PID
15967         wait
15968         sleep 1
15969         cancel_lru_locks mdc # flush opencache
15970         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
15971         return 0
15972 }
15973
15974 test_185a(){
15975         # LU-12516 - volatile creation via .lustre
15976         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
15977                 skip "Need MDS version at least 2.3.55"
15978
15979         create_check_volatile 0
15980         [ $MDSCOUNT -lt 2 ] && return 0
15981
15982         # DNE case
15983         create_check_volatile 1
15984
15985         return 0
15986 }
15987 run_test 185a "Volatile file creation in .lustre/fid/"
15988
15989 test_187a() {
15990         remote_mds_nodsh && skip "remote MDS with nodsh"
15991         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
15992                 skip "Need MDS version at least 2.3.0"
15993
15994         local dir0=$DIR/$tdir/$testnum
15995         mkdir -p $dir0 || error "creating dir $dir0"
15996
15997         local file=$dir0/file1
15998         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
15999         local dv1=$($LFS data_version $file)
16000         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
16001         local dv2=$($LFS data_version $file)
16002         [[ $dv1 != $dv2 ]] ||
16003                 error "data version did not change on write $dv1 == $dv2"
16004
16005         # clean up
16006         rm -f $file1
16007 }
16008 run_test 187a "Test data version change"
16009
16010 test_187b() {
16011         remote_mds_nodsh && skip "remote MDS with nodsh"
16012         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
16013                 skip "Need MDS version at least 2.3.0"
16014
16015         local dir0=$DIR/$tdir/$testnum
16016         mkdir -p $dir0 || error "creating dir $dir0"
16017
16018         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
16019         [[ ${DV[0]} != ${DV[1]} ]] ||
16020                 error "data version did not change on write"\
16021                       " ${DV[0]} == ${DV[1]}"
16022
16023         # clean up
16024         rm -f $file1
16025 }
16026 run_test 187b "Test data version change on volatile file"
16027
16028 test_200() {
16029         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16030         remote_mgs_nodsh && skip "remote MGS with nodsh"
16031         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16032
16033         local POOL=${POOL:-cea1}
16034         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
16035         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
16036         # Pool OST targets
16037         local first_ost=0
16038         local last_ost=$(($OSTCOUNT - 1))
16039         local ost_step=2
16040         local ost_list=$(seq $first_ost $ost_step $last_ost)
16041         local ost_range="$first_ost $last_ost $ost_step"
16042         local test_path=$POOL_ROOT/$POOL_DIR_NAME
16043         local file_dir=$POOL_ROOT/file_tst
16044         local subdir=$test_path/subdir
16045         local rc=0
16046
16047         while : ; do
16048                 # former test_200a test_200b
16049                 pool_add $POOL                          || { rc=$? ; break; }
16050                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
16051                 # former test_200c test_200d
16052                 mkdir -p $test_path
16053                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
16054                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
16055                 mkdir -p $subdir
16056                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
16057                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
16058                                                         || { rc=$? ; break; }
16059                 # former test_200e test_200f
16060                 local files=$((OSTCOUNT*3))
16061                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
16062                                                         || { rc=$? ; break; }
16063                 pool_create_files $POOL $file_dir $files "$ost_list" \
16064                                                         || { rc=$? ; break; }
16065                 # former test_200g test_200h
16066                 pool_lfs_df $POOL                       || { rc=$? ; break; }
16067                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
16068
16069                 # former test_201a test_201b test_201c
16070                 pool_remove_first_target $POOL          || { rc=$? ; break; }
16071
16072                 local f=$test_path/$tfile
16073                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
16074                 pool_remove $POOL $f                    || { rc=$? ; break; }
16075                 break
16076         done
16077
16078         destroy_test_pools
16079
16080         return $rc
16081 }
16082 run_test 200 "OST pools"
16083
16084 # usage: default_attr <count | size | offset>
16085 default_attr() {
16086         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
16087 }
16088
16089 # usage: check_default_stripe_attr
16090 check_default_stripe_attr() {
16091         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
16092         case $1 in
16093         --stripe-count|-c)
16094                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
16095         --stripe-size|-S)
16096                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
16097         --stripe-index|-i)
16098                 EXPECTED=-1;;
16099         *)
16100                 error "unknown getstripe attr '$1'"
16101         esac
16102
16103         [ $ACTUAL == $EXPECTED ] ||
16104                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
16105 }
16106
16107 test_204a() {
16108         test_mkdir $DIR/$tdir
16109         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
16110
16111         check_default_stripe_attr --stripe-count
16112         check_default_stripe_attr --stripe-size
16113         check_default_stripe_attr --stripe-index
16114 }
16115 run_test 204a "Print default stripe attributes"
16116
16117 test_204b() {
16118         test_mkdir $DIR/$tdir
16119         $LFS setstripe --stripe-count 1 $DIR/$tdir
16120
16121         check_default_stripe_attr --stripe-size
16122         check_default_stripe_attr --stripe-index
16123 }
16124 run_test 204b "Print default stripe size and offset"
16125
16126 test_204c() {
16127         test_mkdir $DIR/$tdir
16128         $LFS setstripe --stripe-size 65536 $DIR/$tdir
16129
16130         check_default_stripe_attr --stripe-count
16131         check_default_stripe_attr --stripe-index
16132 }
16133 run_test 204c "Print default stripe count and offset"
16134
16135 test_204d() {
16136         test_mkdir $DIR/$tdir
16137         $LFS setstripe --stripe-index 0 $DIR/$tdir
16138
16139         check_default_stripe_attr --stripe-count
16140         check_default_stripe_attr --stripe-size
16141 }
16142 run_test 204d "Print default stripe count and size"
16143
16144 test_204e() {
16145         test_mkdir $DIR/$tdir
16146         $LFS setstripe -d $DIR/$tdir
16147
16148         check_default_stripe_attr --stripe-count --raw
16149         check_default_stripe_attr --stripe-size --raw
16150         check_default_stripe_attr --stripe-index --raw
16151 }
16152 run_test 204e "Print raw stripe attributes"
16153
16154 test_204f() {
16155         test_mkdir $DIR/$tdir
16156         $LFS setstripe --stripe-count 1 $DIR/$tdir
16157
16158         check_default_stripe_attr --stripe-size --raw
16159         check_default_stripe_attr --stripe-index --raw
16160 }
16161 run_test 204f "Print raw stripe size and offset"
16162
16163 test_204g() {
16164         test_mkdir $DIR/$tdir
16165         $LFS setstripe --stripe-size 65536 $DIR/$tdir
16166
16167         check_default_stripe_attr --stripe-count --raw
16168         check_default_stripe_attr --stripe-index --raw
16169 }
16170 run_test 204g "Print raw stripe count and offset"
16171
16172 test_204h() {
16173         test_mkdir $DIR/$tdir
16174         $LFS setstripe --stripe-index 0 $DIR/$tdir
16175
16176         check_default_stripe_attr --stripe-count --raw
16177         check_default_stripe_attr --stripe-size --raw
16178 }
16179 run_test 204h "Print raw stripe count and size"
16180
16181 # Figure out which job scheduler is being used, if any,
16182 # or use a fake one
16183 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
16184         JOBENV=SLURM_JOB_ID
16185 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
16186         JOBENV=LSB_JOBID
16187 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
16188         JOBENV=PBS_JOBID
16189 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
16190         JOBENV=LOADL_STEP_ID
16191 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
16192         JOBENV=JOB_ID
16193 else
16194         $LCTL list_param jobid_name > /dev/null 2>&1
16195         if [ $? -eq 0 ]; then
16196                 JOBENV=nodelocal
16197         else
16198                 JOBENV=FAKE_JOBID
16199         fi
16200 fi
16201 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
16202
16203 verify_jobstats() {
16204         local cmd=($1)
16205         shift
16206         local facets="$@"
16207
16208 # we don't really need to clear the stats for this test to work, since each
16209 # command has a unique jobid, but it makes debugging easier if needed.
16210 #       for facet in $facets; do
16211 #               local dev=$(convert_facet2label $facet)
16212 #               # clear old jobstats
16213 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
16214 #       done
16215
16216         # use a new JobID for each test, or we might see an old one
16217         [ "$JOBENV" = "FAKE_JOBID" ] &&
16218                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
16219
16220         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
16221
16222         [ "$JOBENV" = "nodelocal" ] && {
16223                 FAKE_JOBID=id.$testnum.%e.$RANDOM
16224                 $LCTL set_param jobid_name=$FAKE_JOBID
16225                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
16226         }
16227
16228         log "Test: ${cmd[*]}"
16229         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
16230
16231         if [ $JOBENV = "FAKE_JOBID" ]; then
16232                 FAKE_JOBID=$JOBVAL ${cmd[*]}
16233         else
16234                 ${cmd[*]}
16235         fi
16236
16237         # all files are created on OST0000
16238         for facet in $facets; do
16239                 local stats="*.$(convert_facet2label $facet).job_stats"
16240
16241                 # strip out libtool wrappers for in-tree executables
16242                 if [ $(do_facet $facet lctl get_param $stats |
16243                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
16244                         do_facet $facet lctl get_param $stats
16245                         error "No jobstats for $JOBVAL found on $facet::$stats"
16246                 fi
16247         done
16248 }
16249
16250 jobstats_set() {
16251         local new_jobenv=$1
16252
16253         set_persistent_param_and_check client "jobid_var" \
16254                 "$FSNAME.sys.jobid_var" $new_jobenv
16255 }
16256
16257 test_205a() { # Job stats
16258         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16259         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
16260                 skip "Need MDS version with at least 2.7.1"
16261         remote_mgs_nodsh && skip "remote MGS with nodsh"
16262         remote_mds_nodsh && skip "remote MDS with nodsh"
16263         remote_ost_nodsh && skip "remote OST with nodsh"
16264         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
16265                 skip "Server doesn't support jobstats"
16266         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
16267
16268         local old_jobenv=$($LCTL get_param -n jobid_var)
16269         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
16270
16271         if [[ $PERM_CMD == *"set_param -P"* ]]; then
16272                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
16273         else
16274                 stack_trap "do_facet mgs $PERM_CMD \
16275                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
16276         fi
16277         changelog_register
16278
16279         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
16280                                 mdt.*.job_cleanup_interval | head -n 1)
16281         local new_interval=5
16282         do_facet $SINGLEMDS \
16283                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
16284         stack_trap "do_facet $SINGLEMDS \
16285                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
16286         local start=$SECONDS
16287
16288         local cmd
16289         # mkdir
16290         cmd="mkdir $DIR/$tdir"
16291         verify_jobstats "$cmd" "$SINGLEMDS"
16292         # rmdir
16293         cmd="rmdir $DIR/$tdir"
16294         verify_jobstats "$cmd" "$SINGLEMDS"
16295         # mkdir on secondary MDT
16296         if [ $MDSCOUNT -gt 1 ]; then
16297                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
16298                 verify_jobstats "$cmd" "mds2"
16299         fi
16300         # mknod
16301         cmd="mknod $DIR/$tfile c 1 3"
16302         verify_jobstats "$cmd" "$SINGLEMDS"
16303         # unlink
16304         cmd="rm -f $DIR/$tfile"
16305         verify_jobstats "$cmd" "$SINGLEMDS"
16306         # create all files on OST0000 so verify_jobstats can find OST stats
16307         # open & close
16308         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
16309         verify_jobstats "$cmd" "$SINGLEMDS"
16310         # setattr
16311         cmd="touch $DIR/$tfile"
16312         verify_jobstats "$cmd" "$SINGLEMDS ost1"
16313         # write
16314         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
16315         verify_jobstats "$cmd" "ost1"
16316         # read
16317         cancel_lru_locks osc
16318         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
16319         verify_jobstats "$cmd" "ost1"
16320         # truncate
16321         cmd="$TRUNCATE $DIR/$tfile 0"
16322         verify_jobstats "$cmd" "$SINGLEMDS ost1"
16323         # rename
16324         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
16325         verify_jobstats "$cmd" "$SINGLEMDS"
16326         # jobstats expiry - sleep until old stats should be expired
16327         local left=$((new_interval + 5 - (SECONDS - start)))
16328         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
16329                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
16330                         "0" $left
16331         cmd="mkdir $DIR/$tdir.expire"
16332         verify_jobstats "$cmd" "$SINGLEMDS"
16333         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
16334             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
16335
16336         # Ensure that jobid are present in changelog (if supported by MDS)
16337         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
16338                 changelog_dump | tail -10
16339                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
16340                 [ $jobids -eq 9 ] ||
16341                         error "Wrong changelog jobid count $jobids != 9"
16342
16343                 # LU-5862
16344                 JOBENV="disable"
16345                 jobstats_set $JOBENV
16346                 touch $DIR/$tfile
16347                 changelog_dump | grep $tfile
16348                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
16349                 [ $jobids -eq 0 ] ||
16350                         error "Unexpected jobids when jobid_var=$JOBENV"
16351         fi
16352
16353         lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"
16354         JOBENV="JOBCOMPLEX"
16355         JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
16356
16357         verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
16358 }
16359 run_test 205a "Verify job stats"
16360
16361 # LU-13117, LU-13597
16362 test_205b() {
16363         job_stats="mdt.*.job_stats"
16364         $LCTL set_param $job_stats=clear
16365         $LCTL set_param jobid_var=USER jobid_name="%e.%u"
16366         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
16367         do_facet $SINGLEMDS $LCTL get_param $job_stats |
16368                 grep "job_id:.*foolish" &&
16369                         error "Unexpected jobid found"
16370         do_facet $SINGLEMDS $LCTL get_param $job_stats |
16371                 grep "open:.*min.*max.*sum" ||
16372                         error "wrong job_stats format found"
16373 }
16374 run_test 205b "Verify job stats jobid and output format"
16375
16376 # LU-1480, LU-1773 and LU-1657
16377 test_206() {
16378         mkdir -p $DIR/$tdir
16379         $LFS setstripe -c -1 $DIR/$tdir
16380 #define OBD_FAIL_LOV_INIT 0x1403
16381         $LCTL set_param fail_loc=0xa0001403
16382         $LCTL set_param fail_val=1
16383         touch $DIR/$tdir/$tfile || true
16384 }
16385 run_test 206 "fail lov_init_raid0() doesn't lbug"
16386
16387 test_207a() {
16388         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
16389         local fsz=`stat -c %s $DIR/$tfile`
16390         cancel_lru_locks mdc
16391
16392         # do not return layout in getattr intent
16393 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
16394         $LCTL set_param fail_loc=0x170
16395         local sz=`stat -c %s $DIR/$tfile`
16396
16397         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
16398
16399         rm -rf $DIR/$tfile
16400 }
16401 run_test 207a "can refresh layout at glimpse"
16402
16403 test_207b() {
16404         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
16405         local cksum=`md5sum $DIR/$tfile`
16406         local fsz=`stat -c %s $DIR/$tfile`
16407         cancel_lru_locks mdc
16408         cancel_lru_locks osc
16409
16410         # do not return layout in getattr intent
16411 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
16412         $LCTL set_param fail_loc=0x171
16413
16414         # it will refresh layout after the file is opened but before read issues
16415         echo checksum is "$cksum"
16416         echo "$cksum" |md5sum -c --quiet || error "file differs"
16417
16418         rm -rf $DIR/$tfile
16419 }
16420 run_test 207b "can refresh layout at open"
16421
16422 test_208() {
16423         # FIXME: in this test suite, only RD lease is used. This is okay
16424         # for now as only exclusive open is supported. After generic lease
16425         # is done, this test suite should be revised. - Jinshan
16426
16427         remote_mds_nodsh && skip "remote MDS with nodsh"
16428         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
16429                 skip "Need MDS version at least 2.4.52"
16430
16431         echo "==== test 1: verify get lease work"
16432         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
16433
16434         echo "==== test 2: verify lease can be broken by upcoming open"
16435         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
16436         local PID=$!
16437         sleep 1
16438
16439         $MULTIOP $DIR/$tfile oO_RDONLY:c
16440         kill -USR1 $PID && wait $PID || error "break lease error"
16441
16442         echo "==== test 3: verify lease can't be granted if an open already exists"
16443         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
16444         local PID=$!
16445         sleep 1
16446
16447         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
16448         kill -USR1 $PID && wait $PID || error "open file error"
16449
16450         echo "==== test 4: lease can sustain over recovery"
16451         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
16452         PID=$!
16453         sleep 1
16454
16455         fail mds1
16456
16457         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
16458
16459         echo "==== test 5: lease broken can't be regained by replay"
16460         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
16461         PID=$!
16462         sleep 1
16463
16464         # open file to break lease and then recovery
16465         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
16466         fail mds1
16467
16468         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
16469
16470         rm -f $DIR/$tfile
16471 }
16472 run_test 208 "Exclusive open"
16473
16474 test_209() {
16475         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
16476                 skip_env "must have disp_stripe"
16477
16478         touch $DIR/$tfile
16479         sync; sleep 5; sync;
16480
16481         echo 3 > /proc/sys/vm/drop_caches
16482         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
16483
16484         # open/close 500 times
16485         for i in $(seq 500); do
16486                 cat $DIR/$tfile
16487         done
16488
16489         echo 3 > /proc/sys/vm/drop_caches
16490         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
16491
16492         echo "before: $req_before, after: $req_after"
16493         [ $((req_after - req_before)) -ge 300 ] &&
16494                 error "open/close requests are not freed"
16495         return 0
16496 }
16497 run_test 209 "read-only open/close requests should be freed promptly"
16498
16499 test_210() {
16500         local pid
16501
16502         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
16503         pid=$!
16504         sleep 1
16505
16506         $LFS getstripe $DIR/$tfile
16507         kill -USR1 $pid
16508         wait $pid || error "multiop failed"
16509
16510         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
16511         pid=$!
16512         sleep 1
16513
16514         $LFS getstripe $DIR/$tfile
16515         kill -USR1 $pid
16516         wait $pid || error "multiop failed"
16517 }
16518 run_test 210 "lfs getstripe does not break leases"
16519
16520 test_212() {
16521         size=`date +%s`
16522         size=$((size % 8192 + 1))
16523         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
16524         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
16525         rm -f $DIR/f212 $DIR/f212.xyz
16526 }
16527 run_test 212 "Sendfile test ============================================"
16528
16529 test_213() {
16530         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
16531         cancel_lru_locks osc
16532         lctl set_param fail_loc=0x8000040f
16533         # generate a read lock
16534         cat $DIR/$tfile > /dev/null
16535         # write to the file, it will try to cancel the above read lock.
16536         cat /etc/hosts >> $DIR/$tfile
16537 }
16538 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
16539
16540 test_214() { # for bug 20133
16541         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
16542         for (( i=0; i < 340; i++ )) ; do
16543                 touch $DIR/$tdir/d214c/a$i
16544         done
16545
16546         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
16547         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
16548         ls $DIR/d214c || error "ls $DIR/d214c failed"
16549         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
16550         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
16551 }
16552 run_test 214 "hash-indexed directory test - bug 20133"
16553
16554 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
16555 create_lnet_proc_files() {
16556         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
16557 }
16558
16559 # counterpart of create_lnet_proc_files
16560 remove_lnet_proc_files() {
16561         rm -f $TMP/lnet_$1.sys
16562 }
16563
16564 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
16565 # 3rd arg as regexp for body
16566 check_lnet_proc_stats() {
16567         local l=$(cat "$TMP/lnet_$1" |wc -l)
16568         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
16569
16570         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
16571 }
16572
16573 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
16574 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
16575 # optional and can be regexp for 2nd line (lnet.routes case)
16576 check_lnet_proc_entry() {
16577         local blp=2          # blp stands for 'position of 1st line of body'
16578         [ -z "$5" ] || blp=3 # lnet.routes case
16579
16580         local l=$(cat "$TMP/lnet_$1" |wc -l)
16581         # subtracting one from $blp because the body can be empty
16582         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
16583
16584         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
16585                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
16586
16587         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
16588                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
16589
16590         # bail out if any unexpected line happened
16591         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
16592         [ "$?" != 0 ] || error "$2 misformatted"
16593 }
16594
16595 test_215() { # for bugs 18102, 21079, 21517
16596         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16597
16598         local N='(0|[1-9][0-9]*)'       # non-negative numeric
16599         local P='[1-9][0-9]*'           # positive numeric
16600         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
16601         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
16602         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
16603         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
16604
16605         local L1 # regexp for 1st line
16606         local L2 # regexp for 2nd line (optional)
16607         local BR # regexp for the rest (body)
16608
16609         # lnet.stats should look as 11 space-separated non-negative numerics
16610         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
16611         create_lnet_proc_files "stats"
16612         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
16613         remove_lnet_proc_files "stats"
16614
16615         # lnet.routes should look like this:
16616         # Routing disabled/enabled
16617         # net hops priority state router
16618         # where net is a string like tcp0, hops > 0, priority >= 0,
16619         # state is up/down,
16620         # router is a string like 192.168.1.1@tcp2
16621         L1="^Routing (disabled|enabled)$"
16622         L2="^net +hops +priority +state +router$"
16623         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
16624         create_lnet_proc_files "routes"
16625         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
16626         remove_lnet_proc_files "routes"
16627
16628         # lnet.routers should look like this:
16629         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
16630         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
16631         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
16632         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
16633         L1="^ref +rtr_ref +alive +router$"
16634         BR="^$P +$P +(up|down) +$NID$"
16635         create_lnet_proc_files "routers"
16636         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
16637         remove_lnet_proc_files "routers"
16638
16639         # lnet.peers should look like this:
16640         # nid refs state last max rtr min tx min queue
16641         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
16642         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
16643         # numeric (0 or >0 or <0), queue >= 0.
16644         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
16645         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
16646         create_lnet_proc_files "peers"
16647         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
16648         remove_lnet_proc_files "peers"
16649
16650         # lnet.buffers  should look like this:
16651         # pages count credits min
16652         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
16653         L1="^pages +count +credits +min$"
16654         BR="^ +$N +$N +$I +$I$"
16655         create_lnet_proc_files "buffers"
16656         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
16657         remove_lnet_proc_files "buffers"
16658
16659         # lnet.nis should look like this:
16660         # nid status alive refs peer rtr max tx min
16661         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
16662         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
16663         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
16664         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
16665         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
16666         create_lnet_proc_files "nis"
16667         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
16668         remove_lnet_proc_files "nis"
16669
16670         # can we successfully write to lnet.stats?
16671         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
16672 }
16673 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
16674
16675 test_216() { # bug 20317
16676         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16677         remote_ost_nodsh && skip "remote OST with nodsh"
16678
16679         local node
16680         local facets=$(get_facets OST)
16681         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16682
16683         save_lustre_params client "osc.*.contention_seconds" > $p
16684         save_lustre_params $facets \
16685                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
16686         save_lustre_params $facets \
16687                 "ldlm.namespaces.filter-*.contended_locks" >> $p
16688         save_lustre_params $facets \
16689                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
16690         clear_stats osc.*.osc_stats
16691
16692         # agressive lockless i/o settings
16693         do_nodes $(comma_list $(osts_nodes)) \
16694                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
16695                         ldlm.namespaces.filter-*.contended_locks=0 \
16696                         ldlm.namespaces.filter-*.contention_seconds=60"
16697         lctl set_param -n osc.*.contention_seconds=60
16698
16699         $DIRECTIO write $DIR/$tfile 0 10 4096
16700         $CHECKSTAT -s 40960 $DIR/$tfile
16701
16702         # disable lockless i/o
16703         do_nodes $(comma_list $(osts_nodes)) \
16704                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
16705                         ldlm.namespaces.filter-*.contended_locks=32 \
16706                         ldlm.namespaces.filter-*.contention_seconds=0"
16707         lctl set_param -n osc.*.contention_seconds=0
16708         clear_stats osc.*.osc_stats
16709
16710         dd if=/dev/zero of=$DIR/$tfile count=0
16711         $CHECKSTAT -s 0 $DIR/$tfile
16712
16713         restore_lustre_params <$p
16714         rm -f $p
16715         rm $DIR/$tfile
16716 }
16717 run_test 216 "check lockless direct write updates file size and kms correctly"
16718
16719 test_217() { # bug 22430
16720         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16721
16722         local node
16723         local nid
16724
16725         for node in $(nodes_list); do
16726                 nid=$(host_nids_address $node $NETTYPE)
16727                 if [[ $nid = *-* ]] ; then
16728                         echo "lctl ping $(h2nettype $nid)"
16729                         lctl ping $(h2nettype $nid)
16730                 else
16731                         echo "skipping $node (no hyphen detected)"
16732                 fi
16733         done
16734 }
16735 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
16736
16737 test_218() {
16738        # do directio so as not to populate the page cache
16739        log "creating a 10 Mb file"
16740        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
16741        log "starting reads"
16742        dd if=$DIR/$tfile of=/dev/null bs=4096 &
16743        log "truncating the file"
16744        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
16745        log "killing dd"
16746        kill %+ || true # reads might have finished
16747        echo "wait until dd is finished"
16748        wait
16749        log "removing the temporary file"
16750        rm -rf $DIR/$tfile || error "tmp file removal failed"
16751 }
16752 run_test 218 "parallel read and truncate should not deadlock"
16753
16754 test_219() {
16755         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16756
16757         # write one partial page
16758         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
16759         # set no grant so vvp_io_commit_write will do sync write
16760         $LCTL set_param fail_loc=0x411
16761         # write a full page at the end of file
16762         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
16763
16764         $LCTL set_param fail_loc=0
16765         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
16766         $LCTL set_param fail_loc=0x411
16767         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
16768
16769         # LU-4201
16770         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
16771         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
16772 }
16773 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
16774
16775 test_220() { #LU-325
16776         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16777         remote_ost_nodsh && skip "remote OST with nodsh"
16778         remote_mds_nodsh && skip "remote MDS with nodsh"
16779         remote_mgs_nodsh && skip "remote MGS with nodsh"
16780
16781         local OSTIDX=0
16782
16783         # create on MDT0000 so the last_id and next_id are correct
16784         mkdir $DIR/$tdir
16785         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
16786         OST=${OST%_UUID}
16787
16788         # on the mdt's osc
16789         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
16790         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
16791                         osp.$mdtosc_proc1.prealloc_last_id)
16792         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
16793                         osp.$mdtosc_proc1.prealloc_next_id)
16794
16795         $LFS df -i
16796
16797         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
16798         #define OBD_FAIL_OST_ENOINO              0x229
16799         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
16800         create_pool $FSNAME.$TESTNAME || return 1
16801         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
16802
16803         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
16804
16805         MDSOBJS=$((last_id - next_id))
16806         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
16807
16808         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
16809         echo "OST still has $count kbytes free"
16810
16811         echo "create $MDSOBJS files @next_id..."
16812         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
16813
16814         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
16815                         osp.$mdtosc_proc1.prealloc_last_id)
16816         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
16817                         osp.$mdtosc_proc1.prealloc_next_id)
16818
16819         echo "after creation, last_id=$last_id2, next_id=$next_id2"
16820         $LFS df -i
16821
16822         echo "cleanup..."
16823
16824         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
16825         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
16826
16827         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
16828                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
16829         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
16830                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
16831         echo "unlink $MDSOBJS files @$next_id..."
16832         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
16833 }
16834 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
16835
16836 test_221() {
16837         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16838
16839         dd if=`which date` of=$MOUNT/date oflag=sync
16840         chmod +x $MOUNT/date
16841
16842         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
16843         $LCTL set_param fail_loc=0x80001401
16844
16845         $MOUNT/date > /dev/null
16846         rm -f $MOUNT/date
16847 }
16848 run_test 221 "make sure fault and truncate race to not cause OOM"
16849
16850 test_222a () {
16851         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16852
16853         rm -rf $DIR/$tdir
16854         test_mkdir $DIR/$tdir
16855         $LFS setstripe -c 1 -i 0 $DIR/$tdir
16856         createmany -o $DIR/$tdir/$tfile 10
16857         cancel_lru_locks mdc
16858         cancel_lru_locks osc
16859         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
16860         $LCTL set_param fail_loc=0x31a
16861         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
16862         $LCTL set_param fail_loc=0
16863         rm -r $DIR/$tdir
16864 }
16865 run_test 222a "AGL for ls should not trigger CLIO lock failure"
16866
16867 test_222b () {
16868         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16869
16870         rm -rf $DIR/$tdir
16871         test_mkdir $DIR/$tdir
16872         $LFS setstripe -c 1 -i 0 $DIR/$tdir
16873         createmany -o $DIR/$tdir/$tfile 10
16874         cancel_lru_locks mdc
16875         cancel_lru_locks osc
16876         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
16877         $LCTL set_param fail_loc=0x31a
16878         rm -r $DIR/$tdir || error "AGL for rmdir failed"
16879         $LCTL set_param fail_loc=0
16880 }
16881 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
16882
16883 test_223 () {
16884         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16885
16886         rm -rf $DIR/$tdir
16887         test_mkdir $DIR/$tdir
16888         $LFS setstripe -c 1 -i 0 $DIR/$tdir
16889         createmany -o $DIR/$tdir/$tfile 10
16890         cancel_lru_locks mdc
16891         cancel_lru_locks osc
16892         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
16893         $LCTL set_param fail_loc=0x31b
16894         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
16895         $LCTL set_param fail_loc=0
16896         rm -r $DIR/$tdir
16897 }
16898 run_test 223 "osc reenqueue if without AGL lock granted ======================="
16899
16900 test_224a() { # LU-1039, MRP-303
16901         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16902
16903         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
16904         $LCTL set_param fail_loc=0x508
16905         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
16906         $LCTL set_param fail_loc=0
16907         df $DIR
16908 }
16909 run_test 224a "Don't panic on bulk IO failure"
16910
16911 test_224b() { # LU-1039, MRP-303
16912         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16913
16914         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
16915         cancel_lru_locks osc
16916         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
16917         $LCTL set_param fail_loc=0x515
16918         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
16919         $LCTL set_param fail_loc=0
16920         df $DIR
16921 }
16922 run_test 224b "Don't panic on bulk IO failure"
16923
16924 test_224c() { # LU-6441
16925         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16926         remote_mds_nodsh && skip "remote MDS with nodsh"
16927
16928         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16929         save_writethrough $p
16930         set_cache writethrough on
16931
16932         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
16933         local at_max=$($LCTL get_param -n at_max)
16934         local timeout=$($LCTL get_param -n timeout)
16935         local test_at="at_max"
16936         local param_at="$FSNAME.sys.at_max"
16937         local test_timeout="timeout"
16938         local param_timeout="$FSNAME.sys.timeout"
16939
16940         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
16941
16942         set_persistent_param_and_check client "$test_at" "$param_at" 0
16943         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
16944
16945         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
16946         do_facet ost1 "$LCTL set_param fail_loc=0x520"
16947         $LFS setstripe -c 1 -i 0 $DIR/$tfile
16948         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
16949         sync
16950         do_facet ost1 "$LCTL set_param fail_loc=0"
16951
16952         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
16953         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
16954                 $timeout
16955
16956         $LCTL set_param -n $pages_per_rpc
16957         restore_lustre_params < $p
16958         rm -f $p
16959 }
16960 run_test 224c "Don't hang if one of md lost during large bulk RPC"
16961
16962 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
16963 test_225a () {
16964         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16965         if [ -z ${MDSSURVEY} ]; then
16966                 skip_env "mds-survey not found"
16967         fi
16968         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
16969                 skip "Need MDS version at least 2.2.51"
16970
16971         local mds=$(facet_host $SINGLEMDS)
16972         local target=$(do_nodes $mds 'lctl dl' |
16973                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
16974
16975         local cmd1="file_count=1000 thrhi=4"
16976         local cmd2="dir_count=2 layer=mdd stripe_count=0"
16977         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
16978         local cmd="$cmd1 $cmd2 $cmd3"
16979
16980         rm -f ${TMP}/mds_survey*
16981         echo + $cmd
16982         eval $cmd || error "mds-survey with zero-stripe failed"
16983         cat ${TMP}/mds_survey*
16984         rm -f ${TMP}/mds_survey*
16985 }
16986 run_test 225a "Metadata survey sanity with zero-stripe"
16987
16988 test_225b () {
16989         if [ -z ${MDSSURVEY} ]; then
16990                 skip_env "mds-survey not found"
16991         fi
16992         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
16993                 skip "Need MDS version at least 2.2.51"
16994         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16995         remote_mds_nodsh && skip "remote MDS with nodsh"
16996         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
16997                 skip_env "Need to mount OST to test"
16998         fi
16999
17000         local mds=$(facet_host $SINGLEMDS)
17001         local target=$(do_nodes $mds 'lctl dl' |
17002                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17003
17004         local cmd1="file_count=1000 thrhi=4"
17005         local cmd2="dir_count=2 layer=mdd stripe_count=1"
17006         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17007         local cmd="$cmd1 $cmd2 $cmd3"
17008
17009         rm -f ${TMP}/mds_survey*
17010         echo + $cmd
17011         eval $cmd || error "mds-survey with stripe_count failed"
17012         cat ${TMP}/mds_survey*
17013         rm -f ${TMP}/mds_survey*
17014 }
17015 run_test 225b "Metadata survey sanity with stripe_count = 1"
17016
17017 mcreate_path2fid () {
17018         local mode=$1
17019         local major=$2
17020         local minor=$3
17021         local name=$4
17022         local desc=$5
17023         local path=$DIR/$tdir/$name
17024         local fid
17025         local rc
17026         local fid_path
17027
17028         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
17029                 error "cannot create $desc"
17030
17031         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
17032         rc=$?
17033         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
17034
17035         fid_path=$($LFS fid2path $MOUNT $fid)
17036         rc=$?
17037         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
17038
17039         [ "$path" == "$fid_path" ] ||
17040                 error "fid2path returned $fid_path, expected $path"
17041
17042         echo "pass with $path and $fid"
17043 }
17044
17045 test_226a () {
17046         rm -rf $DIR/$tdir
17047         mkdir -p $DIR/$tdir
17048
17049         mcreate_path2fid 0010666 0 0 fifo "FIFO"
17050         mcreate_path2fid 0020666 1 3 null "character special file (null)"
17051         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
17052         mcreate_path2fid 0040666 0 0 dir "directory"
17053         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
17054         mcreate_path2fid 0100666 0 0 file "regular file"
17055         mcreate_path2fid 0120666 0 0 link "symbolic link"
17056         mcreate_path2fid 0140666 0 0 sock "socket"
17057 }
17058 run_test 226a "call path2fid and fid2path on files of all type"
17059
17060 test_226b () {
17061         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17062
17063         local MDTIDX=1
17064
17065         rm -rf $DIR/$tdir
17066         mkdir -p $DIR/$tdir
17067         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
17068                 error "create remote directory failed"
17069         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
17070         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
17071                                 "character special file (null)"
17072         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
17073                                 "character special file (no device)"
17074         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
17075         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
17076                                 "block special file (loop)"
17077         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
17078         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
17079         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
17080 }
17081 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
17082
17083 # LU-1299 Executing or running ldd on a truncated executable does not
17084 # cause an out-of-memory condition.
17085 test_227() {
17086         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17087         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
17088
17089         dd if=$(which date) of=$MOUNT/date bs=1k count=1
17090         chmod +x $MOUNT/date
17091
17092         $MOUNT/date > /dev/null
17093         ldd $MOUNT/date > /dev/null
17094         rm -f $MOUNT/date
17095 }
17096 run_test 227 "running truncated executable does not cause OOM"
17097
17098 # LU-1512 try to reuse idle OI blocks
17099 test_228a() {
17100         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17101         remote_mds_nodsh && skip "remote MDS with nodsh"
17102         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17103
17104         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17105         local myDIR=$DIR/$tdir
17106
17107         mkdir -p $myDIR
17108         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17109         $LCTL set_param fail_loc=0x80001002
17110         createmany -o $myDIR/t- 10000
17111         $LCTL set_param fail_loc=0
17112         # The guard is current the largest FID holder
17113         touch $myDIR/guard
17114         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17115                     tr -d '[')
17116         local IDX=$(($SEQ % 64))
17117
17118         do_facet $SINGLEMDS sync
17119         # Make sure journal flushed.
17120         sleep 6
17121         local blk1=$(do_facet $SINGLEMDS \
17122                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17123                      grep Blockcount | awk '{print $4}')
17124
17125         # Remove old files, some OI blocks will become idle.
17126         unlinkmany $myDIR/t- 10000
17127         # Create new files, idle OI blocks should be reused.
17128         createmany -o $myDIR/t- 2000
17129         do_facet $SINGLEMDS sync
17130         # Make sure journal flushed.
17131         sleep 6
17132         local blk2=$(do_facet $SINGLEMDS \
17133                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17134                      grep Blockcount | awk '{print $4}')
17135
17136         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17137 }
17138 run_test 228a "try to reuse idle OI blocks"
17139
17140 test_228b() {
17141         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17142         remote_mds_nodsh && skip "remote MDS with nodsh"
17143         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17144
17145         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17146         local myDIR=$DIR/$tdir
17147
17148         mkdir -p $myDIR
17149         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17150         $LCTL set_param fail_loc=0x80001002
17151         createmany -o $myDIR/t- 10000
17152         $LCTL set_param fail_loc=0
17153         # The guard is current the largest FID holder
17154         touch $myDIR/guard
17155         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17156                     tr -d '[')
17157         local IDX=$(($SEQ % 64))
17158
17159         do_facet $SINGLEMDS sync
17160         # Make sure journal flushed.
17161         sleep 6
17162         local blk1=$(do_facet $SINGLEMDS \
17163                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17164                      grep Blockcount | awk '{print $4}')
17165
17166         # Remove old files, some OI blocks will become idle.
17167         unlinkmany $myDIR/t- 10000
17168
17169         # stop the MDT
17170         stop $SINGLEMDS || error "Fail to stop MDT."
17171         # remount the MDT
17172         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
17173
17174         df $MOUNT || error "Fail to df."
17175         # Create new files, idle OI blocks should be reused.
17176         createmany -o $myDIR/t- 2000
17177         do_facet $SINGLEMDS sync
17178         # Make sure journal flushed.
17179         sleep 6
17180         local blk2=$(do_facet $SINGLEMDS \
17181                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17182                      grep Blockcount | awk '{print $4}')
17183
17184         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17185 }
17186 run_test 228b "idle OI blocks can be reused after MDT restart"
17187
17188 #LU-1881
17189 test_228c() {
17190         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17191         remote_mds_nodsh && skip "remote MDS with nodsh"
17192         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17193
17194         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17195         local myDIR=$DIR/$tdir
17196
17197         mkdir -p $myDIR
17198         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17199         $LCTL set_param fail_loc=0x80001002
17200         # 20000 files can guarantee there are index nodes in the OI file
17201         createmany -o $myDIR/t- 20000
17202         $LCTL set_param fail_loc=0
17203         # The guard is current the largest FID holder
17204         touch $myDIR/guard
17205         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17206                     tr -d '[')
17207         local IDX=$(($SEQ % 64))
17208
17209         do_facet $SINGLEMDS sync
17210         # Make sure journal flushed.
17211         sleep 6
17212         local blk1=$(do_facet $SINGLEMDS \
17213                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17214                      grep Blockcount | awk '{print $4}')
17215
17216         # Remove old files, some OI blocks will become idle.
17217         unlinkmany $myDIR/t- 20000
17218         rm -f $myDIR/guard
17219         # The OI file should become empty now
17220
17221         # Create new files, idle OI blocks should be reused.
17222         createmany -o $myDIR/t- 2000
17223         do_facet $SINGLEMDS sync
17224         # Make sure journal flushed.
17225         sleep 6
17226         local blk2=$(do_facet $SINGLEMDS \
17227                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17228                      grep Blockcount | awk '{print $4}')
17229
17230         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17231 }
17232 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
17233
17234 test_229() { # LU-2482, LU-3448
17235         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17236         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
17237         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
17238                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
17239
17240         rm -f $DIR/$tfile
17241
17242         # Create a file with a released layout and stripe count 2.
17243         $MULTIOP $DIR/$tfile H2c ||
17244                 error "failed to create file with released layout"
17245
17246         $LFS getstripe -v $DIR/$tfile
17247
17248         local pattern=$($LFS getstripe -L $DIR/$tfile)
17249         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
17250
17251         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
17252                 error "getstripe"
17253         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
17254         stat $DIR/$tfile || error "failed to stat released file"
17255
17256         chown $RUNAS_ID $DIR/$tfile ||
17257                 error "chown $RUNAS_ID $DIR/$tfile failed"
17258
17259         chgrp $RUNAS_ID $DIR/$tfile ||
17260                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
17261
17262         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
17263         rm $DIR/$tfile || error "failed to remove released file"
17264 }
17265 run_test 229 "getstripe/stat/rm/attr changes work on released files"
17266
17267 test_230a() {
17268         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17269         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17270         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17271                 skip "Need MDS version at least 2.11.52"
17272
17273         local MDTIDX=1
17274
17275         test_mkdir $DIR/$tdir
17276         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
17277         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
17278         [ $mdt_idx -ne 0 ] &&
17279                 error "create local directory on wrong MDT $mdt_idx"
17280
17281         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
17282                         error "create remote directory failed"
17283         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
17284         [ $mdt_idx -ne $MDTIDX ] &&
17285                 error "create remote directory on wrong MDT $mdt_idx"
17286
17287         createmany -o $DIR/$tdir/test_230/t- 10 ||
17288                 error "create files on remote directory failed"
17289         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
17290         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
17291         rm -r $DIR/$tdir || error "unlink remote directory failed"
17292 }
17293 run_test 230a "Create remote directory and files under the remote directory"
17294
17295 test_230b() {
17296         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17297         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17298         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17299                 skip "Need MDS version at least 2.11.52"
17300
17301         local MDTIDX=1
17302         local mdt_index
17303         local i
17304         local file
17305         local pid
17306         local stripe_count
17307         local migrate_dir=$DIR/$tdir/migrate_dir
17308         local other_dir=$DIR/$tdir/other_dir
17309
17310         test_mkdir $DIR/$tdir
17311         test_mkdir -i0 -c1 $migrate_dir
17312         test_mkdir -i0 -c1 $other_dir
17313         for ((i=0; i<10; i++)); do
17314                 mkdir -p $migrate_dir/dir_${i}
17315                 createmany -o $migrate_dir/dir_${i}/f 10 ||
17316                         error "create files under remote dir failed $i"
17317         done
17318
17319         cp /etc/passwd $migrate_dir/$tfile
17320         cp /etc/passwd $other_dir/$tfile
17321         chattr +SAD $migrate_dir
17322         chattr +SAD $migrate_dir/$tfile
17323
17324         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17325         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17326         local old_dir_mode=$(stat -c%f $migrate_dir)
17327         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
17328
17329         mkdir -p $migrate_dir/dir_default_stripe2
17330         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
17331         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
17332
17333         mkdir -p $other_dir
17334         ln $migrate_dir/$tfile $other_dir/luna
17335         ln $migrate_dir/$tfile $migrate_dir/sofia
17336         ln $other_dir/$tfile $migrate_dir/david
17337         ln -s $migrate_dir/$tfile $other_dir/zachary
17338         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
17339         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
17340
17341         local len
17342         local lnktgt
17343
17344         # inline symlink
17345         for len in 58 59 60; do
17346                 lnktgt=$(str_repeat 'l' $len)
17347                 touch $migrate_dir/$lnktgt
17348                 ln -s $lnktgt $migrate_dir/${len}char_ln
17349         done
17350
17351         # PATH_MAX
17352         for len in 4094 4095; do
17353                 lnktgt=$(str_repeat 'l' $len)
17354                 ln -s $lnktgt $migrate_dir/${len}char_ln
17355         done
17356
17357         # NAME_MAX
17358         for len in 254 255; do
17359                 touch $migrate_dir/$(str_repeat 'l' $len)
17360         done
17361
17362         $LFS migrate -m $MDTIDX $migrate_dir ||
17363                 error "fails on migrating remote dir to MDT1"
17364
17365         echo "migratate to MDT1, then checking.."
17366         for ((i = 0; i < 10; i++)); do
17367                 for file in $(find $migrate_dir/dir_${i}); do
17368                         mdt_index=$($LFS getstripe -m $file)
17369                         # broken symlink getstripe will fail
17370                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
17371                                 error "$file is not on MDT${MDTIDX}"
17372                 done
17373         done
17374
17375         # the multiple link file should still in MDT0
17376         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
17377         [ $mdt_index == 0 ] ||
17378                 error "$file is not on MDT${MDTIDX}"
17379
17380         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17381         [ "$old_dir_flag" = "$new_dir_flag" ] ||
17382                 error " expect $old_dir_flag get $new_dir_flag"
17383
17384         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17385         [ "$old_file_flag" = "$new_file_flag" ] ||
17386                 error " expect $old_file_flag get $new_file_flag"
17387
17388         local new_dir_mode=$(stat -c%f $migrate_dir)
17389         [ "$old_dir_mode" = "$new_dir_mode" ] ||
17390                 error "expect mode $old_dir_mode get $new_dir_mode"
17391
17392         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
17393         [ "$old_file_mode" = "$new_file_mode" ] ||
17394                 error "expect mode $old_file_mode get $new_file_mode"
17395
17396         diff /etc/passwd $migrate_dir/$tfile ||
17397                 error "$tfile different after migration"
17398
17399         diff /etc/passwd $other_dir/luna ||
17400                 error "luna different after migration"
17401
17402         diff /etc/passwd $migrate_dir/sofia ||
17403                 error "sofia different after migration"
17404
17405         diff /etc/passwd $migrate_dir/david ||
17406                 error "david different after migration"
17407
17408         diff /etc/passwd $other_dir/zachary ||
17409                 error "zachary different after migration"
17410
17411         diff /etc/passwd $migrate_dir/${tfile}_ln ||
17412                 error "${tfile}_ln different after migration"
17413
17414         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
17415                 error "${tfile}_ln_other different after migration"
17416
17417         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
17418         [ $stripe_count = 2 ] ||
17419                 error "dir strpe_count $d != 2 after migration."
17420
17421         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
17422         [ $stripe_count = 2 ] ||
17423                 error "file strpe_count $d != 2 after migration."
17424
17425         #migrate back to MDT0
17426         MDTIDX=0
17427
17428         $LFS migrate -m $MDTIDX $migrate_dir ||
17429                 error "fails on migrating remote dir to MDT0"
17430
17431         echo "migrate back to MDT0, checking.."
17432         for file in $(find $migrate_dir); do
17433                 mdt_index=$($LFS getstripe -m $file)
17434                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
17435                         error "$file is not on MDT${MDTIDX}"
17436         done
17437
17438         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17439         [ "$old_dir_flag" = "$new_dir_flag" ] ||
17440                 error " expect $old_dir_flag get $new_dir_flag"
17441
17442         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17443         [ "$old_file_flag" = "$new_file_flag" ] ||
17444                 error " expect $old_file_flag get $new_file_flag"
17445
17446         local new_dir_mode=$(stat -c%f $migrate_dir)
17447         [ "$old_dir_mode" = "$new_dir_mode" ] ||
17448                 error "expect mode $old_dir_mode get $new_dir_mode"
17449
17450         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
17451         [ "$old_file_mode" = "$new_file_mode" ] ||
17452                 error "expect mode $old_file_mode get $new_file_mode"
17453
17454         diff /etc/passwd ${migrate_dir}/$tfile ||
17455                 error "$tfile different after migration"
17456
17457         diff /etc/passwd ${other_dir}/luna ||
17458                 error "luna different after migration"
17459
17460         diff /etc/passwd ${migrate_dir}/sofia ||
17461                 error "sofia different after migration"
17462
17463         diff /etc/passwd ${other_dir}/zachary ||
17464                 error "zachary different after migration"
17465
17466         diff /etc/passwd $migrate_dir/${tfile}_ln ||
17467                 error "${tfile}_ln different after migration"
17468
17469         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
17470                 error "${tfile}_ln_other different after migration"
17471
17472         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
17473         [ $stripe_count = 2 ] ||
17474                 error "dir strpe_count $d != 2 after migration."
17475
17476         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
17477         [ $stripe_count = 2 ] ||
17478                 error "file strpe_count $d != 2 after migration."
17479
17480         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17481 }
17482 run_test 230b "migrate directory"
17483
17484 test_230c() {
17485         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17486         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17487         remote_mds_nodsh && skip "remote MDS with nodsh"
17488         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17489                 skip "Need MDS version at least 2.11.52"
17490
17491         local MDTIDX=1
17492         local total=3
17493         local mdt_index
17494         local file
17495         local migrate_dir=$DIR/$tdir/migrate_dir
17496
17497         #If migrating directory fails in the middle, all entries of
17498         #the directory is still accessiable.
17499         test_mkdir $DIR/$tdir
17500         test_mkdir -i0 -c1 $migrate_dir
17501         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
17502         stat $migrate_dir
17503         createmany -o $migrate_dir/f $total ||
17504                 error "create files under ${migrate_dir} failed"
17505
17506         # fail after migrating top dir, and this will fail only once, so the
17507         # first sub file migration will fail (currently f3), others succeed.
17508         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
17509         do_facet mds1 lctl set_param fail_loc=0x1801
17510         local t=$(ls $migrate_dir | wc -l)
17511         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
17512                 error "migrate should fail"
17513         local u=$(ls $migrate_dir | wc -l)
17514         [ "$u" == "$t" ] || error "$u != $t during migration"
17515
17516         # add new dir/file should succeed
17517         mkdir $migrate_dir/dir ||
17518                 error "mkdir failed under migrating directory"
17519         touch $migrate_dir/file ||
17520                 error "create file failed under migrating directory"
17521
17522         # add file with existing name should fail
17523         for file in $migrate_dir/f*; do
17524                 stat $file > /dev/null || error "stat $file failed"
17525                 $OPENFILE -f O_CREAT:O_EXCL $file &&
17526                         error "open(O_CREAT|O_EXCL) $file should fail"
17527                 $MULTIOP $file m && error "create $file should fail"
17528                 touch $DIR/$tdir/remote_dir/$tfile ||
17529                         error "touch $tfile failed"
17530                 ln $DIR/$tdir/remote_dir/$tfile $file &&
17531                         error "link $file should fail"
17532                 mdt_index=$($LFS getstripe -m $file)
17533                 if [ $mdt_index == 0 ]; then
17534                         # file failed to migrate is not allowed to rename to
17535                         mv $DIR/$tdir/remote_dir/$tfile $file &&
17536                                 error "rename to $file should fail"
17537                 else
17538                         mv $DIR/$tdir/remote_dir/$tfile $file ||
17539                                 error "rename to $file failed"
17540                 fi
17541                 echo hello >> $file || error "write $file failed"
17542         done
17543
17544         # resume migration with different options should fail
17545         $LFS migrate -m 0 $migrate_dir &&
17546                 error "migrate -m 0 $migrate_dir should fail"
17547
17548         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
17549                 error "migrate -c 2 $migrate_dir should fail"
17550
17551         # resume migration should succeed
17552         $LFS migrate -m $MDTIDX $migrate_dir ||
17553                 error "migrate $migrate_dir failed"
17554
17555         echo "Finish migration, then checking.."
17556         for file in $(find $migrate_dir); do
17557                 mdt_index=$($LFS getstripe -m $file)
17558                 [ $mdt_index == $MDTIDX ] ||
17559                         error "$file is not on MDT${MDTIDX}"
17560         done
17561
17562         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17563 }
17564 run_test 230c "check directory accessiblity if migration failed"
17565
17566 test_230d() {
17567         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17568         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17569         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17570                 skip "Need MDS version at least 2.11.52"
17571         # LU-11235
17572         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
17573
17574         local migrate_dir=$DIR/$tdir/migrate_dir
17575         local old_index
17576         local new_index
17577         local old_count
17578         local new_count
17579         local new_hash
17580         local mdt_index
17581         local i
17582         local j
17583
17584         old_index=$((RANDOM % MDSCOUNT))
17585         old_count=$((MDSCOUNT - old_index))
17586         new_index=$((RANDOM % MDSCOUNT))
17587         new_count=$((MDSCOUNT - new_index))
17588         new_hash=1 # for all_char
17589
17590         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
17591         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
17592
17593         test_mkdir $DIR/$tdir
17594         test_mkdir -i $old_index -c $old_count $migrate_dir
17595
17596         for ((i=0; i<100; i++)); do
17597                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
17598                 createmany -o $migrate_dir/dir_${i}/f 100 ||
17599                         error "create files under remote dir failed $i"
17600         done
17601
17602         echo -n "Migrate from MDT$old_index "
17603         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
17604         echo -n "to MDT$new_index"
17605         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
17606         echo
17607
17608         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
17609         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
17610                 error "migrate remote dir error"
17611
17612         echo "Finish migration, then checking.."
17613         for file in $(find $migrate_dir); do
17614                 mdt_index=$($LFS getstripe -m $file)
17615                 if [ $mdt_index -lt $new_index ] ||
17616                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
17617                         error "$file is on MDT$mdt_index"
17618                 fi
17619         done
17620
17621         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17622 }
17623 run_test 230d "check migrate big directory"
17624
17625 test_230e() {
17626         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17627         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17628         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17629                 skip "Need MDS version at least 2.11.52"
17630
17631         local i
17632         local j
17633         local a_fid
17634         local b_fid
17635
17636         mkdir -p $DIR/$tdir
17637         mkdir $DIR/$tdir/migrate_dir
17638         mkdir $DIR/$tdir/other_dir
17639         touch $DIR/$tdir/migrate_dir/a
17640         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
17641         ls $DIR/$tdir/other_dir
17642
17643         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
17644                 error "migrate dir fails"
17645
17646         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
17647         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
17648
17649         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17650         [ $mdt_index == 0 ] || error "a is not on MDT0"
17651
17652         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
17653                 error "migrate dir fails"
17654
17655         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
17656         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
17657
17658         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17659         [ $mdt_index == 1 ] || error "a is not on MDT1"
17660
17661         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
17662         [ $mdt_index == 1 ] || error "b is not on MDT1"
17663
17664         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
17665         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
17666
17667         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
17668
17669         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17670 }
17671 run_test 230e "migrate mulitple local link files"
17672
17673 test_230f() {
17674         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17675         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17676         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17677                 skip "Need MDS version at least 2.11.52"
17678
17679         local a_fid
17680         local ln_fid
17681
17682         mkdir -p $DIR/$tdir
17683         mkdir $DIR/$tdir/migrate_dir
17684         $LFS mkdir -i1 $DIR/$tdir/other_dir
17685         touch $DIR/$tdir/migrate_dir/a
17686         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
17687         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
17688         ls $DIR/$tdir/other_dir
17689
17690         # a should be migrated to MDT1, since no other links on MDT0
17691         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
17692                 error "#1 migrate dir fails"
17693         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
17694         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
17695         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17696         [ $mdt_index == 1 ] || error "a is not on MDT1"
17697
17698         # a should stay on MDT1, because it is a mulitple link file
17699         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
17700                 error "#2 migrate dir fails"
17701         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17702         [ $mdt_index == 1 ] || error "a is not on MDT1"
17703
17704         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
17705                 error "#3 migrate dir fails"
17706
17707         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
17708         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
17709         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
17710
17711         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
17712         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
17713
17714         # a should be migrated to MDT0, since no other links on MDT1
17715         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
17716                 error "#4 migrate dir fails"
17717         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17718         [ $mdt_index == 0 ] || error "a is not on MDT0"
17719
17720         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17721 }
17722 run_test 230f "migrate mulitple remote link files"
17723
17724 test_230g() {
17725         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17726         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17727         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17728                 skip "Need MDS version at least 2.11.52"
17729
17730         mkdir -p $DIR/$tdir/migrate_dir
17731
17732         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
17733                 error "migrating dir to non-exist MDT succeeds"
17734         true
17735 }
17736 run_test 230g "migrate dir to non-exist MDT"
17737
17738 test_230h() {
17739         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17740         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17741         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17742                 skip "Need MDS version at least 2.11.52"
17743
17744         local mdt_index
17745
17746         mkdir -p $DIR/$tdir/migrate_dir
17747
17748         $LFS migrate -m1 $DIR &&
17749                 error "migrating mountpoint1 should fail"
17750
17751         $LFS migrate -m1 $DIR/$tdir/.. &&
17752                 error "migrating mountpoint2 should fail"
17753
17754         # same as mv
17755         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
17756                 error "migrating $tdir/migrate_dir/.. should fail"
17757
17758         true
17759 }
17760 run_test 230h "migrate .. and root"
17761
17762 test_230i() {
17763         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17764         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17765         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17766                 skip "Need MDS version at least 2.11.52"
17767
17768         mkdir -p $DIR/$tdir/migrate_dir
17769
17770         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
17771                 error "migration fails with a tailing slash"
17772
17773         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
17774                 error "migration fails with two tailing slashes"
17775 }
17776 run_test 230i "lfs migrate -m tolerates trailing slashes"
17777
17778 test_230j() {
17779         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
17780         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
17781                 skip "Need MDS version at least 2.11.52"
17782
17783         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
17784         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
17785                 error "create $tfile failed"
17786         cat /etc/passwd > $DIR/$tdir/$tfile
17787
17788         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
17789
17790         cmp /etc/passwd $DIR/$tdir/$tfile ||
17791                 error "DoM file mismatch after migration"
17792 }
17793 run_test 230j "DoM file data not changed after dir migration"
17794
17795 test_230k() {
17796         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
17797         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
17798                 skip "Need MDS version at least 2.11.56"
17799
17800         local total=20
17801         local files_on_starting_mdt=0
17802
17803         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
17804         $LFS getdirstripe $DIR/$tdir
17805         for i in $(seq $total); do
17806                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
17807                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
17808                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
17809         done
17810
17811         echo "$files_on_starting_mdt files on MDT0"
17812
17813         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
17814         $LFS getdirstripe $DIR/$tdir
17815
17816         files_on_starting_mdt=0
17817         for i in $(seq $total); do
17818                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
17819                         error "file $tfile.$i mismatch after migration"
17820                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
17821                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
17822         done
17823
17824         echo "$files_on_starting_mdt files on MDT1 after migration"
17825         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
17826
17827         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
17828         $LFS getdirstripe $DIR/$tdir
17829
17830         files_on_starting_mdt=0
17831         for i in $(seq $total); do
17832                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
17833                         error "file $tfile.$i mismatch after 2nd migration"
17834                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
17835                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
17836         done
17837
17838         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
17839         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
17840
17841         true
17842 }
17843 run_test 230k "file data not changed after dir migration"
17844
17845 test_230l() {
17846         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
17847         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
17848                 skip "Need MDS version at least 2.11.56"
17849
17850         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
17851         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
17852                 error "create files under remote dir failed $i"
17853         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
17854 }
17855 run_test 230l "readdir between MDTs won't crash"
17856
17857 test_230m() {
17858         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
17859         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
17860                 skip "Need MDS version at least 2.11.56"
17861
17862         local MDTIDX=1
17863         local mig_dir=$DIR/$tdir/migrate_dir
17864         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
17865         local shortstr="b"
17866         local val
17867
17868         echo "Creating files and dirs with xattrs"
17869         test_mkdir $DIR/$tdir
17870         test_mkdir -i0 -c1 $mig_dir
17871         mkdir $mig_dir/dir
17872         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
17873                 error "cannot set xattr attr1 on dir"
17874         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
17875                 error "cannot set xattr attr2 on dir"
17876         touch $mig_dir/dir/f0
17877         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
17878                 error "cannot set xattr attr1 on file"
17879         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
17880                 error "cannot set xattr attr2 on file"
17881         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
17882         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
17883         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
17884         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
17885         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
17886         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
17887         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
17888         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
17889         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
17890
17891         echo "Migrating to MDT1"
17892         $LFS migrate -m $MDTIDX $mig_dir ||
17893                 error "fails on migrating dir to MDT1"
17894
17895         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
17896         echo "Checking xattrs"
17897         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
17898         [ "$val" = $longstr ] ||
17899                 error "expecting xattr1 $longstr on dir, found $val"
17900         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
17901         [ "$val" = $shortstr ] ||
17902                 error "expecting xattr2 $shortstr on dir, found $val"
17903         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
17904         [ "$val" = $longstr ] ||
17905                 error "expecting xattr1 $longstr on file, found $val"
17906         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
17907         [ "$val" = $shortstr ] ||
17908                 error "expecting xattr2 $shortstr on file, found $val"
17909 }
17910 run_test 230m "xattrs not changed after dir migration"
17911
17912 test_230n() {
17913         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
17914         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
17915                 skip "Need MDS version at least 2.13.53"
17916
17917         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
17918         cat /etc/hosts > $DIR/$tdir/$tfile
17919         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
17920         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
17921
17922         cmp /etc/hosts $DIR/$tdir/$tfile ||
17923                 error "File data mismatch after migration"
17924 }
17925 run_test 230n "Dir migration with mirrored file"
17926
17927 test_230o() {
17928         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
17929         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
17930                 skip "Need MDS version at least 2.13.52"
17931
17932         local mdts=$(comma_list $(mdts_nodes))
17933
17934         local restripe_status
17935         local delta
17936         local i
17937         local j
17938
17939         # in case "crush" hash type is not set
17940         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
17941
17942         restripe_status=$(do_facet mds1 $LCTL get_param -n \
17943                            mdt.*MDT0000.enable_dir_restripe)
17944         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
17945         stack_trap "do_nodes $mdts $LCTL set_param \
17946                     mdt.*.enable_dir_restripe=$restripe_status"
17947
17948         mkdir $DIR/$tdir
17949         createmany -m $DIR/$tdir/f 100 ||
17950                 error "create files under remote dir failed $i"
17951         createmany -d $DIR/$tdir/d 100 ||
17952                 error "create dirs under remote dir failed $i"
17953
17954         for i in $(seq 2 $MDSCOUNT); do
17955                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
17956                 $LFS setdirstripe -c $i $DIR/$tdir ||
17957                         error "split -c $i $tdir failed"
17958                 wait_update $HOSTNAME \
17959                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 100 ||
17960                         error "dir split not finished"
17961                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
17962                         awk '/migrate/ {sum += $2} END { print sum }')
17963                 echo "$delta files migrated when dir split from $((i - 1)) to $i stripes"
17964                 # delta is around total_files/stripe_count
17965                 [ $delta -lt $((200 /(i - 1))) ] ||
17966                         error "$delta files migrated"
17967         done
17968 }
17969 run_test 230o "dir split"
17970
17971 test_230p() {
17972         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
17973         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
17974                 skip "Need MDS version at least 2.13.52"
17975
17976         local mdts=$(comma_list $(mdts_nodes))
17977
17978         local restripe_status
17979         local delta
17980         local i
17981         local j
17982
17983         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
17984
17985         restripe_status=$(do_facet mds1 $LCTL get_param -n \
17986                            mdt.*MDT0000.enable_dir_restripe)
17987         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
17988         stack_trap "do_nodes $mdts $LCTL set_param \
17989                     mdt.*.enable_dir_restripe=$restripe_status"
17990
17991         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
17992         createmany -m $DIR/$tdir/f 100 ||
17993                 error "create files under remote dir failed $i"
17994         createmany -d $DIR/$tdir/d 100 ||
17995                 error "create dirs under remote dir failed $i"
17996
17997         for i in $(seq $((MDSCOUNT - 1)) -1 1); do
17998                 local mdt_hash="crush"
17999
18000                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
18001                 $LFS setdirstripe -c $i $DIR/$tdir ||
18002                         error "split -c $i $tdir failed"
18003                 [ $i -eq 1 ] && mdt_hash="none"
18004                 wait_update $HOSTNAME \
18005                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash 100 ||
18006                         error "dir merge not finished"
18007                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18008                         awk '/migrate/ {sum += $2} END { print sum }')
18009                 echo "$delta files migrated when dir merge from $((i + 1)) to $i stripes"
18010                 # delta is around total_files/stripe_count
18011                 [ $delta -lt $((200 / i)) ] ||
18012                         error "$delta files migrated"
18013         done
18014 }
18015 run_test 230p "dir merge"
18016
18017 test_230q() {
18018         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18019         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18020                 skip "Need MDS version at least 2.13.52"
18021
18022         local mdts=$(comma_list $(mdts_nodes))
18023         local saved_threshold=$(do_facet mds1 \
18024                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
18025         local saved_delta=$(do_facet mds1 \
18026                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
18027         local threshold=100
18028         local delta=2
18029         local total=0
18030         local stripe_count=0
18031         local stripe_index
18032         local nr_files
18033
18034         stack_trap "do_nodes $mdts $LCTL set_param \
18035                     mdt.*.dir_split_count=$saved_threshold"
18036         stack_trap "do_nodes $mdts $LCTL set_param \
18037                     mdt.*.dir_split_delta=$saved_delta"
18038         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
18039         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
18040         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
18041         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
18042         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
18043         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18044
18045         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
18046         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
18047
18048         while [ $stripe_count -lt $MDSCOUNT ]; do
18049                 createmany -m $DIR/$tdir/f $total $((threshold * 3 / 2)) ||
18050                         error "create sub files failed"
18051                 stat $DIR/$tdir > /dev/null
18052                 total=$((total + threshold * 3 / 2))
18053                 stripe_count=$((stripe_count + delta))
18054                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
18055
18056                 wait_update $HOSTNAME \
18057                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
18058                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
18059
18060                 wait_update $HOSTNAME \
18061                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
18062                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
18063
18064                 nr_files=$($LFS getstripe -m $DIR/$tdir/* |
18065                            grep -w $stripe_index | wc -l)
18066                 echo "$nr_files files on MDT$stripe_index after split"
18067                 [ $nr_files -lt $((total / (stripe_count - 1))) ] ||
18068                         error "$nr_files files on MDT$stripe_index after split"
18069
18070                 nr_files=$(ls $DIR/$tdir | wc -w)
18071                 [ $nr_files -eq $total ] ||
18072                         error "total sub files $nr_files != $total"
18073         done
18074 }
18075 run_test 230q "dir auto split"
18076
18077 test_231a()
18078 {
18079         # For simplicity this test assumes that max_pages_per_rpc
18080         # is the same across all OSCs
18081         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
18082         local bulk_size=$((max_pages * PAGE_SIZE))
18083         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
18084                                        head -n 1)
18085
18086         mkdir -p $DIR/$tdir
18087         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
18088                 error "failed to set stripe with -S ${brw_size}M option"
18089
18090         # clear the OSC stats
18091         $LCTL set_param osc.*.stats=0 &>/dev/null
18092         stop_writeback
18093
18094         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
18095         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
18096                 oflag=direct &>/dev/null || error "dd failed"
18097
18098         sync; sleep 1; sync # just to be safe
18099         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
18100         if [ x$nrpcs != "x1" ]; then
18101                 $LCTL get_param osc.*.stats
18102                 error "found $nrpcs ost_write RPCs, not 1 as expected"
18103         fi
18104
18105         start_writeback
18106         # Drop the OSC cache, otherwise we will read from it
18107         cancel_lru_locks osc
18108
18109         # clear the OSC stats
18110         $LCTL set_param osc.*.stats=0 &>/dev/null
18111
18112         # Client reads $bulk_size.
18113         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
18114                 iflag=direct &>/dev/null || error "dd failed"
18115
18116         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
18117         if [ x$nrpcs != "x1" ]; then
18118                 $LCTL get_param osc.*.stats
18119                 error "found $nrpcs ost_read RPCs, not 1 as expected"
18120         fi
18121 }
18122 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
18123
18124 test_231b() {
18125         mkdir -p $DIR/$tdir
18126         local i
18127         for i in {0..1023}; do
18128                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
18129                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
18130                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
18131         done
18132         sync
18133 }
18134 run_test 231b "must not assert on fully utilized OST request buffer"
18135
18136 test_232a() {
18137         mkdir -p $DIR/$tdir
18138         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
18139
18140         #define OBD_FAIL_LDLM_OST_LVB            0x31c
18141         do_facet ost1 $LCTL set_param fail_loc=0x31c
18142
18143         # ignore dd failure
18144         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
18145
18146         do_facet ost1 $LCTL set_param fail_loc=0
18147         umount_client $MOUNT || error "umount failed"
18148         mount_client $MOUNT || error "mount failed"
18149         stop ost1 || error "cannot stop ost1"
18150         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18151 }
18152 run_test 232a "failed lock should not block umount"
18153
18154 test_232b() {
18155         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
18156                 skip "Need MDS version at least 2.10.58"
18157
18158         mkdir -p $DIR/$tdir
18159         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
18160         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
18161         sync
18162         cancel_lru_locks osc
18163
18164         #define OBD_FAIL_LDLM_OST_LVB            0x31c
18165         do_facet ost1 $LCTL set_param fail_loc=0x31c
18166
18167         # ignore failure
18168         $LFS data_version $DIR/$tdir/$tfile || true
18169
18170         do_facet ost1 $LCTL set_param fail_loc=0
18171         umount_client $MOUNT || error "umount failed"
18172         mount_client $MOUNT || error "mount failed"
18173         stop ost1 || error "cannot stop ost1"
18174         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18175 }
18176 run_test 232b "failed data version lock should not block umount"
18177
18178 test_233a() {
18179         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
18180                 skip "Need MDS version at least 2.3.64"
18181         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
18182
18183         local fid=$($LFS path2fid $MOUNT)
18184
18185         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18186                 error "cannot access $MOUNT using its FID '$fid'"
18187 }
18188 run_test 233a "checking that OBF of the FS root succeeds"
18189
18190 test_233b() {
18191         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
18192                 skip "Need MDS version at least 2.5.90"
18193         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
18194
18195         local fid=$($LFS path2fid $MOUNT/.lustre)
18196
18197         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18198                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
18199
18200         fid=$($LFS path2fid $MOUNT/.lustre/fid)
18201         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18202                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
18203 }
18204 run_test 233b "checking that OBF of the FS .lustre succeeds"
18205
18206 test_234() {
18207         local p="$TMP/sanityN-$TESTNAME.parameters"
18208         save_lustre_params client "llite.*.xattr_cache" > $p
18209         lctl set_param llite.*.xattr_cache 1 ||
18210                 skip_env "xattr cache is not supported"
18211
18212         mkdir -p $DIR/$tdir || error "mkdir failed"
18213         touch $DIR/$tdir/$tfile || error "touch failed"
18214         # OBD_FAIL_LLITE_XATTR_ENOMEM
18215         $LCTL set_param fail_loc=0x1405
18216         getfattr -n user.attr $DIR/$tdir/$tfile &&
18217                 error "getfattr should have failed with ENOMEM"
18218         $LCTL set_param fail_loc=0x0
18219         rm -rf $DIR/$tdir
18220
18221         restore_lustre_params < $p
18222         rm -f $p
18223 }
18224 run_test 234 "xattr cache should not crash on ENOMEM"
18225
18226 test_235() {
18227         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
18228                 skip "Need MDS version at least 2.4.52"
18229
18230         flock_deadlock $DIR/$tfile
18231         local RC=$?
18232         case $RC in
18233                 0)
18234                 ;;
18235                 124) error "process hangs on a deadlock"
18236                 ;;
18237                 *) error "error executing flock_deadlock $DIR/$tfile"
18238                 ;;
18239         esac
18240 }
18241 run_test 235 "LU-1715: flock deadlock detection does not work properly"
18242
18243 #LU-2935
18244 test_236() {
18245         check_swap_layouts_support
18246
18247         local ref1=/etc/passwd
18248         local ref2=/etc/group
18249         local file1=$DIR/$tdir/f1
18250         local file2=$DIR/$tdir/f2
18251
18252         test_mkdir -c1 $DIR/$tdir
18253         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
18254         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
18255         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
18256         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
18257         local fd=$(free_fd)
18258         local cmd="exec $fd<>$file2"
18259         eval $cmd
18260         rm $file2
18261         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
18262                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
18263         cmd="exec $fd>&-"
18264         eval $cmd
18265         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
18266
18267         #cleanup
18268         rm -rf $DIR/$tdir
18269 }
18270 run_test 236 "Layout swap on open unlinked file"
18271
18272 # LU-4659 linkea consistency
18273 test_238() {
18274         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
18275                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
18276                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
18277                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
18278
18279         touch $DIR/$tfile
18280         ln $DIR/$tfile $DIR/$tfile.lnk
18281         touch $DIR/$tfile.new
18282         mv $DIR/$tfile.new $DIR/$tfile
18283         local fid1=$($LFS path2fid $DIR/$tfile)
18284         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
18285         local path1=$($LFS fid2path $FSNAME "$fid1")
18286         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
18287         local path2=$($LFS fid2path $FSNAME "$fid2")
18288         [ $tfile.lnk == $path2 ] ||
18289                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
18290         rm -f $DIR/$tfile*
18291 }
18292 run_test 238 "Verify linkea consistency"
18293
18294 test_239A() { # was test_239
18295         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
18296                 skip "Need MDS version at least 2.5.60"
18297
18298         local list=$(comma_list $(mdts_nodes))
18299
18300         mkdir -p $DIR/$tdir
18301         createmany -o $DIR/$tdir/f- 5000
18302         unlinkmany $DIR/$tdir/f- 5000
18303         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
18304                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
18305         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
18306                         osp.*MDT*.sync_in_flight" | calc_sum)
18307         [ "$changes" -eq 0 ] || error "$changes not synced"
18308 }
18309 run_test 239A "osp_sync test"
18310
18311 test_239a() { #LU-5297
18312         remote_mds_nodsh && skip "remote MDS with nodsh"
18313
18314         touch $DIR/$tfile
18315         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
18316         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
18317         chgrp $RUNAS_GID $DIR/$tfile
18318         wait_delete_completed
18319 }
18320 run_test 239a "process invalid osp sync record correctly"
18321
18322 test_239b() { #LU-5297
18323         remote_mds_nodsh && skip "remote MDS with nodsh"
18324
18325         touch $DIR/$tfile1
18326         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
18327         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
18328         chgrp $RUNAS_GID $DIR/$tfile1
18329         wait_delete_completed
18330         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
18331         touch $DIR/$tfile2
18332         chgrp $RUNAS_GID $DIR/$tfile2
18333         wait_delete_completed
18334 }
18335 run_test 239b "process osp sync record with ENOMEM error correctly"
18336
18337 test_240() {
18338         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18339         remote_mds_nodsh && skip "remote MDS with nodsh"
18340
18341         mkdir -p $DIR/$tdir
18342
18343         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
18344                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
18345         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
18346                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
18347
18348         umount_client $MOUNT || error "umount failed"
18349         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
18350         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
18351         mount_client $MOUNT || error "failed to mount client"
18352
18353         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
18354         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
18355 }
18356 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
18357
18358 test_241_bio() {
18359         local count=$1
18360         local bsize=$2
18361
18362         for LOOP in $(seq $count); do
18363                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
18364                 cancel_lru_locks $OSC || true
18365         done
18366 }
18367
18368 test_241_dio() {
18369         local count=$1
18370         local bsize=$2
18371
18372         for LOOP in $(seq $1); do
18373                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
18374                         2>/dev/null
18375         done
18376 }
18377
18378 test_241a() { # was test_241
18379         local bsize=$PAGE_SIZE
18380
18381         (( bsize < 40960 )) && bsize=40960
18382         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
18383         ls -la $DIR/$tfile
18384         cancel_lru_locks $OSC
18385         test_241_bio 1000 $bsize &
18386         PID=$!
18387         test_241_dio 1000 $bsize
18388         wait $PID
18389 }
18390 run_test 241a "bio vs dio"
18391
18392 test_241b() {
18393         local bsize=$PAGE_SIZE
18394
18395         (( bsize < 40960 )) && bsize=40960
18396         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
18397         ls -la $DIR/$tfile
18398         test_241_dio 1000 $bsize &
18399         PID=$!
18400         test_241_dio 1000 $bsize
18401         wait $PID
18402 }
18403 run_test 241b "dio vs dio"
18404
18405 test_242() {
18406         remote_mds_nodsh && skip "remote MDS with nodsh"
18407
18408         mkdir -p $DIR/$tdir
18409         touch $DIR/$tdir/$tfile
18410
18411         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
18412         do_facet mds1 lctl set_param fail_loc=0x105
18413         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
18414
18415         do_facet mds1 lctl set_param fail_loc=0
18416         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
18417 }
18418 run_test 242 "mdt_readpage failure should not cause directory unreadable"
18419
18420 test_243()
18421 {
18422         test_mkdir $DIR/$tdir
18423         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
18424 }
18425 run_test 243 "various group lock tests"
18426
18427 test_244a()
18428 {
18429         test_mkdir $DIR/$tdir
18430         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
18431         sendfile_grouplock $DIR/$tdir/$tfile || \
18432                 error "sendfile+grouplock failed"
18433         rm -rf $DIR/$tdir
18434 }
18435 run_test 244a "sendfile with group lock tests"
18436
18437 test_244b()
18438 {
18439         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
18440
18441         local threads=50
18442         local size=$((1024*1024))
18443
18444         test_mkdir $DIR/$tdir
18445         for i in $(seq 1 $threads); do
18446                 local file=$DIR/$tdir/file_$((i / 10))
18447                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
18448                 local pids[$i]=$!
18449         done
18450         for i in $(seq 1 $threads); do
18451                 wait ${pids[$i]}
18452         done
18453 }
18454 run_test 244b "multi-threaded write with group lock"
18455
18456 test_245() {
18457         local flagname="multi_mod_rpcs"
18458         local connect_data_name="max_mod_rpcs"
18459         local out
18460
18461         # check if multiple modify RPCs flag is set
18462         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
18463                 grep "connect_flags:")
18464         echo "$out"
18465
18466         echo "$out" | grep -qw $flagname
18467         if [ $? -ne 0 ]; then
18468                 echo "connect flag $flagname is not set"
18469                 return
18470         fi
18471
18472         # check if multiple modify RPCs data is set
18473         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
18474         echo "$out"
18475
18476         echo "$out" | grep -qw $connect_data_name ||
18477                 error "import should have connect data $connect_data_name"
18478 }
18479 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
18480
18481 cleanup_247() {
18482         local submount=$1
18483
18484         trap 0
18485         umount_client $submount
18486         rmdir $submount
18487 }
18488
18489 test_247a() {
18490         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
18491                 grep -q subtree ||
18492                 skip_env "Fileset feature is not supported"
18493
18494         local submount=${MOUNT}_$tdir
18495
18496         mkdir $MOUNT/$tdir
18497         mkdir -p $submount || error "mkdir $submount failed"
18498         FILESET="$FILESET/$tdir" mount_client $submount ||
18499                 error "mount $submount failed"
18500         trap "cleanup_247 $submount" EXIT
18501         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
18502         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
18503                 error "read $MOUNT/$tdir/$tfile failed"
18504         cleanup_247 $submount
18505 }
18506 run_test 247a "mount subdir as fileset"
18507
18508 test_247b() {
18509         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18510                 skip_env "Fileset feature is not supported"
18511
18512         local submount=${MOUNT}_$tdir
18513
18514         rm -rf $MOUNT/$tdir
18515         mkdir -p $submount || error "mkdir $submount failed"
18516         SKIP_FILESET=1
18517         FILESET="$FILESET/$tdir" mount_client $submount &&
18518                 error "mount $submount should fail"
18519         rmdir $submount
18520 }
18521 run_test 247b "mount subdir that dose not exist"
18522
18523 test_247c() {
18524         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18525                 skip_env "Fileset feature is not supported"
18526
18527         local submount=${MOUNT}_$tdir
18528
18529         mkdir -p $MOUNT/$tdir/dir1
18530         mkdir -p $submount || error "mkdir $submount failed"
18531         trap "cleanup_247 $submount" EXIT
18532         FILESET="$FILESET/$tdir" mount_client $submount ||
18533                 error "mount $submount failed"
18534         local fid=$($LFS path2fid $MOUNT/)
18535         $LFS fid2path $submount $fid && error "fid2path should fail"
18536         cleanup_247 $submount
18537 }
18538 run_test 247c "running fid2path outside root"
18539
18540 test_247d() {
18541         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18542                 skip "Fileset feature is not supported"
18543
18544         local submount=${MOUNT}_$tdir
18545
18546         mkdir -p $MOUNT/$tdir/dir1
18547         mkdir -p $submount || error "mkdir $submount failed"
18548         FILESET="$FILESET/$tdir" mount_client $submount ||
18549                 error "mount $submount failed"
18550         trap "cleanup_247 $submount" EXIT
18551         local fid=$($LFS path2fid $submount/dir1)
18552         $LFS fid2path $submount $fid || error "fid2path should succeed"
18553         cleanup_247 $submount
18554 }
18555 run_test 247d "running fid2path inside root"
18556
18557 # LU-8037
18558 test_247e() {
18559         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
18560                 grep -q subtree ||
18561                 skip "Fileset feature is not supported"
18562
18563         local submount=${MOUNT}_$tdir
18564
18565         mkdir $MOUNT/$tdir
18566         mkdir -p $submount || error "mkdir $submount failed"
18567         FILESET="$FILESET/.." mount_client $submount &&
18568                 error "mount $submount should fail"
18569         rmdir $submount
18570 }
18571 run_test 247e "mount .. as fileset"
18572
18573 test_247f() {
18574         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18575         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
18576                 skip "Need at least version 2.13.52"
18577         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
18578                 grep -q subtree ||
18579                 skip "Fileset feature is not supported"
18580
18581         mkdir $DIR/$tdir || error "mkdir $tdir failed"
18582         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
18583                 error "mkdir remote failed"
18584         mkdir $DIR/$tdir/remote/subdir || error "mkdir remote/subdir failed"
18585         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped ||
18586                 error "mkdir striped failed"
18587         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
18588
18589         local submount=${MOUNT}_$tdir
18590
18591         mkdir -p $submount || error "mkdir $submount failed"
18592
18593         local dir
18594         local fileset=$FILESET
18595
18596         for dir in $tdir/remote $tdir/remote/subdir \
18597                    $tdir/striped $tdir/striped/subdir $tdir/striped/. ; do
18598                 FILESET="$fileset/$dir" mount_client $submount ||
18599                         error "mount $dir failed"
18600                 umount_client $submount
18601         done
18602 }
18603 run_test 247f "mount striped or remote directory as fileset"
18604
18605 test_248a() {
18606         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
18607         [ -z "$fast_read_sav" ] && skip "no fast read support"
18608
18609         # create a large file for fast read verification
18610         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
18611
18612         # make sure the file is created correctly
18613         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
18614                 { rm -f $DIR/$tfile; skip "file creation error"; }
18615
18616         echo "Test 1: verify that fast read is 4 times faster on cache read"
18617
18618         # small read with fast read enabled
18619         $LCTL set_param -n llite.*.fast_read=1
18620         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
18621                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
18622                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
18623         # small read with fast read disabled
18624         $LCTL set_param -n llite.*.fast_read=0
18625         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
18626                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
18627                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
18628
18629         # verify that fast read is 4 times faster for cache read
18630         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
18631                 error_not_in_vm "fast read was not 4 times faster: " \
18632                            "$t_fast vs $t_slow"
18633
18634         echo "Test 2: verify the performance between big and small read"
18635         $LCTL set_param -n llite.*.fast_read=1
18636
18637         # 1k non-cache read
18638         cancel_lru_locks osc
18639         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
18640                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
18641                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
18642
18643         # 1M non-cache read
18644         cancel_lru_locks osc
18645         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
18646                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
18647                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
18648
18649         # verify that big IO is not 4 times faster than small IO
18650         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
18651                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
18652
18653         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
18654         rm -f $DIR/$tfile
18655 }
18656 run_test 248a "fast read verification"
18657
18658 test_248b() {
18659         # Default short_io_bytes=16384, try both smaller and larger sizes.
18660         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
18661         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
18662         echo "bs=53248 count=113 normal buffered write"
18663         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
18664                 error "dd of initial data file failed"
18665         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
18666
18667         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
18668         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
18669                 error "dd with sync normal writes failed"
18670         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
18671
18672         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
18673         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
18674                 error "dd with sync small writes failed"
18675         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
18676
18677         cancel_lru_locks osc
18678
18679         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
18680         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
18681         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
18682         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
18683                 iflag=direct || error "dd with O_DIRECT small read failed"
18684         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
18685         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
18686                 error "compare $TMP/$tfile.1 failed"
18687
18688         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
18689         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
18690
18691         # just to see what the maximum tunable value is, and test parsing
18692         echo "test invalid parameter 2MB"
18693         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
18694                 error "too-large short_io_bytes allowed"
18695         echo "test maximum parameter 512KB"
18696         # if we can set a larger short_io_bytes, run test regardless of version
18697         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
18698                 # older clients may not allow setting it this large, that's OK
18699                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
18700                         skip "Need at least client version 2.13.50"
18701                 error "medium short_io_bytes failed"
18702         fi
18703         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
18704         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
18705
18706         echo "test large parameter 64KB"
18707         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
18708         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
18709
18710         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
18711         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
18712                 error "dd with sync large writes failed"
18713         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
18714
18715         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
18716         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
18717         num=$((113 * 4096 / PAGE_SIZE))
18718         echo "bs=$size count=$num oflag=direct large write $tfile.3"
18719         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
18720                 error "dd with O_DIRECT large writes failed"
18721         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
18722                 error "compare $DIR/$tfile.3 failed"
18723
18724         cancel_lru_locks osc
18725
18726         echo "bs=$size count=$num iflag=direct large read $tfile.2"
18727         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
18728                 error "dd with O_DIRECT large read failed"
18729         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
18730                 error "compare $TMP/$tfile.2 failed"
18731
18732         echo "bs=$size count=$num iflag=direct large read $tfile.3"
18733         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
18734                 error "dd with O_DIRECT large read failed"
18735         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
18736                 error "compare $TMP/$tfile.3 failed"
18737 }
18738 run_test 248b "test short_io read and write for both small and large sizes"
18739
18740 test_249() { # LU-7890
18741         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
18742                 skip "Need at least version 2.8.54"
18743
18744         rm -f $DIR/$tfile
18745         $LFS setstripe -c 1 $DIR/$tfile
18746         # Offset 2T == 4k * 512M
18747         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
18748                 error "dd to 2T offset failed"
18749 }
18750 run_test 249 "Write above 2T file size"
18751
18752 test_250() {
18753         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
18754          && skip "no 16TB file size limit on ZFS"
18755
18756         $LFS setstripe -c 1 $DIR/$tfile
18757         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
18758         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
18759         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
18760         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
18761                 conv=notrunc,fsync && error "append succeeded"
18762         return 0
18763 }
18764 run_test 250 "Write above 16T limit"
18765
18766 test_251() {
18767         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
18768
18769         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
18770         #Skip once - writing the first stripe will succeed
18771         $LCTL set_param fail_loc=0xa0001407 fail_val=1
18772         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
18773                 error "short write happened"
18774
18775         $LCTL set_param fail_loc=0xa0001407 fail_val=1
18776         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
18777                 error "short read happened"
18778
18779         rm -f $DIR/$tfile
18780 }
18781 run_test 251 "Handling short read and write correctly"
18782
18783 test_252() {
18784         remote_mds_nodsh && skip "remote MDS with nodsh"
18785         remote_ost_nodsh && skip "remote OST with nodsh"
18786         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
18787                 skip_env "ldiskfs only test"
18788         fi
18789
18790         local tgt
18791         local dev
18792         local out
18793         local uuid
18794         local num
18795         local gen
18796
18797         # check lr_reader on OST0000
18798         tgt=ost1
18799         dev=$(facet_device $tgt)
18800         out=$(do_facet $tgt $LR_READER $dev)
18801         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
18802         echo "$out"
18803         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
18804         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
18805                 error "Invalid uuid returned by $LR_READER on target $tgt"
18806         echo -e "uuid returned by $LR_READER is '$uuid'\n"
18807
18808         # check lr_reader -c on MDT0000
18809         tgt=mds1
18810         dev=$(facet_device $tgt)
18811         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
18812                 skip "$LR_READER does not support additional options"
18813         fi
18814         out=$(do_facet $tgt $LR_READER -c $dev)
18815         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
18816         echo "$out"
18817         num=$(echo "$out" | grep -c "mdtlov")
18818         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
18819                 error "Invalid number of mdtlov clients returned by $LR_READER"
18820         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
18821
18822         # check lr_reader -cr on MDT0000
18823         out=$(do_facet $tgt $LR_READER -cr $dev)
18824         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
18825         echo "$out"
18826         echo "$out" | grep -q "^reply_data:$" ||
18827                 error "$LR_READER should have returned 'reply_data' section"
18828         num=$(echo "$out" | grep -c "client_generation")
18829         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
18830 }
18831 run_test 252 "check lr_reader tool"
18832
18833 test_253() {
18834         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18835         remote_mds_nodsh && skip "remote MDS with nodsh"
18836         remote_mgs_nodsh && skip "remote MGS with nodsh"
18837
18838         local ostidx=0
18839         local rc=0
18840         local ost_name=$(ostname_from_index $ostidx)
18841
18842         # on the mdt's osc
18843         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
18844         do_facet $SINGLEMDS $LCTL get_param -n \
18845                 osp.$mdtosc_proc1.reserved_mb_high ||
18846                 skip  "remote MDS does not support reserved_mb_high"
18847
18848         rm -rf $DIR/$tdir
18849         wait_mds_ost_sync
18850         wait_delete_completed
18851         mkdir $DIR/$tdir
18852
18853         pool_add $TESTNAME || error "Pool creation failed"
18854         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
18855
18856         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
18857                 error "Setstripe failed"
18858
18859         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
18860
18861         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
18862                     grep "watermarks")
18863         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
18864
18865         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
18866                         osp.$mdtosc_proc1.prealloc_status)
18867         echo "prealloc_status $oa_status"
18868
18869         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
18870                 error "File creation should fail"
18871
18872         #object allocation was stopped, but we still able to append files
18873         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
18874                 oflag=append || error "Append failed"
18875
18876         rm -f $DIR/$tdir/$tfile.0
18877
18878         # For this test, we want to delete the files we created to go out of
18879         # space but leave the watermark, so we remain nearly out of space
18880         ost_watermarks_enospc_delete_files $tfile $ostidx
18881
18882         wait_delete_completed
18883
18884         sleep_maxage
18885
18886         for i in $(seq 10 12); do
18887                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
18888                         2>/dev/null || error "File creation failed after rm"
18889         done
18890
18891         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
18892                         osp.$mdtosc_proc1.prealloc_status)
18893         echo "prealloc_status $oa_status"
18894
18895         if (( oa_status != 0 )); then
18896                 error "Object allocation still disable after rm"
18897         fi
18898 }
18899 run_test 253 "Check object allocation limit"
18900
18901 test_254() {
18902         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18903         remote_mds_nodsh && skip "remote MDS with nodsh"
18904         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
18905                 skip "MDS does not support changelog_size"
18906
18907         local cl_user
18908         local MDT0=$(facet_svc $SINGLEMDS)
18909
18910         changelog_register || error "changelog_register failed"
18911
18912         changelog_clear 0 || error "changelog_clear failed"
18913
18914         local size1=$(do_facet $SINGLEMDS \
18915                       $LCTL get_param -n mdd.$MDT0.changelog_size)
18916         echo "Changelog size $size1"
18917
18918         rm -rf $DIR/$tdir
18919         $LFS mkdir -i 0 $DIR/$tdir
18920         # change something
18921         mkdir -p $DIR/$tdir/pics/2008/zachy
18922         touch $DIR/$tdir/pics/2008/zachy/timestamp
18923         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
18924         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
18925         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
18926         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
18927         rm $DIR/$tdir/pics/desktop.jpg
18928
18929         local size2=$(do_facet $SINGLEMDS \
18930                       $LCTL get_param -n mdd.$MDT0.changelog_size)
18931         echo "Changelog size after work $size2"
18932
18933         (( $size2 > $size1 )) ||
18934                 error "new Changelog size=$size2 less than old size=$size1"
18935 }
18936 run_test 254 "Check changelog size"
18937
18938 ladvise_no_type()
18939 {
18940         local type=$1
18941         local file=$2
18942
18943         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
18944                 awk -F: '{print $2}' | grep $type > /dev/null
18945         if [ $? -ne 0 ]; then
18946                 return 0
18947         fi
18948         return 1
18949 }
18950
18951 ladvise_no_ioctl()
18952 {
18953         local file=$1
18954
18955         lfs ladvise -a willread $file > /dev/null 2>&1
18956         if [ $? -eq 0 ]; then
18957                 return 1
18958         fi
18959
18960         lfs ladvise -a willread $file 2>&1 |
18961                 grep "Inappropriate ioctl for device" > /dev/null
18962         if [ $? -eq 0 ]; then
18963                 return 0
18964         fi
18965         return 1
18966 }
18967
18968 percent() {
18969         bc <<<"scale=2; ($1 - $2) * 100 / $2"
18970 }
18971
18972 # run a random read IO workload
18973 # usage: random_read_iops <filename> <filesize> <iosize>
18974 random_read_iops() {
18975         local file=$1
18976         local fsize=$2
18977         local iosize=${3:-4096}
18978
18979         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
18980                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
18981 }
18982
18983 drop_file_oss_cache() {
18984         local file="$1"
18985         local nodes="$2"
18986
18987         $LFS ladvise -a dontneed $file 2>/dev/null ||
18988                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
18989 }
18990
18991 ladvise_willread_performance()
18992 {
18993         local repeat=10
18994         local average_origin=0
18995         local average_cache=0
18996         local average_ladvise=0
18997
18998         for ((i = 1; i <= $repeat; i++)); do
18999                 echo "Iter $i/$repeat: reading without willread hint"
19000                 cancel_lru_locks osc
19001                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
19002                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
19003                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
19004                 average_origin=$(bc <<<"$average_origin + $speed_origin")
19005
19006                 cancel_lru_locks osc
19007                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
19008                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
19009                 average_cache=$(bc <<<"$average_cache + $speed_cache")
19010
19011                 cancel_lru_locks osc
19012                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
19013                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
19014                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
19015                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
19016                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
19017         done
19018         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
19019         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
19020         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
19021
19022         speedup_cache=$(percent $average_cache $average_origin)
19023         speedup_ladvise=$(percent $average_ladvise $average_origin)
19024
19025         echo "Average uncached read: $average_origin"
19026         echo "Average speedup with OSS cached read: " \
19027                 "$average_cache = +$speedup_cache%"
19028         echo "Average speedup with ladvise willread: " \
19029                 "$average_ladvise = +$speedup_ladvise%"
19030
19031         local lowest_speedup=20
19032         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
19033                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
19034                         "got $average_cache%. Skipping ladvise willread check."
19035                 return 0
19036         fi
19037
19038         # the test won't work on ZFS until it supports 'ladvise dontneed', but
19039         # it is still good to run until then to exercise 'ladvise willread'
19040         ! $LFS ladvise -a dontneed $DIR/$tfile &&
19041                 [ "$ost1_FSTYPE" = "zfs" ] &&
19042                 echo "osd-zfs does not support dontneed or drop_caches" &&
19043                 return 0
19044
19045         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
19046         [ ${average_ladvise%.*} -gt $lowest_speedup ] ||
19047                 error_not_in_vm "Speedup with willread is less than " \
19048                         "$lowest_speedup%, got $average_ladvise%"
19049 }
19050
19051 test_255a() {
19052         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
19053                 skip "lustre < 2.8.54 does not support ladvise "
19054         remote_ost_nodsh && skip "remote OST with nodsh"
19055
19056         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
19057
19058         ladvise_no_type willread $DIR/$tfile &&
19059                 skip "willread ladvise is not supported"
19060
19061         ladvise_no_ioctl $DIR/$tfile &&
19062                 skip "ladvise ioctl is not supported"
19063
19064         local size_mb=100
19065         local size=$((size_mb * 1048576))
19066         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
19067                 error "dd to $DIR/$tfile failed"
19068
19069         lfs ladvise -a willread $DIR/$tfile ||
19070                 error "Ladvise failed with no range argument"
19071
19072         lfs ladvise -a willread -s 0 $DIR/$tfile ||
19073                 error "Ladvise failed with no -l or -e argument"
19074
19075         lfs ladvise -a willread -e 1 $DIR/$tfile ||
19076                 error "Ladvise failed with only -e argument"
19077
19078         lfs ladvise -a willread -l 1 $DIR/$tfile ||
19079                 error "Ladvise failed with only -l argument"
19080
19081         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
19082                 error "End offset should not be smaller than start offset"
19083
19084         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
19085                 error "End offset should not be equal to start offset"
19086
19087         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
19088                 error "Ladvise failed with overflowing -s argument"
19089
19090         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
19091                 error "Ladvise failed with overflowing -e argument"
19092
19093         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
19094                 error "Ladvise failed with overflowing -l argument"
19095
19096         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
19097                 error "Ladvise succeeded with conflicting -l and -e arguments"
19098
19099         echo "Synchronous ladvise should wait"
19100         local delay=4
19101 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
19102         do_nodes $(comma_list $(osts_nodes)) \
19103                 $LCTL set_param fail_val=$delay fail_loc=0x237
19104
19105         local start_ts=$SECONDS
19106         lfs ladvise -a willread $DIR/$tfile ||
19107                 error "Ladvise failed with no range argument"
19108         local end_ts=$SECONDS
19109         local inteval_ts=$((end_ts - start_ts))
19110
19111         if [ $inteval_ts -lt $(($delay - 1)) ]; then
19112                 error "Synchronous advice didn't wait reply"
19113         fi
19114
19115         echo "Asynchronous ladvise shouldn't wait"
19116         local start_ts=$SECONDS
19117         lfs ladvise -a willread -b $DIR/$tfile ||
19118                 error "Ladvise failed with no range argument"
19119         local end_ts=$SECONDS
19120         local inteval_ts=$((end_ts - start_ts))
19121
19122         if [ $inteval_ts -gt $(($delay / 2)) ]; then
19123                 error "Asynchronous advice blocked"
19124         fi
19125
19126         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
19127         ladvise_willread_performance
19128 }
19129 run_test 255a "check 'lfs ladvise -a willread'"
19130
19131 facet_meminfo() {
19132         local facet=$1
19133         local info=$2
19134
19135         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
19136 }
19137
19138 test_255b() {
19139         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
19140                 skip "lustre < 2.8.54 does not support ladvise "
19141         remote_ost_nodsh && skip "remote OST with nodsh"
19142
19143         lfs setstripe -c 1 -i 0 $DIR/$tfile
19144
19145         ladvise_no_type dontneed $DIR/$tfile &&
19146                 skip "dontneed ladvise is not supported"
19147
19148         ladvise_no_ioctl $DIR/$tfile &&
19149                 skip "ladvise ioctl is not supported"
19150
19151         ! $LFS ladvise -a dontneed $DIR/$tfile &&
19152                 [ "$ost1_FSTYPE" = "zfs" ] &&
19153                 skip "zfs-osd does not support 'ladvise dontneed'"
19154
19155         local size_mb=100
19156         local size=$((size_mb * 1048576))
19157         # In order to prevent disturbance of other processes, only check 3/4
19158         # of the memory usage
19159         local kibibytes=$((size_mb * 1024 * 3 / 4))
19160
19161         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
19162                 error "dd to $DIR/$tfile failed"
19163
19164         #force write to complete before dropping OST cache & checking memory
19165         sync
19166
19167         local total=$(facet_meminfo ost1 MemTotal)
19168         echo "Total memory: $total KiB"
19169
19170         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
19171         local before_read=$(facet_meminfo ost1 Cached)
19172         echo "Cache used before read: $before_read KiB"
19173
19174         lfs ladvise -a willread $DIR/$tfile ||
19175                 error "Ladvise willread failed"
19176         local after_read=$(facet_meminfo ost1 Cached)
19177         echo "Cache used after read: $after_read KiB"
19178
19179         lfs ladvise -a dontneed $DIR/$tfile ||
19180                 error "Ladvise dontneed again failed"
19181         local no_read=$(facet_meminfo ost1 Cached)
19182         echo "Cache used after dontneed ladvise: $no_read KiB"
19183
19184         if [ $total -lt $((before_read + kibibytes)) ]; then
19185                 echo "Memory is too small, abort checking"
19186                 return 0
19187         fi
19188
19189         if [ $((before_read + kibibytes)) -gt $after_read ]; then
19190                 error "Ladvise willread should use more memory" \
19191                         "than $kibibytes KiB"
19192         fi
19193
19194         if [ $((no_read + kibibytes)) -gt $after_read ]; then
19195                 error "Ladvise dontneed should release more memory" \
19196                         "than $kibibytes KiB"
19197         fi
19198 }
19199 run_test 255b "check 'lfs ladvise -a dontneed'"
19200
19201 test_255c() {
19202         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
19203                 skip "lustre < 2.10.50 does not support lockahead"
19204
19205         local count
19206         local new_count
19207         local difference
19208         local i
19209         local rc
19210
19211         test_mkdir -p $DIR/$tdir
19212         $LFS setstripe -i 0 -c 1 $DIR/$tdir
19213
19214         #test 10 returns only success/failure
19215         i=10
19216         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19217         rc=$?
19218         if [ $rc -eq 255 ]; then
19219                 error "Ladvise test${i} failed, ${rc}"
19220         fi
19221
19222         #test 11 counts lock enqueue requests, all others count new locks
19223         i=11
19224         count=$(do_facet ost1 \
19225                 $LCTL get_param -n ost.OSS.ost.stats)
19226         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
19227
19228         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19229         rc=$?
19230         if [ $rc -eq 255 ]; then
19231                 error "Ladvise test${i} failed, ${rc}"
19232         fi
19233
19234         new_count=$(do_facet ost1 \
19235                 $LCTL get_param -n ost.OSS.ost.stats)
19236         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
19237                    awk '{ print $2 }')
19238
19239         difference="$((new_count - count))"
19240         if [ $difference -ne $rc ]; then
19241                 error "Ladvise test${i}, bad enqueue count, returned " \
19242                       "${rc}, actual ${difference}"
19243         fi
19244
19245         for i in $(seq 12 21); do
19246                 # If we do not do this, we run the risk of having too many
19247                 # locks and starting lock cancellation while we are checking
19248                 # lock counts.
19249                 cancel_lru_locks osc
19250
19251                 count=$($LCTL get_param -n \
19252                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
19253
19254                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
19255                 rc=$?
19256                 if [ $rc -eq 255 ]; then
19257                         error "Ladvise test ${i} failed, ${rc}"
19258                 fi
19259
19260                 new_count=$($LCTL get_param -n \
19261                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
19262                 difference="$((new_count - count))"
19263
19264                 # Test 15 output is divided by 100 to map down to valid return
19265                 if [ $i -eq 15 ]; then
19266                         rc="$((rc * 100))"
19267                 fi
19268
19269                 if [ $difference -ne $rc ]; then
19270                         error "Ladvise test ${i}, bad lock count, returned " \
19271                               "${rc}, actual ${difference}"
19272                 fi
19273         done
19274
19275         #test 22 returns only success/failure
19276         i=22
19277         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19278         rc=$?
19279         if [ $rc -eq 255 ]; then
19280                 error "Ladvise test${i} failed, ${rc}"
19281         fi
19282 }
19283 run_test 255c "suite of ladvise lockahead tests"
19284
19285 test_256() {
19286         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19287         remote_mds_nodsh && skip "remote MDS with nodsh"
19288         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
19289         changelog_users $SINGLEMDS | grep "^cl" &&
19290                 skip "active changelog user"
19291
19292         local cl_user
19293         local cat_sl
19294         local mdt_dev
19295
19296         mdt_dev=$(mdsdevname 1)
19297         echo $mdt_dev
19298
19299         changelog_register || error "changelog_register failed"
19300
19301         rm -rf $DIR/$tdir
19302         mkdir -p $DIR/$tdir
19303
19304         changelog_clear 0 || error "changelog_clear failed"
19305
19306         # change something
19307         touch $DIR/$tdir/{1..10}
19308
19309         # stop the MDT
19310         stop $SINGLEMDS || error "Fail to stop MDT"
19311
19312         # remount the MDT
19313
19314         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
19315
19316         #after mount new plainllog is used
19317         touch $DIR/$tdir/{11..19}
19318         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
19319         stack_trap "rm -f $tmpfile"
19320         cat_sl=$(do_facet $SINGLEMDS "sync; \
19321                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
19322                  llog_reader $tmpfile | grep -c type=1064553b")
19323         do_facet $SINGLEMDS llog_reader $tmpfile
19324
19325         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
19326
19327         changelog_clear 0 || error "changelog_clear failed"
19328
19329         cat_sl=$(do_facet $SINGLEMDS "sync; \
19330                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
19331                  llog_reader $tmpfile | grep -c type=1064553b")
19332
19333         if (( cat_sl == 2 )); then
19334                 error "Empty plain llog was not deleted from changelog catalog"
19335         elif (( cat_sl != 1 )); then
19336                 error "Active plain llog shouldn't be deleted from catalog"
19337         fi
19338 }
19339 run_test 256 "Check llog delete for empty and not full state"
19340
19341 test_257() {
19342         remote_mds_nodsh && skip "remote MDS with nodsh"
19343         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
19344                 skip "Need MDS version at least 2.8.55"
19345
19346         test_mkdir $DIR/$tdir
19347
19348         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
19349                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
19350         stat $DIR/$tdir
19351
19352 #define OBD_FAIL_MDS_XATTR_REP                  0x161
19353         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
19354         local facet=mds$((mdtidx + 1))
19355         set_nodes_failloc $(facet_active_host $facet) 0x80000161
19356         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
19357
19358         stop $facet || error "stop MDS failed"
19359         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
19360                 error "start MDS fail"
19361         wait_recovery_complete $facet
19362 }
19363 run_test 257 "xattr locks are not lost"
19364
19365 # Verify we take the i_mutex when security requires it
19366 test_258a() {
19367 #define OBD_FAIL_IMUTEX_SEC 0x141c
19368         $LCTL set_param fail_loc=0x141c
19369         touch $DIR/$tfile
19370         chmod u+s $DIR/$tfile
19371         chmod a+rwx $DIR/$tfile
19372         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
19373         RC=$?
19374         if [ $RC -ne 0 ]; then
19375                 error "error, failed to take i_mutex, rc=$?"
19376         fi
19377         rm -f $DIR/$tfile
19378 }
19379 run_test 258a "verify i_mutex security behavior when suid attributes is set"
19380
19381 # Verify we do NOT take the i_mutex in the normal case
19382 test_258b() {
19383 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
19384         $LCTL set_param fail_loc=0x141d
19385         touch $DIR/$tfile
19386         chmod a+rwx $DIR
19387         chmod a+rw $DIR/$tfile
19388         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
19389         RC=$?
19390         if [ $RC -ne 0 ]; then
19391                 error "error, took i_mutex unnecessarily, rc=$?"
19392         fi
19393         rm -f $DIR/$tfile
19394
19395 }
19396 run_test 258b "verify i_mutex security behavior"
19397
19398 test_259() {
19399         local file=$DIR/$tfile
19400         local before
19401         local after
19402
19403         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
19404
19405         stack_trap "rm -f $file" EXIT
19406
19407         wait_delete_completed
19408         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19409         echo "before: $before"
19410
19411         $LFS setstripe -i 0 -c 1 $file
19412         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
19413         sync_all_data
19414         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19415         echo "after write: $after"
19416
19417 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
19418         do_facet ost1 $LCTL set_param fail_loc=0x2301
19419         $TRUNCATE $file 0
19420         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19421         echo "after truncate: $after"
19422
19423         stop ost1
19424         do_facet ost1 $LCTL set_param fail_loc=0
19425         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19426         sleep 2
19427         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19428         echo "after restart: $after"
19429         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
19430                 error "missing truncate?"
19431
19432         return 0
19433 }
19434 run_test 259 "crash at delayed truncate"
19435
19436 test_260() {
19437 #define OBD_FAIL_MDC_CLOSE               0x806
19438         $LCTL set_param fail_loc=0x80000806
19439         touch $DIR/$tfile
19440
19441 }
19442 run_test 260 "Check mdc_close fail"
19443
19444 ### Data-on-MDT sanity tests ###
19445 test_270a() {
19446         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19447                 skip "Need MDS version at least 2.10.55 for DoM"
19448
19449         # create DoM file
19450         local dom=$DIR/$tdir/dom_file
19451         local tmp=$DIR/$tdir/tmp_file
19452
19453         mkdir -p $DIR/$tdir
19454
19455         # basic checks for DoM component creation
19456         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
19457                 error "Can set MDT layout to non-first entry"
19458
19459         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
19460                 error "Can define multiple entries as MDT layout"
19461
19462         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
19463
19464         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
19465         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
19466         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
19467
19468         local mdtidx=$($LFS getstripe -m $dom)
19469         local mdtname=MDT$(printf %04x $mdtidx)
19470         local facet=mds$((mdtidx + 1))
19471         local space_check=1
19472
19473         # Skip free space checks with ZFS
19474         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
19475
19476         # write
19477         sync
19478         local size_tmp=$((65536 * 3))
19479         local mdtfree1=$(do_facet $facet \
19480                          lctl get_param -n osd*.*$mdtname.kbytesfree)
19481
19482         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
19483         # check also direct IO along write
19484         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
19485         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
19486         sync
19487         cmp $tmp $dom || error "file data is different"
19488         [ $(stat -c%s $dom) == $size_tmp ] ||
19489                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
19490         if [ $space_check == 1 ]; then
19491                 local mdtfree2=$(do_facet $facet \
19492                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
19493
19494                 # increase in usage from by $size_tmp
19495                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
19496                         error "MDT free space wrong after write: " \
19497                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
19498         fi
19499
19500         # truncate
19501         local size_dom=10000
19502
19503         $TRUNCATE $dom $size_dom
19504         [ $(stat -c%s $dom) == $size_dom ] ||
19505                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
19506         if [ $space_check == 1 ]; then
19507                 mdtfree1=$(do_facet $facet \
19508                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19509                 # decrease in usage from $size_tmp to new $size_dom
19510                 [ $(($mdtfree1 - $mdtfree2)) -ge \
19511                   $(((size_tmp - size_dom) / 1024)) ] ||
19512                         error "MDT free space is wrong after truncate: " \
19513                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
19514         fi
19515
19516         # append
19517         cat $tmp >> $dom
19518         sync
19519         size_dom=$((size_dom + size_tmp))
19520         [ $(stat -c%s $dom) == $size_dom ] ||
19521                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
19522         if [ $space_check == 1 ]; then
19523                 mdtfree2=$(do_facet $facet \
19524                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19525                 # increase in usage by $size_tmp from previous
19526                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
19527                         error "MDT free space is wrong after append: " \
19528                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
19529         fi
19530
19531         # delete
19532         rm $dom
19533         if [ $space_check == 1 ]; then
19534                 mdtfree1=$(do_facet $facet \
19535                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19536                 # decrease in usage by $size_dom from previous
19537                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
19538                         error "MDT free space is wrong after removal: " \
19539                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
19540         fi
19541
19542         # combined striping
19543         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
19544                 error "Can't create DoM + OST striping"
19545
19546         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
19547         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
19548         # check also direct IO along write
19549         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
19550         sync
19551         cmp $tmp $dom || error "file data is different"
19552         [ $(stat -c%s $dom) == $size_tmp ] ||
19553                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
19554         rm $dom $tmp
19555
19556         return 0
19557 }
19558 run_test 270a "DoM: basic functionality tests"
19559
19560 test_270b() {
19561         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19562                 skip "Need MDS version at least 2.10.55"
19563
19564         local dom=$DIR/$tdir/dom_file
19565         local max_size=1048576
19566
19567         mkdir -p $DIR/$tdir
19568         $LFS setstripe -E $max_size -L mdt $dom
19569
19570         # truncate over the limit
19571         $TRUNCATE $dom $(($max_size + 1)) &&
19572                 error "successful truncate over the maximum size"
19573         # write over the limit
19574         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
19575                 error "successful write over the maximum size"
19576         # append over the limit
19577         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
19578         echo "12345" >> $dom && error "successful append over the maximum size"
19579         rm $dom
19580
19581         return 0
19582 }
19583 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
19584
19585 test_270c() {
19586         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19587                 skip "Need MDS version at least 2.10.55"
19588
19589         mkdir -p $DIR/$tdir
19590         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
19591
19592         # check files inherit DoM EA
19593         touch $DIR/$tdir/first
19594         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
19595                 error "bad pattern"
19596         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
19597                 error "bad stripe count"
19598         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
19599                 error "bad stripe size"
19600
19601         # check directory inherits DoM EA and uses it as default
19602         mkdir $DIR/$tdir/subdir
19603         touch $DIR/$tdir/subdir/second
19604         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
19605                 error "bad pattern in sub-directory"
19606         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
19607                 error "bad stripe count in sub-directory"
19608         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
19609                 error "bad stripe size in sub-directory"
19610         return 0
19611 }
19612 run_test 270c "DoM: DoM EA inheritance tests"
19613
19614 test_270d() {
19615         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19616                 skip "Need MDS version at least 2.10.55"
19617
19618         mkdir -p $DIR/$tdir
19619         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
19620
19621         # inherit default DoM striping
19622         mkdir $DIR/$tdir/subdir
19623         touch $DIR/$tdir/subdir/f1
19624
19625         # change default directory striping
19626         $LFS setstripe -c 1 $DIR/$tdir/subdir
19627         touch $DIR/$tdir/subdir/f2
19628         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
19629                 error "wrong default striping in file 2"
19630         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
19631                 error "bad pattern in file 2"
19632         return 0
19633 }
19634 run_test 270d "DoM: change striping from DoM to RAID0"
19635
19636 test_270e() {
19637         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19638                 skip "Need MDS version at least 2.10.55"
19639
19640         mkdir -p $DIR/$tdir/dom
19641         mkdir -p $DIR/$tdir/norm
19642         DOMFILES=20
19643         NORMFILES=10
19644         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
19645         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
19646
19647         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
19648         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
19649
19650         # find DoM files by layout
19651         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
19652         [ $NUM -eq  $DOMFILES ] ||
19653                 error "lfs find -L: found $NUM, expected $DOMFILES"
19654         echo "Test 1: lfs find 20 DOM files by layout: OK"
19655
19656         # there should be 1 dir with default DOM striping
19657         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
19658         [ $NUM -eq  1 ] ||
19659                 error "lfs find -L: found $NUM, expected 1 dir"
19660         echo "Test 2: lfs find 1 DOM dir by layout: OK"
19661
19662         # find DoM files by stripe size
19663         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
19664         [ $NUM -eq  $DOMFILES ] ||
19665                 error "lfs find -S: found $NUM, expected $DOMFILES"
19666         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
19667
19668         # find files by stripe offset except DoM files
19669         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
19670         [ $NUM -eq  $NORMFILES ] ||
19671                 error "lfs find -i: found $NUM, expected $NORMFILES"
19672         echo "Test 5: lfs find no DOM files by stripe index: OK"
19673         return 0
19674 }
19675 run_test 270e "DoM: lfs find with DoM files test"
19676
19677 test_270f() {
19678         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19679                 skip "Need MDS version at least 2.10.55"
19680
19681         local mdtname=${FSNAME}-MDT0000-mdtlov
19682         local dom=$DIR/$tdir/dom_file
19683         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
19684                                                 lod.$mdtname.dom_stripesize)
19685         local dom_limit=131072
19686
19687         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
19688         local dom_current=$(do_facet mds1 $LCTL get_param -n \
19689                                                 lod.$mdtname.dom_stripesize)
19690         [ ${dom_limit} -eq ${dom_current} ] ||
19691                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
19692
19693         $LFS mkdir -i 0 -c 1 $DIR/$tdir
19694         $LFS setstripe -d $DIR/$tdir
19695         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
19696                 error "Can't set directory default striping"
19697
19698         # exceed maximum stripe size
19699         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
19700                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
19701         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
19702                 error "Able to create DoM component size more than LOD limit"
19703
19704         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
19705         dom_current=$(do_facet mds1 $LCTL get_param -n \
19706                                                 lod.$mdtname.dom_stripesize)
19707         [ 0 -eq ${dom_current} ] ||
19708                 error "Can't set zero DoM stripe limit"
19709         rm $dom
19710
19711         # attempt to create DoM file on server with disabled DoM should
19712         # remove DoM entry from layout and be succeed
19713         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
19714                 error "Can't create DoM file (DoM is disabled)"
19715         [ $($LFS getstripe -L $dom) == "mdt" ] &&
19716                 error "File has DoM component while DoM is disabled"
19717         rm $dom
19718
19719         # attempt to create DoM file with only DoM stripe should return error
19720         $LFS setstripe -E $dom_limit -L mdt $dom &&
19721                 error "Able to create DoM-only file while DoM is disabled"
19722
19723         # too low values to be aligned with smallest stripe size 64K
19724         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
19725         dom_current=$(do_facet mds1 $LCTL get_param -n \
19726                                                 lod.$mdtname.dom_stripesize)
19727         [ 30000 -eq ${dom_current} ] &&
19728                 error "Can set too small DoM stripe limit"
19729
19730         # 64K is a minimal stripe size in Lustre, expect limit of that size
19731         [ 65536 -eq ${dom_current} ] ||
19732                 error "Limit is not set to 64K but ${dom_current}"
19733
19734         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
19735         dom_current=$(do_facet mds1 $LCTL get_param -n \
19736                                                 lod.$mdtname.dom_stripesize)
19737         echo $dom_current
19738         [ 2147483648 -eq ${dom_current} ] &&
19739                 error "Can set too large DoM stripe limit"
19740
19741         do_facet mds1 $LCTL set_param -n \
19742                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
19743         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
19744                 error "Can't create DoM component size after limit change"
19745         do_facet mds1 $LCTL set_param -n \
19746                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
19747         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
19748                 error "Can't create DoM file after limit decrease"
19749         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
19750                 error "Can create big DoM component after limit decrease"
19751         touch ${dom}_def ||
19752                 error "Can't create file with old default layout"
19753
19754         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
19755         return 0
19756 }
19757 run_test 270f "DoM: maximum DoM stripe size checks"
19758
19759 test_270g() {
19760         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
19761                 skip "Need MDS version at least 2.13.52"
19762         local dom=$DIR/$tdir/$tfile
19763
19764         $LFS mkdir -i 0 -c 1 $DIR/$tdir
19765         local lodname=${FSNAME}-MDT0000-mdtlov
19766
19767         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
19768         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
19769         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
19770         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
19771
19772         local dom_limit=1024
19773         local dom_threshold="50%"
19774
19775         $LFS setstripe -d $DIR/$tdir
19776         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
19777                 error "Can't set directory default striping"
19778
19779         do_facet mds1 $LCTL set_param -n \
19780                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
19781         # set 0 threshold and create DOM file to change tunable stripesize
19782         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
19783         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
19784                 error "Failed to create $dom file"
19785         # now tunable dom_cur_stripesize should reach maximum
19786         local dom_current=$(do_facet mds1 $LCTL get_param -n \
19787                                         lod.${lodname}.dom_stripesize_cur_kb)
19788         [[ $dom_current == $dom_limit ]] ||
19789                 error "Current DOM stripesize is not maximum"
19790         rm $dom
19791
19792         # set threshold for further tests
19793         do_facet mds1 $LCTL set_param -n \
19794                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
19795         echo "DOM threshold is $dom_threshold free space"
19796         local dom_def
19797         local dom_set
19798         # Spoof bfree to exceed threshold
19799         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
19800         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
19801         for spfree in 40 20 0 15 30 55; do
19802                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
19803                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
19804                         error "Failed to create $dom file"
19805                 dom_def=$(do_facet mds1 $LCTL get_param -n \
19806                                         lod.${lodname}.dom_stripesize_cur_kb)
19807                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
19808                 [[ $dom_def != $dom_current ]] ||
19809                         error "Default stripe size was not changed"
19810                 if [[ $spfree > 0 ]] ; then
19811                         dom_set=$($LFS getstripe -S $dom)
19812                         [[ $dom_set == $((dom_def * 1024)) ]] ||
19813                                 error "DOM component size is still old"
19814                 else
19815                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
19816                                 error "DoM component is set with no free space"
19817                 fi
19818                 rm $dom
19819                 dom_current=$dom_def
19820         done
19821 }
19822 run_test 270g "DoM: default DoM stripe size depends on free space"
19823
19824 test_270h() {
19825         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
19826                 skip "Need MDS version at least 2.13.53"
19827
19828         local mdtname=${FSNAME}-MDT0000-mdtlov
19829         local dom=$DIR/$tdir/$tfile
19830         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
19831
19832         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
19833         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
19834
19835         $LFS mkdir -i 0 -c 1 $DIR/$tdir
19836         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
19837                 error "can't create OST file"
19838         # mirrored file with DOM entry in the second mirror
19839         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
19840                 error "can't create mirror with DoM component"
19841
19842         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
19843
19844         # DOM component in the middle and has other enries in the same mirror,
19845         # should succeed but lost DoM component
19846         $LFS setstripe --copy=${dom}_1 $dom ||
19847                 error "Can't create file from OST|DOM mirror layout"
19848         # check new file has no DoM layout after all
19849         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
19850                 error "File has DoM component while DoM is disabled"
19851 }
19852 run_test 270h "DoM: DoM stripe removal when disabled on server"
19853
19854 test_271a() {
19855         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19856                 skip "Need MDS version at least 2.10.55"
19857
19858         local dom=$DIR/$tdir/dom
19859
19860         mkdir -p $DIR/$tdir
19861
19862         $LFS setstripe -E 1024K -L mdt $dom
19863
19864         lctl set_param -n mdc.*.stats=clear
19865         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
19866         cat $dom > /dev/null
19867         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
19868         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
19869         ls $dom
19870         rm -f $dom
19871 }
19872 run_test 271a "DoM: data is cached for read after write"
19873
19874 test_271b() {
19875         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19876                 skip "Need MDS version at least 2.10.55"
19877
19878         local dom=$DIR/$tdir/dom
19879
19880         mkdir -p $DIR/$tdir
19881
19882         $LFS setstripe -E 1024K -L mdt -E EOF $dom
19883
19884         lctl set_param -n mdc.*.stats=clear
19885         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
19886         cancel_lru_locks mdc
19887         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
19888         # second stat to check size is cached on client
19889         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
19890         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
19891         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
19892         rm -f $dom
19893 }
19894 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
19895
19896 test_271ba() {
19897         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19898                 skip "Need MDS version at least 2.10.55"
19899
19900         local dom=$DIR/$tdir/dom
19901
19902         mkdir -p $DIR/$tdir
19903
19904         $LFS setstripe -E 1024K -L mdt -E EOF $dom
19905
19906         lctl set_param -n mdc.*.stats=clear
19907         lctl set_param -n osc.*.stats=clear
19908         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
19909         cancel_lru_locks mdc
19910         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
19911         # second stat to check size is cached on client
19912         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
19913         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
19914         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
19915         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
19916         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
19917         rm -f $dom
19918 }
19919 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
19920
19921
19922 get_mdc_stats() {
19923         local mdtidx=$1
19924         local param=$2
19925         local mdt=MDT$(printf %04x $mdtidx)
19926
19927         if [ -z $param ]; then
19928                 lctl get_param -n mdc.*$mdt*.stats
19929         else
19930                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
19931         fi
19932 }
19933
19934 test_271c() {
19935         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19936                 skip "Need MDS version at least 2.10.55"
19937
19938         local dom=$DIR/$tdir/dom
19939
19940         mkdir -p $DIR/$tdir
19941
19942         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
19943
19944         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
19945         local facet=mds$((mdtidx + 1))
19946
19947         cancel_lru_locks mdc
19948         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
19949         createmany -o $dom 1000
19950         lctl set_param -n mdc.*.stats=clear
19951         smalliomany -w $dom 1000 200
19952         get_mdc_stats $mdtidx
19953         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
19954         # Each file has 1 open, 1 IO enqueues, total 2000
19955         # but now we have also +1 getxattr for security.capability, total 3000
19956         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
19957         unlinkmany $dom 1000
19958
19959         cancel_lru_locks mdc
19960         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
19961         createmany -o $dom 1000
19962         lctl set_param -n mdc.*.stats=clear
19963         smalliomany -w $dom 1000 200
19964         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
19965         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
19966         # for OPEN and IO lock.
19967         [ $((enq - enq_2)) -ge 1000 ] ||
19968                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
19969         unlinkmany $dom 1000
19970         return 0
19971 }
19972 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
19973
19974 cleanup_271def_tests() {
19975         trap 0
19976         rm -f $1
19977 }
19978
19979 test_271d() {
19980         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
19981                 skip "Need MDS version at least 2.10.57"
19982
19983         local dom=$DIR/$tdir/dom
19984         local tmp=$TMP/$tfile
19985         trap "cleanup_271def_tests $tmp" EXIT
19986
19987         mkdir -p $DIR/$tdir
19988
19989         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
19990
19991         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
19992
19993         cancel_lru_locks mdc
19994         dd if=/dev/urandom of=$tmp bs=1000 count=1
19995         dd if=$tmp of=$dom bs=1000 count=1
19996         cancel_lru_locks mdc
19997
19998         cat /etc/hosts >> $tmp
19999         lctl set_param -n mdc.*.stats=clear
20000
20001         # append data to the same file it should update local page
20002         echo "Append to the same page"
20003         cat /etc/hosts >> $dom
20004         local num=$(get_mdc_stats $mdtidx ost_read)
20005         local ra=$(get_mdc_stats $mdtidx req_active)
20006         local rw=$(get_mdc_stats $mdtidx req_waittime)
20007
20008         [ -z $num ] || error "$num READ RPC occured"
20009         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20010         echo "... DONE"
20011
20012         # compare content
20013         cmp $tmp $dom || error "file miscompare"
20014
20015         cancel_lru_locks mdc
20016         lctl set_param -n mdc.*.stats=clear
20017
20018         echo "Open and read file"
20019         cat $dom > /dev/null
20020         local num=$(get_mdc_stats $mdtidx ost_read)
20021         local ra=$(get_mdc_stats $mdtidx req_active)
20022         local rw=$(get_mdc_stats $mdtidx req_waittime)
20023
20024         [ -z $num ] || error "$num READ RPC occured"
20025         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20026         echo "... DONE"
20027
20028         # compare content
20029         cmp $tmp $dom || error "file miscompare"
20030
20031         return 0
20032 }
20033 run_test 271d "DoM: read on open (1K file in reply buffer)"
20034
20035 test_271f() {
20036         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
20037                 skip "Need MDS version at least 2.10.57"
20038
20039         local dom=$DIR/$tdir/dom
20040         local tmp=$TMP/$tfile
20041         trap "cleanup_271def_tests $tmp" EXIT
20042
20043         mkdir -p $DIR/$tdir
20044
20045         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20046
20047         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
20048
20049         cancel_lru_locks mdc
20050         dd if=/dev/urandom of=$tmp bs=265000 count=1
20051         dd if=$tmp of=$dom bs=265000 count=1
20052         cancel_lru_locks mdc
20053         cat /etc/hosts >> $tmp
20054         lctl set_param -n mdc.*.stats=clear
20055
20056         echo "Append to the same page"
20057         cat /etc/hosts >> $dom
20058         local num=$(get_mdc_stats $mdtidx ost_read)
20059         local ra=$(get_mdc_stats $mdtidx req_active)
20060         local rw=$(get_mdc_stats $mdtidx req_waittime)
20061
20062         [ -z $num ] || error "$num READ RPC occured"
20063         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20064         echo "... DONE"
20065
20066         # compare content
20067         cmp $tmp $dom || error "file miscompare"
20068
20069         cancel_lru_locks mdc
20070         lctl set_param -n mdc.*.stats=clear
20071
20072         echo "Open and read file"
20073         cat $dom > /dev/null
20074         local num=$(get_mdc_stats $mdtidx ost_read)
20075         local ra=$(get_mdc_stats $mdtidx req_active)
20076         local rw=$(get_mdc_stats $mdtidx req_waittime)
20077
20078         [ -z $num ] && num=0
20079         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
20080         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20081         echo "... DONE"
20082
20083         # compare content
20084         cmp $tmp $dom || error "file miscompare"
20085
20086         return 0
20087 }
20088 run_test 271f "DoM: read on open (200K file and read tail)"
20089
20090 test_271g() {
20091         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
20092                 skip "Skipping due to old client or server version"
20093
20094         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
20095         # to get layout
20096         $CHECKSTAT -t file $DIR1/$tfile
20097
20098         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
20099         MULTIOP_PID=$!
20100         sleep 1
20101         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
20102         $LCTL set_param fail_loc=0x80000314
20103         rm $DIR1/$tfile || error "Unlink fails"
20104         RC=$?
20105         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
20106         [ $RC -eq 0 ] || error "Failed write to stale object"
20107 }
20108 run_test 271g "Discard DoM data vs client flush race"
20109
20110 test_272a() {
20111         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20112                 skip "Need MDS version at least 2.11.50"
20113
20114         local dom=$DIR/$tdir/dom
20115         mkdir -p $DIR/$tdir
20116
20117         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
20118         dd if=/dev/urandom of=$dom bs=512K count=1 ||
20119                 error "failed to write data into $dom"
20120         local old_md5=$(md5sum $dom)
20121
20122         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
20123                 error "failed to migrate to the same DoM component"
20124
20125         local new_md5=$(md5sum $dom)
20126
20127         [ "$old_md5" == "$new_md5" ] ||
20128                 error "md5sum differ: $old_md5, $new_md5"
20129
20130         [ $($LFS getstripe -c $dom) -eq 2 ] ||
20131                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
20132 }
20133 run_test 272a "DoM migration: new layout with the same DOM component"
20134
20135 test_272b() {
20136         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20137                 skip "Need MDS version at least 2.11.50"
20138
20139         local dom=$DIR/$tdir/dom
20140         mkdir -p $DIR/$tdir
20141         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20142
20143         local mdtidx=$($LFS getstripe -m $dom)
20144         local mdtname=MDT$(printf %04x $mdtidx)
20145         local facet=mds$((mdtidx + 1))
20146
20147         local mdtfree1=$(do_facet $facet \
20148                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20149         dd if=/dev/urandom of=$dom bs=2M count=1 ||
20150                 error "failed to write data into $dom"
20151         local old_md5=$(md5sum $dom)
20152         cancel_lru_locks mdc
20153         local mdtfree1=$(do_facet $facet \
20154                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20155
20156         $LFS migrate -c2 $dom ||
20157                 error "failed to migrate to the new composite layout"
20158         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20159                 error "MDT stripe was not removed"
20160
20161         cancel_lru_locks mdc
20162         local new_md5=$(md5sum $dom)
20163         [ "$old_md5" == "$new_md5" ] ||
20164                 error "$old_md5 != $new_md5"
20165
20166         # Skip free space checks with ZFS
20167         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20168                 local mdtfree2=$(do_facet $facet \
20169                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20170                 [ $mdtfree2 -gt $mdtfree1 ] ||
20171                         error "MDT space is not freed after migration"
20172         fi
20173         return 0
20174 }
20175 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
20176
20177 test_272c() {
20178         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20179                 skip "Need MDS version at least 2.11.50"
20180
20181         local dom=$DIR/$tdir/$tfile
20182         mkdir -p $DIR/$tdir
20183         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20184
20185         local mdtidx=$($LFS getstripe -m $dom)
20186         local mdtname=MDT$(printf %04x $mdtidx)
20187         local facet=mds$((mdtidx + 1))
20188
20189         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
20190                 error "failed to write data into $dom"
20191         local old_md5=$(md5sum $dom)
20192         cancel_lru_locks mdc
20193         local mdtfree1=$(do_facet $facet \
20194                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20195
20196         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
20197                 error "failed to migrate to the new composite layout"
20198         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
20199                 error "MDT stripe was not removed"
20200
20201         cancel_lru_locks mdc
20202         local new_md5=$(md5sum $dom)
20203         [ "$old_md5" == "$new_md5" ] ||
20204                 error "$old_md5 != $new_md5"
20205
20206         # Skip free space checks with ZFS
20207         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20208                 local mdtfree2=$(do_facet $facet \
20209                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20210                 [ $mdtfree2 -gt $mdtfree1 ] ||
20211                         error "MDS space is not freed after migration"
20212         fi
20213         return 0
20214 }
20215 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
20216
20217 test_272d() {
20218         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20219                 skip "Need MDS version at least 2.12.55"
20220
20221         local dom=$DIR/$tdir/$tfile
20222         mkdir -p $DIR/$tdir
20223         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20224
20225         local mdtidx=$($LFS getstripe -m $dom)
20226         local mdtname=MDT$(printf %04x $mdtidx)
20227         local facet=mds$((mdtidx + 1))
20228
20229         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
20230                 error "failed to write data into $dom"
20231         local old_md5=$(md5sum $dom)
20232         cancel_lru_locks mdc
20233         local mdtfree1=$(do_facet $facet \
20234                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20235
20236         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
20237                 error "failed mirroring to the new composite layout"
20238         $LFS mirror resync $dom ||
20239                 error "failed mirror resync"
20240         $LFS mirror split --mirror-id 1 -d $dom ||
20241                 error "failed mirror split"
20242
20243         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20244                 error "MDT stripe was not removed"
20245
20246         cancel_lru_locks mdc
20247         local new_md5=$(md5sum $dom)
20248         [ "$old_md5" == "$new_md5" ] ||
20249                 error "$old_md5 != $new_md5"
20250
20251         # Skip free space checks with ZFS
20252         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20253                 local mdtfree2=$(do_facet $facet \
20254                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20255                 [ $mdtfree2 -gt $mdtfree1 ] ||
20256                         error "MDS space is not freed after DOM mirror deletion"
20257         fi
20258         return 0
20259 }
20260 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
20261
20262 test_272e() {
20263         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20264                 skip "Need MDS version at least 2.12.55"
20265
20266         local dom=$DIR/$tdir/$tfile
20267         mkdir -p $DIR/$tdir
20268         $LFS setstripe -c 2 $dom
20269
20270         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
20271                 error "failed to write data into $dom"
20272         local old_md5=$(md5sum $dom)
20273         cancel_lru_locks mdc
20274
20275         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
20276                 error "failed mirroring to the DOM layout"
20277         $LFS mirror resync $dom ||
20278                 error "failed mirror resync"
20279         $LFS mirror split --mirror-id 1 -d $dom ||
20280                 error "failed mirror split"
20281
20282         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20283                 error "MDT stripe was not removed"
20284
20285         cancel_lru_locks mdc
20286         local new_md5=$(md5sum $dom)
20287         [ "$old_md5" == "$new_md5" ] ||
20288                 error "$old_md5 != $new_md5"
20289
20290         return 0
20291 }
20292 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
20293
20294 test_272f() {
20295         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20296                 skip "Need MDS version at least 2.12.55"
20297
20298         local dom=$DIR/$tdir/$tfile
20299         mkdir -p $DIR/$tdir
20300         $LFS setstripe -c 2 $dom
20301
20302         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
20303                 error "failed to write data into $dom"
20304         local old_md5=$(md5sum $dom)
20305         cancel_lru_locks mdc
20306
20307         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
20308                 error "failed migrating to the DOM file"
20309
20310         cancel_lru_locks mdc
20311         local new_md5=$(md5sum $dom)
20312         [ "$old_md5" != "$new_md5" ] &&
20313                 error "$old_md5 != $new_md5"
20314
20315         return 0
20316 }
20317 run_test 272f "DoM migration: OST-striped file to DOM file"
20318
20319 test_273a() {
20320         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20321                 skip "Need MDS version at least 2.11.50"
20322
20323         # Layout swap cannot be done if either file has DOM component,
20324         # this will never be supported, migration should be used instead
20325
20326         local dom=$DIR/$tdir/$tfile
20327         mkdir -p $DIR/$tdir
20328
20329         $LFS setstripe -c2 ${dom}_plain
20330         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
20331         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
20332                 error "can swap layout with DoM component"
20333         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
20334                 error "can swap layout with DoM component"
20335
20336         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
20337         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
20338                 error "can swap layout with DoM component"
20339         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
20340                 error "can swap layout with DoM component"
20341         return 0
20342 }
20343 run_test 273a "DoM: layout swapping should fail with DOM"
20344
20345 test_275() {
20346         remote_ost_nodsh && skip "remote OST with nodsh"
20347         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
20348                 skip "Need OST version >= 2.10.57"
20349
20350         local file=$DIR/$tfile
20351         local oss
20352
20353         oss=$(comma_list $(osts_nodes))
20354
20355         dd if=/dev/urandom of=$file bs=1M count=2 ||
20356                 error "failed to create a file"
20357         cancel_lru_locks osc
20358
20359         #lock 1
20360         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
20361                 error "failed to read a file"
20362
20363 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
20364         $LCTL set_param fail_loc=0x8000031f
20365
20366         cancel_lru_locks osc &
20367         sleep 1
20368
20369 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
20370         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
20371         #IO takes another lock, but matches the PENDING one
20372         #and places it to the IO RPC
20373         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
20374                 error "failed to read a file with PENDING lock"
20375 }
20376 run_test 275 "Read on a canceled duplicate lock"
20377
20378 test_276() {
20379         remote_ost_nodsh && skip "remote OST with nodsh"
20380         local pid
20381
20382         do_facet ost1 "(while true; do \
20383                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
20384                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
20385         pid=$!
20386
20387         for LOOP in $(seq 20); do
20388                 stop ost1
20389                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
20390         done
20391         kill -9 $pid
20392         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
20393                 rm $TMP/sanity_276_pid"
20394 }
20395 run_test 276 "Race between mount and obd_statfs"
20396
20397 test_277() {
20398         $LCTL set_param ldlm.namespaces.*.lru_size=0
20399         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
20400         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
20401                         grep ^used_mb | awk '{print $2}')
20402         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
20403         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
20404                 oflag=direct conv=notrunc
20405         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
20406                         grep ^used_mb | awk '{print $2}')
20407         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
20408 }
20409 run_test 277 "Direct IO shall drop page cache"
20410
20411 test_278() {
20412         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
20413         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
20414         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
20415                 skip "needs the same host for mdt1 mdt2" && return
20416
20417         local pid1
20418         local pid2
20419
20420 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
20421         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
20422         stop mds2 &
20423         pid2=$!
20424
20425         stop mds1
20426
20427         echo "Starting MDTs"
20428         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
20429         wait $pid2
20430 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
20431 #will return NULL
20432         do_facet mds2 $LCTL set_param fail_loc=0
20433
20434         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
20435         wait_recovery_complete mds2
20436 }
20437 run_test 278 "Race starting MDS between MDTs stop/start"
20438
20439 test_280() {
20440         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
20441                 skip "Need MGS version at least 2.13.52"
20442         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20443         combined_mgs_mds || skip "needs combined MGS/MDT"
20444
20445         umount_client $MOUNT
20446 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
20447         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
20448
20449         mount_client $MOUNT &
20450         sleep 1
20451         stop mgs || error "stop mgs failed"
20452         #for a race mgs would crash
20453         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
20454         mount_client $MOUNT || error "mount client failed"
20455 }
20456 run_test 280 "Race between MGS umount and client llog processing"
20457
20458 cleanup_test_300() {
20459         trap 0
20460         umask $SAVE_UMASK
20461 }
20462 test_striped_dir() {
20463         local mdt_index=$1
20464         local stripe_count
20465         local stripe_index
20466
20467         mkdir -p $DIR/$tdir
20468
20469         SAVE_UMASK=$(umask)
20470         trap cleanup_test_300 RETURN EXIT
20471
20472         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
20473                                                 $DIR/$tdir/striped_dir ||
20474                 error "set striped dir error"
20475
20476         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
20477         [ "$mode" = "755" ] || error "expect 755 got $mode"
20478
20479         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
20480                 error "getdirstripe failed"
20481         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
20482         if [ "$stripe_count" != "2" ]; then
20483                 error "1:stripe_count is $stripe_count, expect 2"
20484         fi
20485         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
20486         if [ "$stripe_count" != "2" ]; then
20487                 error "2:stripe_count is $stripe_count, expect 2"
20488         fi
20489
20490         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
20491         if [ "$stripe_index" != "$mdt_index" ]; then
20492                 error "stripe_index is $stripe_index, expect $mdt_index"
20493         fi
20494
20495         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
20496                 error "nlink error after create striped dir"
20497
20498         mkdir $DIR/$tdir/striped_dir/a
20499         mkdir $DIR/$tdir/striped_dir/b
20500
20501         stat $DIR/$tdir/striped_dir/a ||
20502                 error "create dir under striped dir failed"
20503         stat $DIR/$tdir/striped_dir/b ||
20504                 error "create dir under striped dir failed"
20505
20506         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
20507                 error "nlink error after mkdir"
20508
20509         rmdir $DIR/$tdir/striped_dir/a
20510         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
20511                 error "nlink error after rmdir"
20512
20513         rmdir $DIR/$tdir/striped_dir/b
20514         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
20515                 error "nlink error after rmdir"
20516
20517         chattr +i $DIR/$tdir/striped_dir
20518         createmany -o $DIR/$tdir/striped_dir/f 10 &&
20519                 error "immutable flags not working under striped dir!"
20520         chattr -i $DIR/$tdir/striped_dir
20521
20522         rmdir $DIR/$tdir/striped_dir ||
20523                 error "rmdir striped dir error"
20524
20525         cleanup_test_300
20526
20527         true
20528 }
20529
20530 test_300a() {
20531         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20532                 skip "skipped for lustre < 2.7.0"
20533         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20534         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20535
20536         test_striped_dir 0 || error "failed on striped dir on MDT0"
20537         test_striped_dir 1 || error "failed on striped dir on MDT0"
20538 }
20539 run_test 300a "basic striped dir sanity test"
20540
20541 test_300b() {
20542         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20543                 skip "skipped for lustre < 2.7.0"
20544         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20545         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20546
20547         local i
20548         local mtime1
20549         local mtime2
20550         local mtime3
20551
20552         test_mkdir $DIR/$tdir || error "mkdir fail"
20553         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
20554                 error "set striped dir error"
20555         for i in {0..9}; do
20556                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
20557                 sleep 1
20558                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
20559                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
20560                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
20561                 sleep 1
20562                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
20563                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
20564                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
20565         done
20566         true
20567 }
20568 run_test 300b "check ctime/mtime for striped dir"
20569
20570 test_300c() {
20571         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20572                 skip "skipped for lustre < 2.7.0"
20573         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20574         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20575
20576         local file_count
20577
20578         mkdir -p $DIR/$tdir
20579         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
20580                 error "set striped dir error"
20581
20582         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
20583                 error "chown striped dir failed"
20584
20585         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
20586                 error "create 5k files failed"
20587
20588         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
20589
20590         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
20591
20592         rm -rf $DIR/$tdir
20593 }
20594 run_test 300c "chown && check ls under striped directory"
20595
20596 test_300d() {
20597         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20598                 skip "skipped for lustre < 2.7.0"
20599         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20600         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20601
20602         local stripe_count
20603         local file
20604
20605         mkdir -p $DIR/$tdir
20606         $LFS setstripe -c 2 $DIR/$tdir
20607
20608         #local striped directory
20609         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
20610                 error "set striped dir error"
20611         #look at the directories for debug purposes
20612         ls -l $DIR/$tdir
20613         $LFS getdirstripe $DIR/$tdir
20614         ls -l $DIR/$tdir/striped_dir
20615         $LFS getdirstripe $DIR/$tdir/striped_dir
20616         createmany -o $DIR/$tdir/striped_dir/f 10 ||
20617                 error "create 10 files failed"
20618
20619         #remote striped directory
20620         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
20621                 error "set striped dir error"
20622         #look at the directories for debug purposes
20623         ls -l $DIR/$tdir
20624         $LFS getdirstripe $DIR/$tdir
20625         ls -l $DIR/$tdir/remote_striped_dir
20626         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
20627         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
20628                 error "create 10 files failed"
20629
20630         for file in $(find $DIR/$tdir); do
20631                 stripe_count=$($LFS getstripe -c $file)
20632                 [ $stripe_count -eq 2 ] ||
20633                         error "wrong stripe $stripe_count for $file"
20634         done
20635
20636         rm -rf $DIR/$tdir
20637 }
20638 run_test 300d "check default stripe under striped directory"
20639
20640 test_300e() {
20641         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20642                 skip "Need MDS version at least 2.7.55"
20643         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20644         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20645
20646         local stripe_count
20647         local file
20648
20649         mkdir -p $DIR/$tdir
20650
20651         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
20652                 error "set striped dir error"
20653
20654         touch $DIR/$tdir/striped_dir/a
20655         touch $DIR/$tdir/striped_dir/b
20656         touch $DIR/$tdir/striped_dir/c
20657
20658         mkdir $DIR/$tdir/striped_dir/dir_a
20659         mkdir $DIR/$tdir/striped_dir/dir_b
20660         mkdir $DIR/$tdir/striped_dir/dir_c
20661
20662         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
20663                 error "set striped adir under striped dir error"
20664
20665         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
20666                 error "set striped bdir under striped dir error"
20667
20668         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
20669                 error "set striped cdir under striped dir error"
20670
20671         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
20672                 error "rename dir under striped dir fails"
20673
20674         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
20675                 error "rename dir under different stripes fails"
20676
20677         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
20678                 error "rename file under striped dir should succeed"
20679
20680         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
20681                 error "rename dir under striped dir should succeed"
20682
20683         rm -rf $DIR/$tdir
20684 }
20685 run_test 300e "check rename under striped directory"
20686
20687 test_300f() {
20688         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20689         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20690         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20691                 skip "Need MDS version at least 2.7.55"
20692
20693         local stripe_count
20694         local file
20695
20696         rm -rf $DIR/$tdir
20697         mkdir -p $DIR/$tdir
20698
20699         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
20700                 error "set striped dir error"
20701
20702         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
20703                 error "set striped dir error"
20704
20705         touch $DIR/$tdir/striped_dir/a
20706         mkdir $DIR/$tdir/striped_dir/dir_a
20707         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
20708                 error "create striped dir under striped dir fails"
20709
20710         touch $DIR/$tdir/striped_dir1/b
20711         mkdir $DIR/$tdir/striped_dir1/dir_b
20712         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
20713                 error "create striped dir under striped dir fails"
20714
20715         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
20716                 error "rename dir under different striped dir should fail"
20717
20718         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
20719                 error "rename striped dir under diff striped dir should fail"
20720
20721         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
20722                 error "rename file under diff striped dirs fails"
20723
20724         rm -rf $DIR/$tdir
20725 }
20726 run_test 300f "check rename cross striped directory"
20727
20728 test_300_check_default_striped_dir()
20729 {
20730         local dirname=$1
20731         local default_count=$2
20732         local default_index=$3
20733         local stripe_count
20734         local stripe_index
20735         local dir_stripe_index
20736         local dir
20737
20738         echo "checking $dirname $default_count $default_index"
20739         $LFS setdirstripe -D -c $default_count -i $default_index \
20740                                 -t all_char $DIR/$tdir/$dirname ||
20741                 error "set default stripe on striped dir error"
20742         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
20743         [ $stripe_count -eq $default_count ] ||
20744                 error "expect $default_count get $stripe_count for $dirname"
20745
20746         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
20747         [ $stripe_index -eq $default_index ] ||
20748                 error "expect $default_index get $stripe_index for $dirname"
20749
20750         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
20751                                                 error "create dirs failed"
20752
20753         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
20754         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
20755         for dir in $(find $DIR/$tdir/$dirname/*); do
20756                 stripe_count=$($LFS getdirstripe -c $dir)
20757                 [ $stripe_count -eq $default_count ] ||
20758                 [ $stripe_count -eq 0 ] || [ $default_count -eq 1 ] ||
20759                 error "stripe count $default_count != $stripe_count for $dir"
20760
20761                 stripe_index=$($LFS getdirstripe -i $dir)
20762                 [ $default_index -eq -1 ] ||
20763                         [ $stripe_index -eq $default_index ] ||
20764                         error "$stripe_index != $default_index for $dir"
20765
20766                 #check default stripe
20767                 stripe_count=$($LFS getdirstripe -D -c $dir)
20768                 [ $stripe_count -eq $default_count ] ||
20769                 error "default count $default_count != $stripe_count for $dir"
20770
20771                 stripe_index=$($LFS getdirstripe -D -i $dir)
20772                 [ $stripe_index -eq $default_index ] ||
20773                 error "default index $default_index != $stripe_index for $dir"
20774         done
20775         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
20776 }
20777
20778 test_300g() {
20779         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20780         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20781                 skip "Need MDS version at least 2.7.55"
20782
20783         local dir
20784         local stripe_count
20785         local stripe_index
20786
20787         mkdir $DIR/$tdir
20788         mkdir $DIR/$tdir/normal_dir
20789
20790         #Checking when client cache stripe index
20791         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
20792         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
20793                 error "create striped_dir failed"
20794
20795         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
20796                 error "create dir0 fails"
20797         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
20798         [ $stripe_index -eq 0 ] ||
20799                 error "dir0 expect index 0 got $stripe_index"
20800
20801         mkdir $DIR/$tdir/striped_dir/dir1 ||
20802                 error "create dir1 fails"
20803         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
20804         [ $stripe_index -eq 1 ] ||
20805                 error "dir1 expect index 1 got $stripe_index"
20806
20807         #check default stripe count/stripe index
20808         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
20809         test_300_check_default_striped_dir normal_dir 1 0
20810         test_300_check_default_striped_dir normal_dir 2 1
20811         test_300_check_default_striped_dir normal_dir 2 -1
20812
20813         #delete default stripe information
20814         echo "delete default stripeEA"
20815         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
20816                 error "set default stripe on striped dir error"
20817
20818         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
20819         for dir in $(find $DIR/$tdir/normal_dir/*); do
20820                 stripe_count=$($LFS getdirstripe -c $dir)
20821                 [ $stripe_count -eq 0 ] ||
20822                         error "expect 1 get $stripe_count for $dir"
20823                 stripe_index=$($LFS getdirstripe -i $dir)
20824                 [ $stripe_index -eq 0 ] ||
20825                         error "expect 0 get $stripe_index for $dir"
20826         done
20827 }
20828 run_test 300g "check default striped directory for normal directory"
20829
20830 test_300h() {
20831         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20832         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20833                 skip "Need MDS version at least 2.7.55"
20834
20835         local dir
20836         local stripe_count
20837
20838         mkdir $DIR/$tdir
20839         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
20840                 error "set striped dir error"
20841
20842         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
20843         test_300_check_default_striped_dir striped_dir 1 0
20844         test_300_check_default_striped_dir striped_dir 2 1
20845         test_300_check_default_striped_dir striped_dir 2 -1
20846
20847         #delete default stripe information
20848         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
20849                 error "set default stripe on striped dir error"
20850
20851         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
20852         for dir in $(find $DIR/$tdir/striped_dir/*); do
20853                 stripe_count=$($LFS getdirstripe -c $dir)
20854                 [ $stripe_count -eq 0 ] ||
20855                         error "expect 1 get $stripe_count for $dir"
20856         done
20857 }
20858 run_test 300h "check default striped directory for striped directory"
20859
20860 test_300i() {
20861         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20862         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20863         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20864                 skip "Need MDS version at least 2.7.55"
20865
20866         local stripe_count
20867         local file
20868
20869         mkdir $DIR/$tdir
20870
20871         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
20872                 error "set striped dir error"
20873
20874         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
20875                 error "create files under striped dir failed"
20876
20877         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
20878                 error "set striped hashdir error"
20879
20880         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
20881                 error "create dir0 under hash dir failed"
20882         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
20883                 error "create dir1 under hash dir failed"
20884
20885         # unfortunately, we need to umount to clear dir layout cache for now
20886         # once we fully implement dir layout, we can drop this
20887         umount_client $MOUNT || error "umount failed"
20888         mount_client $MOUNT || error "mount failed"
20889
20890         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
20891         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
20892         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
20893
20894         #set the stripe to be unknown hash type
20895         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
20896         $LCTL set_param fail_loc=0x1901
20897         for ((i = 0; i < 10; i++)); do
20898                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
20899                         error "stat f-$i failed"
20900                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
20901         done
20902
20903         touch $DIR/$tdir/striped_dir/f0 &&
20904                 error "create under striped dir with unknown hash should fail"
20905
20906         $LCTL set_param fail_loc=0
20907
20908         umount_client $MOUNT || error "umount failed"
20909         mount_client $MOUNT || error "mount failed"
20910
20911         return 0
20912 }
20913 run_test 300i "client handle unknown hash type striped directory"
20914
20915 test_300j() {
20916         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20917         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20918         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20919                 skip "Need MDS version at least 2.7.55"
20920
20921         local stripe_count
20922         local file
20923
20924         mkdir $DIR/$tdir
20925
20926         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
20927         $LCTL set_param fail_loc=0x1702
20928         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
20929                 error "set striped dir error"
20930
20931         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
20932                 error "create files under striped dir failed"
20933
20934         $LCTL set_param fail_loc=0
20935
20936         rm -rf $DIR/$tdir || error "unlink striped dir fails"
20937
20938         return 0
20939 }
20940 run_test 300j "test large update record"
20941
20942 test_300k() {
20943         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20944         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20945         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20946                 skip "Need MDS version at least 2.7.55"
20947
20948         # this test needs a huge transaction
20949         local kb
20950         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
20951              osd*.$FSNAME-MDT0000.kbytestotal")
20952         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
20953
20954         local stripe_count
20955         local file
20956
20957         mkdir $DIR/$tdir
20958
20959         #define OBD_FAIL_LARGE_STRIPE   0x1703
20960         $LCTL set_param fail_loc=0x1703
20961         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
20962                 error "set striped dir error"
20963         $LCTL set_param fail_loc=0
20964
20965         $LFS getdirstripe $DIR/$tdir/striped_dir ||
20966                 error "getstripeddir fails"
20967         rm -rf $DIR/$tdir/striped_dir ||
20968                 error "unlink striped dir fails"
20969
20970         return 0
20971 }
20972 run_test 300k "test large striped directory"
20973
20974 test_300l() {
20975         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20976         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20977         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20978                 skip "Need MDS version at least 2.7.55"
20979
20980         local stripe_index
20981
20982         test_mkdir -p $DIR/$tdir/striped_dir
20983         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
20984                         error "chown $RUNAS_ID failed"
20985         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
20986                 error "set default striped dir failed"
20987
20988         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
20989         $LCTL set_param fail_loc=0x80000158
20990         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
20991
20992         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
20993         [ $stripe_index -eq 1 ] ||
20994                 error "expect 1 get $stripe_index for $dir"
20995 }
20996 run_test 300l "non-root user to create dir under striped dir with stale layout"
20997
20998 test_300m() {
20999         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21000         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
21001         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21002                 skip "Need MDS version at least 2.7.55"
21003
21004         mkdir -p $DIR/$tdir/striped_dir
21005         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
21006                 error "set default stripes dir error"
21007
21008         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
21009
21010         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
21011         [ $stripe_count -eq 0 ] ||
21012                         error "expect 0 get $stripe_count for a"
21013
21014         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
21015                 error "set default stripes dir error"
21016
21017         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
21018
21019         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
21020         [ $stripe_count -eq 0 ] ||
21021                         error "expect 0 get $stripe_count for b"
21022
21023         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
21024                 error "set default stripes dir error"
21025
21026         mkdir $DIR/$tdir/striped_dir/c &&
21027                 error "default stripe_index is invalid, mkdir c should fails"
21028
21029         rm -rf $DIR/$tdir || error "rmdir fails"
21030 }
21031 run_test 300m "setstriped directory on single MDT FS"
21032
21033 cleanup_300n() {
21034         local list=$(comma_list $(mdts_nodes))
21035
21036         trap 0
21037         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21038 }
21039
21040 test_300n() {
21041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21042         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21043         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21044                 skip "Need MDS version at least 2.7.55"
21045         remote_mds_nodsh && skip "remote MDS with nodsh"
21046
21047         local stripe_index
21048         local list=$(comma_list $(mdts_nodes))
21049
21050         trap cleanup_300n RETURN EXIT
21051         mkdir -p $DIR/$tdir
21052         chmod 777 $DIR/$tdir
21053         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
21054                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
21055                 error "create striped dir succeeds with gid=0"
21056
21057         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
21058         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
21059                 error "create striped dir fails with gid=-1"
21060
21061         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21062         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
21063                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
21064                 error "set default striped dir succeeds with gid=0"
21065
21066
21067         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
21068         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
21069                 error "set default striped dir fails with gid=-1"
21070
21071
21072         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21073         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
21074                                         error "create test_dir fails"
21075         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
21076                                         error "create test_dir1 fails"
21077         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
21078                                         error "create test_dir2 fails"
21079         cleanup_300n
21080 }
21081 run_test 300n "non-root user to create dir under striped dir with default EA"
21082
21083 test_300o() {
21084         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21085         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21086         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21087                 skip "Need MDS version at least 2.7.55"
21088
21089         local numfree1
21090         local numfree2
21091
21092         mkdir -p $DIR/$tdir
21093
21094         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
21095         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
21096         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
21097                 skip "not enough free inodes $numfree1 $numfree2"
21098         fi
21099
21100         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
21101         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
21102         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
21103                 skip "not enough free space $numfree1 $numfree2"
21104         fi
21105
21106         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
21107                 error "setdirstripe fails"
21108
21109         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
21110                 error "create dirs fails"
21111
21112         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
21113         ls $DIR/$tdir/striped_dir > /dev/null ||
21114                 error "ls striped dir fails"
21115         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
21116                 error "unlink big striped dir fails"
21117 }
21118 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
21119
21120 test_300p() {
21121         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21122         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21123         remote_mds_nodsh && skip "remote MDS with nodsh"
21124
21125         mkdir -p $DIR/$tdir
21126
21127         #define OBD_FAIL_OUT_ENOSPC     0x1704
21128         do_facet mds2 lctl set_param fail_loc=0x80001704
21129         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
21130                  && error "create striped directory should fail"
21131
21132         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
21133
21134         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
21135         true
21136 }
21137 run_test 300p "create striped directory without space"
21138
21139 test_300q() {
21140         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21141         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21142
21143         local fd=$(free_fd)
21144         local cmd="exec $fd<$tdir"
21145         cd $DIR
21146         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
21147         eval $cmd
21148         cmd="exec $fd<&-"
21149         trap "eval $cmd" EXIT
21150         cd $tdir || error "cd $tdir fails"
21151         rmdir  ../$tdir || error "rmdir $tdir fails"
21152         mkdir local_dir && error "create dir succeeds"
21153         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
21154         eval $cmd
21155         return 0
21156 }
21157 run_test 300q "create remote directory under orphan directory"
21158
21159 test_300r() {
21160         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21161                 skip "Need MDS version at least 2.7.55" && return
21162         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
21163
21164         mkdir $DIR/$tdir
21165
21166         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
21167                 error "set striped dir error"
21168
21169         $LFS getdirstripe $DIR/$tdir/striped_dir ||
21170                 error "getstripeddir fails"
21171
21172         local stripe_count
21173         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
21174                       awk '/lmv_stripe_count:/ { print $2 }')
21175
21176         [ $MDSCOUNT -ne $stripe_count ] &&
21177                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
21178
21179         rm -rf $DIR/$tdir/striped_dir ||
21180                 error "unlink striped dir fails"
21181 }
21182 run_test 300r "test -1 striped directory"
21183
21184 prepare_remote_file() {
21185         mkdir $DIR/$tdir/src_dir ||
21186                 error "create remote source failed"
21187
21188         cp /etc/hosts $DIR/$tdir/src_dir/a ||
21189                  error "cp to remote source failed"
21190         touch $DIR/$tdir/src_dir/a
21191
21192         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
21193                 error "create remote target dir failed"
21194
21195         touch $DIR/$tdir/tgt_dir/b
21196
21197         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
21198                 error "rename dir cross MDT failed!"
21199
21200         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
21201                 error "src_child still exists after rename"
21202
21203         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
21204                 error "missing file(a) after rename"
21205
21206         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
21207                 error "diff after rename"
21208 }
21209
21210 test_310a() {
21211         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
21212         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21213
21214         local remote_file=$DIR/$tdir/tgt_dir/b
21215
21216         mkdir -p $DIR/$tdir
21217
21218         prepare_remote_file || error "prepare remote file failed"
21219
21220         #open-unlink file
21221         $OPENUNLINK $remote_file $remote_file ||
21222                 error "openunlink $remote_file failed"
21223         $CHECKSTAT -a $remote_file || error "$remote_file exists"
21224 }
21225 run_test 310a "open unlink remote file"
21226
21227 test_310b() {
21228         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
21229         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21230
21231         local remote_file=$DIR/$tdir/tgt_dir/b
21232
21233         mkdir -p $DIR/$tdir
21234
21235         prepare_remote_file || error "prepare remote file failed"
21236
21237         ln $remote_file $DIR/$tfile || error "link failed for remote file"
21238         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
21239         $CHECKSTAT -t file $remote_file || error "check file failed"
21240 }
21241 run_test 310b "unlink remote file with multiple links while open"
21242
21243 test_310c() {
21244         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21245         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
21246
21247         local remote_file=$DIR/$tdir/tgt_dir/b
21248
21249         mkdir -p $DIR/$tdir
21250
21251         prepare_remote_file || error "prepare remote file failed"
21252
21253         ln $remote_file $DIR/$tfile || error "link failed for remote file"
21254         multiop_bg_pause $remote_file O_uc ||
21255                         error "mulitop failed for remote file"
21256         MULTIPID=$!
21257         $MULTIOP $DIR/$tfile Ouc
21258         kill -USR1 $MULTIPID
21259         wait $MULTIPID
21260 }
21261 run_test 310c "open-unlink remote file with multiple links"
21262
21263 #LU-4825
21264 test_311() {
21265         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21266         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
21267         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
21268                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
21269         remote_mds_nodsh && skip "remote MDS with nodsh"
21270
21271         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
21272         local mdts=$(comma_list $(mdts_nodes))
21273
21274         mkdir -p $DIR/$tdir
21275         $LFS setstripe -i 0 -c 1 $DIR/$tdir
21276         createmany -o $DIR/$tdir/$tfile. 1000
21277
21278         # statfs data is not real time, let's just calculate it
21279         old_iused=$((old_iused + 1000))
21280
21281         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21282                         osp.*OST0000*MDT0000.create_count")
21283         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21284                                 osp.*OST0000*MDT0000.max_create_count")
21285         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
21286
21287         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
21288         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
21289         [ $index -ne 0 ] || error "$tfile stripe index is 0"
21290
21291         unlinkmany $DIR/$tdir/$tfile. 1000
21292
21293         do_nodes $mdts "$LCTL set_param -n \
21294                         osp.*OST0000*.max_create_count=$max_count"
21295         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
21296                 do_nodes $mdts "$LCTL set_param -n \
21297                                 osp.*OST0000*.create_count=$count"
21298         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
21299                         grep "=0" && error "create_count is zero"
21300
21301         local new_iused
21302         for i in $(seq 120); do
21303                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
21304                 # system may be too busy to destroy all objs in time, use
21305                 # a somewhat small value to not fail autotest
21306                 [ $((old_iused - new_iused)) -gt 400 ] && break
21307                 sleep 1
21308         done
21309
21310         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
21311         [ $((old_iused - new_iused)) -gt 400 ] ||
21312                 error "objs not destroyed after unlink"
21313 }
21314 run_test 311 "disable OSP precreate, and unlink should destroy objs"
21315
21316 zfs_oid_to_objid()
21317 {
21318         local ost=$1
21319         local objid=$2
21320
21321         local vdevdir=$(dirname $(facet_vdevice $ost))
21322         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
21323         local zfs_zapid=$(do_facet $ost $cmd |
21324                           grep -w "/O/0/d$((objid%32))" -C 5 |
21325                           awk '/Object/{getline; print $1}')
21326         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
21327                           awk "/$objid = /"'{printf $3}')
21328
21329         echo $zfs_objid
21330 }
21331
21332 zfs_object_blksz() {
21333         local ost=$1
21334         local objid=$2
21335
21336         local vdevdir=$(dirname $(facet_vdevice $ost))
21337         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
21338         local blksz=$(do_facet $ost $cmd $objid |
21339                       awk '/dblk/{getline; printf $4}')
21340
21341         case "${blksz: -1}" in
21342                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
21343                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
21344                 *) ;;
21345         esac
21346
21347         echo $blksz
21348 }
21349
21350 test_312() { # LU-4856
21351         remote_ost_nodsh && skip "remote OST with nodsh"
21352         [ "$ost1_FSTYPE" = "zfs" ] ||
21353                 skip_env "the test only applies to zfs"
21354
21355         local max_blksz=$(do_facet ost1 \
21356                           $ZFS get -p recordsize $(facet_device ost1) |
21357                           awk '!/VALUE/{print $3}')
21358
21359         # to make life a little bit easier
21360         $LFS mkdir -c 1 -i 0 $DIR/$tdir
21361         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21362
21363         local tf=$DIR/$tdir/$tfile
21364         touch $tf
21365         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
21366
21367         # Get ZFS object id
21368         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
21369         # block size change by sequential overwrite
21370         local bs
21371
21372         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
21373                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
21374
21375                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
21376                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
21377         done
21378         rm -f $tf
21379
21380         # block size change by sequential append write
21381         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
21382         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
21383         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
21384         local count
21385
21386         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
21387                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
21388                         oflag=sync conv=notrunc
21389
21390                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
21391                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
21392                         error "blksz error, actual $blksz, " \
21393                                 "expected: 2 * $count * $PAGE_SIZE"
21394         done
21395         rm -f $tf
21396
21397         # random write
21398         touch $tf
21399         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
21400         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
21401
21402         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
21403         blksz=$(zfs_object_blksz ost1 $zfs_objid)
21404         [ $blksz -eq $PAGE_SIZE ] ||
21405                 error "blksz error: $blksz, expected: $PAGE_SIZE"
21406
21407         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
21408         blksz=$(zfs_object_blksz ost1 $zfs_objid)
21409         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
21410
21411         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
21412         blksz=$(zfs_object_blksz ost1 $zfs_objid)
21413         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
21414 }
21415 run_test 312 "make sure ZFS adjusts its block size by write pattern"
21416
21417 test_313() {
21418         remote_ost_nodsh && skip "remote OST with nodsh"
21419
21420         local file=$DIR/$tfile
21421
21422         rm -f $file
21423         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
21424
21425         # define OBD_FAIL_TGT_RCVD_EIO           0x720
21426         do_facet ost1 "$LCTL set_param fail_loc=0x720"
21427         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
21428                 error "write should failed"
21429         do_facet ost1 "$LCTL set_param fail_loc=0"
21430         rm -f $file
21431 }
21432 run_test 313 "io should fail after last_rcvd update fail"
21433
21434 test_314() {
21435         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
21436
21437         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
21438         do_facet ost1 "$LCTL set_param fail_loc=0x720"
21439         rm -f $DIR/$tfile
21440         wait_delete_completed
21441         do_facet ost1 "$LCTL set_param fail_loc=0"
21442 }
21443 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
21444
21445 test_315() { # LU-618
21446         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
21447
21448         local file=$DIR/$tfile
21449         rm -f $file
21450
21451         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
21452                 error "multiop file write failed"
21453         $MULTIOP $file oO_RDONLY:r4063232_c &
21454         PID=$!
21455
21456         sleep 2
21457
21458         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
21459         kill -USR1 $PID
21460
21461         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
21462         rm -f $file
21463 }
21464 run_test 315 "read should be accounted"
21465
21466 test_316() {
21467         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21468         large_xattr_enabled || skip_env "ea_inode feature disabled"
21469
21470         rm -rf $DIR/$tdir/d
21471         mkdir -p $DIR/$tdir/d
21472         chown nobody $DIR/$tdir/d
21473         touch $DIR/$tdir/d/file
21474
21475         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
21476 }
21477 run_test 316 "lfs mv"
21478
21479 test_317() {
21480         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
21481                 skip "Need MDS version at least 2.11.53"
21482         if [ "$ost1_FSTYPE" == "zfs" ]; then
21483                 skip "LU-10370: no implementation for ZFS"
21484         fi
21485
21486         local trunc_sz
21487         local grant_blk_size
21488
21489         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
21490                         awk '/grant_block_size:/ { print $2; exit; }')
21491         #
21492         # Create File of size 5M. Truncate it to below size's and verify
21493         # blocks count.
21494         #
21495         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
21496                 error "Create file $DIR/$tfile failed"
21497         stack_trap "rm -f $DIR/$tfile" EXIT
21498
21499         for trunc_sz in 2097152 4097 4000 509 0; do
21500                 $TRUNCATE $DIR/$tfile $trunc_sz ||
21501                         error "truncate $tfile to $trunc_sz failed"
21502                 local sz=$(stat --format=%s $DIR/$tfile)
21503                 local blk=$(stat --format=%b $DIR/$tfile)
21504                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
21505                                      grant_blk_size) * 8))
21506
21507                 if [[ $blk -ne $trunc_blk ]]; then
21508                         $(which stat) $DIR/$tfile
21509                         error "Expected Block $trunc_blk got $blk for $tfile"
21510                 fi
21511
21512                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
21513                         error "Expected Size $trunc_sz got $sz for $tfile"
21514         done
21515
21516         #
21517         # sparse file test
21518         # Create file with a hole and write actual two blocks. Block count
21519         # must be 16.
21520         #
21521         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
21522                 conv=fsync || error "Create file : $DIR/$tfile"
21523
21524         # Calculate the final truncate size.
21525         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
21526
21527         #
21528         # truncate to size $trunc_sz bytes. Strip the last block
21529         # The block count must drop to 8
21530         #
21531         $TRUNCATE $DIR/$tfile $trunc_sz ||
21532                 error "truncate $tfile to $trunc_sz failed"
21533
21534         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
21535         sz=$(stat --format=%s $DIR/$tfile)
21536         blk=$(stat --format=%b $DIR/$tfile)
21537
21538         if [[ $blk -ne $trunc_bsz ]]; then
21539                 $(which stat) $DIR/$tfile
21540                 error "Expected Block $trunc_bsz got $blk for $tfile"
21541         fi
21542
21543         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
21544                 error "Expected Size $trunc_sz got $sz for $tfile"
21545 }
21546 run_test 317 "Verify blocks get correctly update after truncate"
21547
21548 test_318() {
21549         local old_max_active=$($LCTL get_param -n \
21550                             llite.*.max_read_ahead_async_active 2>/dev/null)
21551
21552         $LCTL set_param llite.*.max_read_ahead_async_active=256
21553         local max_active=$($LCTL get_param -n \
21554                            llite.*.max_read_ahead_async_active 2>/dev/null)
21555         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
21556
21557         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
21558                 error "set max_read_ahead_async_active should succeed"
21559
21560         $LCTL set_param llite.*.max_read_ahead_async_active=512
21561         max_active=$($LCTL get_param -n \
21562                      llite.*.max_read_ahead_async_active 2>/dev/null)
21563         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
21564
21565         # restore @max_active
21566         [ $old_max_active -ne 0 ] && $LCTL set_param \
21567                 llite.*.max_read_ahead_async_active=$old_max_active
21568
21569         local old_threshold=$($LCTL get_param -n \
21570                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
21571         local max_per_file_mb=$($LCTL get_param -n \
21572                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
21573
21574         local invalid=$(($max_per_file_mb + 1))
21575         $LCTL set_param \
21576                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
21577                         && error "set $invalid should fail"
21578
21579         local valid=$(($invalid - 1))
21580         $LCTL set_param \
21581                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
21582                         error "set $valid should succeed"
21583         local threshold=$($LCTL get_param -n \
21584                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
21585         [ $threshold -eq $valid ] || error \
21586                 "expect threshold $valid got $threshold"
21587         $LCTL set_param \
21588                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
21589 }
21590 run_test 318 "Verify async readahead tunables"
21591
21592 test_319() {
21593         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
21594
21595         local before=$(date +%s)
21596         local evict
21597         local mdir=$DIR/$tdir
21598         local file=$mdir/xxx
21599
21600         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
21601         touch $file
21602
21603 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
21604         $LCTL set_param fail_val=5 fail_loc=0x8000032c
21605         $LFS mv -m1 $file &
21606
21607         sleep 1
21608         dd if=$file of=/dev/null
21609         wait
21610         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
21611           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
21612
21613         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
21614 }
21615 run_test 319 "lost lease lock on migrate error"
21616
21617 test_398a() { # LU-4198
21618         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21619         $LCTL set_param ldlm.namespaces.*.lru_size=clear
21620
21621         # request a new lock on client
21622         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
21623
21624         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
21625         local lock_count=$($LCTL get_param -n \
21626                            ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
21627         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
21628
21629         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
21630
21631         # no lock cached, should use lockless IO and not enqueue new lock
21632         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
21633         lock_count=$($LCTL get_param -n \
21634                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
21635         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
21636 }
21637 run_test 398a "direct IO should cancel lock otherwise lockless"
21638
21639 test_398b() { # LU-4198
21640         which fio || skip_env "no fio installed"
21641         $LFS setstripe -c -1 $DIR/$tfile
21642
21643         local size=12
21644         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
21645
21646         local njobs=4
21647         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
21648         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
21649                 --numjobs=$njobs --fallocate=none \
21650                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
21651                 --filename=$DIR/$tfile &
21652         bg_pid=$!
21653
21654         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
21655         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
21656                 --numjobs=$njobs --fallocate=none \
21657                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
21658                 --filename=$DIR/$tfile || true
21659         wait $bg_pid
21660
21661         rm -rf $DIR/$tfile
21662 }
21663 run_test 398b "DIO and buffer IO race"
21664
21665 test_398c() { # LU-4198
21666         which fio || skip_env "no fio installed"
21667
21668         saved_debug=$($LCTL get_param -n debug)
21669         $LCTL set_param debug=0
21670
21671         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
21672         ((size /= 1024)) # by megabytes
21673         ((size /= 2)) # write half of the OST at most
21674         [ $size -gt 40 ] && size=40 #reduce test time anyway
21675
21676         $LFS setstripe -c 1 $DIR/$tfile
21677
21678         # it seems like ldiskfs reserves more space than necessary if the
21679         # writing blocks are not mapped, so it extends the file firstly
21680         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
21681         cancel_lru_locks osc
21682
21683         # clear and verify rpc_stats later
21684         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
21685
21686         local njobs=4
21687         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
21688         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
21689                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
21690                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
21691                 --filename=$DIR/$tfile
21692         [ $? -eq 0 ] || error "fio write error"
21693
21694         [ $($LCTL get_param -n \
21695          ldlm.namespaces.${FSNAME}-OST0000-osc-ffff*.lock_count) -eq 0 ] ||
21696                 error "Locks were requested while doing AIO"
21697
21698         # get the percentage of 1-page I/O
21699         pct=$($LCTL get_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats |
21700                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
21701                 awk '{print $7}')
21702         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
21703
21704         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
21705         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
21706                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
21707                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
21708                 --filename=$DIR/$tfile
21709         [ $? -eq 0 ] || error "fio mixed read write error"
21710
21711         rm -rf $DIR/$tfile
21712         $LCTL set_param debug="$saved_debug"
21713 }
21714 run_test 398c "run fio to test AIO"
21715
21716 test_fake_rw() {
21717         local read_write=$1
21718         if [ "$read_write" = "write" ]; then
21719                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
21720         elif [ "$read_write" = "read" ]; then
21721                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
21722         else
21723                 error "argument error"
21724         fi
21725
21726         # turn off debug for performance testing
21727         local saved_debug=$($LCTL get_param -n debug)
21728         $LCTL set_param debug=0
21729
21730         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21731
21732         # get ost1 size - $FSNAME-OST0000
21733         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
21734         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
21735         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
21736
21737         if [ "$read_write" = "read" ]; then
21738                 truncate -s $(expr 1048576 \* $blocks) $DIR/$tfile
21739         fi
21740
21741         local start_time=$(date +%s.%N)
21742         $dd_cmd bs=1M count=$blocks oflag=sync ||
21743                 error "real dd $read_write error"
21744         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
21745
21746         if [ "$read_write" = "write" ]; then
21747                 rm -f $DIR/$tfile
21748         fi
21749
21750         # define OBD_FAIL_OST_FAKE_RW           0x238
21751         do_facet ost1 $LCTL set_param fail_loc=0x238
21752
21753         local start_time=$(date +%s.%N)
21754         $dd_cmd bs=1M count=$blocks oflag=sync ||
21755                 error "fake dd $read_write error"
21756         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
21757
21758         if [ "$read_write" = "write" ]; then
21759                 # verify file size
21760                 cancel_lru_locks osc
21761                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
21762                         error "$tfile size not $blocks MB"
21763         fi
21764         do_facet ost1 $LCTL set_param fail_loc=0
21765
21766         echo "fake $read_write $duration_fake vs. normal $read_write" \
21767                 "$duration in seconds"
21768         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
21769                 error_not_in_vm "fake write is slower"
21770
21771         $LCTL set_param -n debug="$saved_debug"
21772         rm -f $DIR/$tfile
21773 }
21774 test_399a() { # LU-7655 for OST fake write
21775         remote_ost_nodsh && skip "remote OST with nodsh"
21776
21777         test_fake_rw write
21778 }
21779 run_test 399a "fake write should not be slower than normal write"
21780
21781 test_399b() { # LU-8726 for OST fake read
21782         remote_ost_nodsh && skip "remote OST with nodsh"
21783         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
21784                 skip_env "ldiskfs only test"
21785         fi
21786
21787         test_fake_rw read
21788 }
21789 run_test 399b "fake read should not be slower than normal read"
21790
21791 test_400a() { # LU-1606, was conf-sanity test_74
21792         if ! which $CC > /dev/null 2>&1; then
21793                 skip_env "$CC is not installed"
21794         fi
21795
21796         local extra_flags=''
21797         local out=$TMP/$tfile
21798         local prefix=/usr/include/lustre
21799         local prog
21800
21801         # Oleg removes c files in his test rig so test if any c files exist
21802         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
21803                 skip_env "Needed c test files are missing"
21804
21805         if ! [[ -d $prefix ]]; then
21806                 # Assume we're running in tree and fixup the include path.
21807                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
21808                 extra_flags+=" -L$LUSTRE/utils/.lib"
21809         fi
21810
21811         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
21812                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
21813                         error "client api broken"
21814         done
21815         rm -f $out
21816 }
21817 run_test 400a "Lustre client api program can compile and link"
21818
21819 test_400b() { # LU-1606, LU-5011
21820         local header
21821         local out=$TMP/$tfile
21822         local prefix=/usr/include/linux/lustre
21823
21824         # We use a hard coded prefix so that this test will not fail
21825         # when run in tree. There are headers in lustre/include/lustre/
21826         # that are not packaged (like lustre_idl.h) and have more
21827         # complicated include dependencies (like config.h and lnet/types.h).
21828         # Since this test about correct packaging we just skip them when
21829         # they don't exist (see below) rather than try to fixup cppflags.
21830
21831         if ! which $CC > /dev/null 2>&1; then
21832                 skip_env "$CC is not installed"
21833         fi
21834
21835         for header in $prefix/*.h; do
21836                 if ! [[ -f "$header" ]]; then
21837                         continue
21838                 fi
21839
21840                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
21841                         continue # lustre_ioctl.h is internal header
21842                 fi
21843
21844                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
21845                         error "cannot compile '$header'"
21846         done
21847         rm -f $out
21848 }
21849 run_test 400b "packaged headers can be compiled"
21850
21851 test_401a() { #LU-7437
21852         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
21853         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
21854
21855         #count the number of parameters by "list_param -R"
21856         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
21857         #count the number of parameters by listing proc files
21858         local proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
21859         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
21860         echo "proc_dirs='$proc_dirs'"
21861         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
21862         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
21863                       sort -u | wc -l)
21864
21865         [ $params -eq $procs ] ||
21866                 error "found $params parameters vs. $procs proc files"
21867
21868         # test the list_param -D option only returns directories
21869         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
21870         #count the number of parameters by listing proc directories
21871         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
21872                 sort -u | wc -l)
21873
21874         [ $params -eq $procs ] ||
21875                 error "found $params parameters vs. $procs proc files"
21876 }
21877 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
21878
21879 test_401b() {
21880         local save=$($LCTL get_param -n jobid_var)
21881         local tmp=testing
21882
21883         $LCTL set_param foo=bar jobid_var=$tmp bar=baz &&
21884                 error "no error returned when setting bad parameters"
21885
21886         local jobid_new=$($LCTL get_param -n foe jobid_var baz)
21887         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
21888
21889         $LCTL set_param -n fog=bam jobid_var=$save bat=fog
21890         local jobid_old=$($LCTL get_param -n foe jobid_var bag)
21891         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
21892 }
21893 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
21894
21895 test_401c() {
21896         local jobid_var_old=$($LCTL get_param -n jobid_var)
21897         local jobid_var_new
21898
21899         $LCTL set_param jobid_var= &&
21900                 error "no error returned for 'set_param a='"
21901
21902         jobid_var_new=$($LCTL get_param -n jobid_var)
21903         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
21904                 error "jobid_var was changed by setting without value"
21905
21906         $LCTL set_param jobid_var &&
21907                 error "no error returned for 'set_param a'"
21908
21909         jobid_var_new=$($LCTL get_param -n jobid_var)
21910         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
21911                 error "jobid_var was changed by setting without value"
21912 }
21913 run_test 401c "Verify 'lctl set_param' without value fails in either format."
21914
21915 test_401d() {
21916         local jobid_var_old=$($LCTL get_param -n jobid_var)
21917         local jobid_var_new
21918         local new_value="foo=bar"
21919
21920         $LCTL set_param jobid_var=$new_value ||
21921                 error "'set_param a=b' did not accept a value containing '='"
21922
21923         jobid_var_new=$($LCTL get_param -n jobid_var)
21924         [[ "$jobid_var_new" == "$new_value" ]] ||
21925                 error "'set_param a=b' failed on a value containing '='"
21926
21927         # Reset the jobid_var to test the other format
21928         $LCTL set_param jobid_var=$jobid_var_old
21929         jobid_var_new=$($LCTL get_param -n jobid_var)
21930         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
21931                 error "failed to reset jobid_var"
21932
21933         $LCTL set_param jobid_var $new_value ||
21934                 error "'set_param a b' did not accept a value containing '='"
21935
21936         jobid_var_new=$($LCTL get_param -n jobid_var)
21937         [[ "$jobid_var_new" == "$new_value" ]] ||
21938                 error "'set_param a b' failed on a value containing '='"
21939
21940         $LCTL set_param jobid_var $jobid_var_old
21941         jobid_var_new=$($LCTL get_param -n jobid_var)
21942         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
21943                 error "failed to reset jobid_var"
21944 }
21945 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
21946
21947 test_402() {
21948         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
21949         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
21950                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
21951         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
21952                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
21953                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
21954         remote_mds_nodsh && skip "remote MDS with nodsh"
21955
21956         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
21957 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
21958         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
21959         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
21960                 echo "Touch failed - OK"
21961 }
21962 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
21963
21964 test_403() {
21965         local file1=$DIR/$tfile.1
21966         local file2=$DIR/$tfile.2
21967         local tfile=$TMP/$tfile
21968
21969         rm -f $file1 $file2 $tfile
21970
21971         touch $file1
21972         ln $file1 $file2
21973
21974         # 30 sec OBD_TIMEOUT in ll_getattr()
21975         # right before populating st_nlink
21976         $LCTL set_param fail_loc=0x80001409
21977         stat -c %h $file1 > $tfile &
21978
21979         # create an alias, drop all locks and reclaim the dentry
21980         < $file2
21981         cancel_lru_locks mdc
21982         cancel_lru_locks osc
21983         sysctl -w vm.drop_caches=2
21984
21985         wait
21986
21987         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
21988
21989         rm -f $tfile $file1 $file2
21990 }
21991 run_test 403 "i_nlink should not drop to zero due to aliasing"
21992
21993 test_404() { # LU-6601
21994         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
21995                 skip "Need server version newer than 2.8.52"
21996         remote_mds_nodsh && skip "remote MDS with nodsh"
21997
21998         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
21999                 awk '/osp .*-osc-MDT/ { print $4}')
22000
22001         local osp
22002         for osp in $mosps; do
22003                 echo "Deactivate: " $osp
22004                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
22005                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
22006                         awk -vp=$osp '$4 == p { print $2 }')
22007                 [ $stat = IN ] || {
22008                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
22009                         error "deactivate error"
22010                 }
22011                 echo "Activate: " $osp
22012                 do_facet $SINGLEMDS $LCTL --device %$osp activate
22013                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
22014                         awk -vp=$osp '$4 == p { print $2 }')
22015                 [ $stat = UP ] || {
22016                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
22017                         error "activate error"
22018                 }
22019         done
22020 }
22021 run_test 404 "validate manual {de}activated works properly for OSPs"
22022
22023 test_405() {
22024         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
22025         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
22026                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
22027                         skip "Layout swap lock is not supported"
22028
22029         check_swap_layouts_support
22030
22031         test_mkdir $DIR/$tdir
22032         swap_lock_test -d $DIR/$tdir ||
22033                 error "One layout swap locked test failed"
22034 }
22035 run_test 405 "Various layout swap lock tests"
22036
22037 test_406() {
22038         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22039         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
22040         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
22041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22042         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
22043                 skip "Need MDS version at least 2.8.50"
22044
22045         local def_stripe_size=$($LFS getstripe -S $MOUNT)
22046         local test_pool=$TESTNAME
22047
22048         pool_add $test_pool || error "pool_add failed"
22049         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
22050                 error "pool_add_targets failed"
22051
22052         save_layout_restore_at_exit $MOUNT
22053
22054         # parent set default stripe count only, child will stripe from both
22055         # parent and fs default
22056         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
22057                 error "setstripe $MOUNT failed"
22058         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
22059         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
22060         for i in $(seq 10); do
22061                 local f=$DIR/$tdir/$tfile.$i
22062                 touch $f || error "touch failed"
22063                 local count=$($LFS getstripe -c $f)
22064                 [ $count -eq $OSTCOUNT ] ||
22065                         error "$f stripe count $count != $OSTCOUNT"
22066                 local offset=$($LFS getstripe -i $f)
22067                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
22068                 local size=$($LFS getstripe -S $f)
22069                 [ $size -eq $((def_stripe_size * 2)) ] ||
22070                         error "$f stripe size $size != $((def_stripe_size * 2))"
22071                 local pool=$($LFS getstripe -p $f)
22072                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
22073         done
22074
22075         # change fs default striping, delete parent default striping, now child
22076         # will stripe from new fs default striping only
22077         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
22078                 error "change $MOUNT default stripe failed"
22079         $LFS setstripe -c 0 $DIR/$tdir ||
22080                 error "delete $tdir default stripe failed"
22081         for i in $(seq 11 20); do
22082                 local f=$DIR/$tdir/$tfile.$i
22083                 touch $f || error "touch $f failed"
22084                 local count=$($LFS getstripe -c $f)
22085                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
22086                 local offset=$($LFS getstripe -i $f)
22087                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
22088                 local size=$($LFS getstripe -S $f)
22089                 [ $size -eq $def_stripe_size ] ||
22090                         error "$f stripe size $size != $def_stripe_size"
22091                 local pool=$($LFS getstripe -p $f)
22092                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
22093         done
22094
22095         unlinkmany $DIR/$tdir/$tfile. 1 20
22096
22097         local f=$DIR/$tdir/$tfile
22098         pool_remove_all_targets $test_pool $f
22099         pool_remove $test_pool $f
22100 }
22101 run_test 406 "DNE support fs default striping"
22102
22103 test_407() {
22104         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22105         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
22106                 skip "Need MDS version at least 2.8.55"
22107         remote_mds_nodsh && skip "remote MDS with nodsh"
22108
22109         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
22110                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
22111         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
22112                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
22113         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
22114
22115         #define OBD_FAIL_DT_TXN_STOP    0x2019
22116         for idx in $(seq $MDSCOUNT); do
22117                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
22118         done
22119         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
22120         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
22121                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
22122         true
22123 }
22124 run_test 407 "transaction fail should cause operation fail"
22125
22126 test_408() {
22127         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
22128
22129         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
22130         lctl set_param fail_loc=0x8000040a
22131         # let ll_prepare_partial_page() fail
22132         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
22133
22134         rm -f $DIR/$tfile
22135
22136         # create at least 100 unused inodes so that
22137         # shrink_icache_memory(0) should not return 0
22138         touch $DIR/$tfile-{0..100}
22139         rm -f $DIR/$tfile-{0..100}
22140         sync
22141
22142         echo 2 > /proc/sys/vm/drop_caches
22143 }
22144 run_test 408 "drop_caches should not hang due to page leaks"
22145
22146 test_409()
22147 {
22148         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22149
22150         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
22151         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
22152         touch $DIR/$tdir/guard || error "(2) Fail to create"
22153
22154         local PREFIX=$(str_repeat 'A' 128)
22155         echo "Create 1K hard links start at $(date)"
22156         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
22157                 error "(3) Fail to hard link"
22158
22159         echo "Links count should be right although linkEA overflow"
22160         stat $DIR/$tdir/guard || error "(4) Fail to stat"
22161         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
22162         [ $linkcount -eq 1001 ] ||
22163                 error "(5) Unexpected hard links count: $linkcount"
22164
22165         echo "List all links start at $(date)"
22166         ls -l $DIR/$tdir/foo > /dev/null ||
22167                 error "(6) Fail to list $DIR/$tdir/foo"
22168
22169         echo "Unlink hard links start at $(date)"
22170         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
22171                 error "(7) Fail to unlink"
22172         echo "Unlink hard links finished at $(date)"
22173 }
22174 run_test 409 "Large amount of cross-MDTs hard links on the same file"
22175
22176 test_410()
22177 {
22178         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
22179                 skip "Need client version at least 2.9.59"
22180
22181         # Create a file, and stat it from the kernel
22182         local testfile=$DIR/$tfile
22183         touch $testfile
22184
22185         local run_id=$RANDOM
22186         local my_ino=$(stat --format "%i" $testfile)
22187
22188         # Try to insert the module. This will always fail as the
22189         # module is designed to not be inserted.
22190         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
22191             &> /dev/null
22192
22193         # Anything but success is a test failure
22194         dmesg | grep -q \
22195             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
22196             error "no inode match"
22197 }
22198 run_test 410 "Test inode number returned from kernel thread"
22199
22200 cleanup_test411_cgroup() {
22201         trap 0
22202         rmdir "$1"
22203 }
22204
22205 test_411() {
22206         local cg_basedir=/sys/fs/cgroup/memory
22207         # LU-9966
22208         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
22209                 skip "no setup for cgroup"
22210
22211         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
22212                 error "test file creation failed"
22213         cancel_lru_locks osc
22214
22215         # Create a very small memory cgroup to force a slab allocation error
22216         local cgdir=$cg_basedir/osc_slab_alloc
22217         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
22218         trap "cleanup_test411_cgroup $cgdir" EXIT
22219         echo 2M > $cgdir/memory.kmem.limit_in_bytes
22220         echo 1M > $cgdir/memory.limit_in_bytes
22221
22222         # Should not LBUG, just be killed by oom-killer
22223         # dd will return 0 even allocation failure in some environment.
22224         # So don't check return value
22225         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
22226         cleanup_test411_cgroup $cgdir
22227
22228         return 0
22229 }
22230 run_test 411 "Slab allocation error with cgroup does not LBUG"
22231
22232 test_412() {
22233         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22234         if [ $MDS1_VERSION -lt $(version_code 2.10.55) ]; then
22235                 skip "Need server version at least 2.10.55"
22236         fi
22237
22238         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
22239                 error "mkdir failed"
22240         $LFS getdirstripe $DIR/$tdir
22241         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
22242         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
22243                 error "expect $((MDSCOUT - 1)) get $stripe_index"
22244         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
22245         [ $stripe_count -eq 2 ] ||
22246                 error "expect 2 get $stripe_count"
22247 }
22248 run_test 412 "mkdir on specific MDTs"
22249
22250 test_qos_mkdir() {
22251         local mkdir_cmd=$1
22252         local stripe_count=$2
22253         local mdts=$(comma_list $(mdts_nodes))
22254
22255         local testdir
22256         local lmv_qos_prio_free
22257         local lmv_qos_threshold_rr
22258         local lmv_qos_maxage
22259         local lod_qos_prio_free
22260         local lod_qos_threshold_rr
22261         local lod_qos_maxage
22262         local count
22263         local i
22264
22265         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
22266         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
22267         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
22268                 head -n1)
22269         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
22270         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
22271         stack_trap "$LCTL set_param \
22272                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null" EXIT
22273         stack_trap "$LCTL set_param \
22274                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
22275         stack_trap "$LCTL set_param \
22276                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" EXIT
22277
22278         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
22279                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
22280         lod_qos_prio_free=${lod_qos_prio_free%%%}
22281         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
22282                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
22283         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
22284         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
22285                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
22286         stack_trap "do_nodes $mdts $LCTL set_param \
22287                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null" EXIT
22288         stack_trap "do_nodes $mdts $LCTL set_param \
22289                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null" \
22290                 EXIT
22291         stack_trap "do_nodes $mdts $LCTL set_param \
22292                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" EXIT
22293
22294         echo
22295         echo "Mkdir (stripe_count $stripe_count) roundrobin:"
22296
22297         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
22298         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
22299
22300         testdir=$DIR/$tdir-s$stripe_count/rr
22301
22302         for i in $(seq $((100 * MDSCOUNT))); do
22303                 eval $mkdir_cmd $testdir/subdir$i ||
22304                         error "$mkdir_cmd subdir$i failed"
22305         done
22306
22307         for i in $(seq $MDSCOUNT); do
22308                 count=$($LFS getdirstripe -i $testdir/* |
22309                                 grep ^$((i - 1))$ | wc -l)
22310                 echo "$count directories created on MDT$((i - 1))"
22311                 [ $count -eq 100 ] || error "subdirs are not evenly distributed"
22312
22313                 if [ $stripe_count -gt 1 ]; then
22314                         count=$($LFS getdirstripe $testdir/* |
22315                                 grep -P "^\s+$((i - 1))\t" | wc -l)
22316                         echo "$count stripes created on MDT$((i - 1))"
22317                         # deviation should < 5% of average
22318                         [ $count -lt $((95 * stripe_count)) ] ||
22319                         [ $count -gt $((105 * stripe_count)) ] &&
22320                                 error "stripes are not evenly distributed"
22321                 fi
22322         done
22323
22324         $LCTL set_param lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null
22325         do_nodes $mdts $LCTL set_param \
22326                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null
22327
22328         echo
22329         echo "Check for uneven MDTs: "
22330
22331         local ffree
22332         local bavail
22333         local max
22334         local min
22335         local max_index
22336         local min_index
22337         local tmp
22338
22339         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
22340         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
22341         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
22342
22343         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
22344         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
22345         max_index=0
22346         min_index=0
22347         for ((i = 1; i < ${#ffree[@]}; i++)); do
22348                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
22349                 if [ $tmp -gt $max ]; then
22350                         max=$tmp
22351                         max_index=$i
22352                 fi
22353                 if [ $tmp -lt $min ]; then
22354                         min=$tmp
22355                         min_index=$i
22356                 fi
22357         done
22358
22359         [ ${ffree[min_index]} -eq 0 ] &&
22360                 skip "no free files in MDT$min_index"
22361         [ ${ffree[min_index]} -gt 100000000 ] &&
22362                 skip "too much free files in MDT$min_index"
22363
22364         # Check if we need to generate uneven MDTs
22365         local threshold=50
22366         local diff=$(((max - min) * 100 / min))
22367         local value="$(generate_string 1024)"
22368
22369         while [ $diff -lt $threshold ]; do
22370                 # generate uneven MDTs, create till $threshold% diff
22371                 echo -n "weight diff=$diff% must be > $threshold% ..."
22372                 count=$((${ffree[min_index]} / 10))
22373                 # 50 sec per 10000 files in vm
22374                 [ $count -gt 40000 ] && [ "$SLOW" = "no" ] &&
22375                         skip "$count files to create"
22376                 echo "Fill MDT$min_index with $count files"
22377                 [ -d $DIR/$tdir-MDT$min_index ] ||
22378                         $LFS mkdir -i $min_index $DIR/$tdir-MDT$min_index ||
22379                         error "mkdir $tdir-MDT$min_index failed"
22380                 for i in $(seq $count); do
22381                         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE \
22382                                 $DIR/$tdir-MDT$min_index/f$j_$i > /dev/null ||
22383                                 error "create f$j_$i failed"
22384                         setfattr -n user.413b -v $value \
22385                                 $DIR/$tdir-MDT$min_index/f$j_$i ||
22386                                 error "setfattr f$j_$i failed"
22387                 done
22388
22389                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
22390                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
22391                 max=$(((${ffree[max_index]} >> 8) * \
22392                         (${bavail[max_index]} * bsize >> 16)))
22393                 min=$(((${ffree[min_index]} >> 8) * \
22394                         (${bavail[min_index]} * bsize >> 16)))
22395                 diff=$(((max - min) * 100 / min))
22396         done
22397
22398         echo "MDT filesfree available: ${ffree[@]}"
22399         echo "MDT blocks available: ${bavail[@]}"
22400         echo "weight diff=$diff%"
22401
22402         echo
22403         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
22404
22405         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
22406         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
22407         # decrease statfs age, so that it can be updated in time
22408         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
22409         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
22410
22411         sleep 1
22412
22413         testdir=$DIR/$tdir-s$stripe_count/qos
22414
22415         for i in $(seq $((100 * MDSCOUNT))); do
22416                 eval $mkdir_cmd $testdir/subdir$i ||
22417                         error "$mkdir_cmd subdir$i failed"
22418         done
22419
22420         for i in $(seq $MDSCOUNT); do
22421                 count=$($LFS getdirstripe -i $testdir/* | grep ^$((i - 1))$ |
22422                         wc -l)
22423                 echo "$count directories created on MDT$((i - 1))"
22424
22425                 if [ $stripe_count -gt 1 ]; then
22426                         count=$($LFS getdirstripe $testdir/* |
22427                                 grep -P "^\s+$((i - 1))\t" | wc -l)
22428                         echo "$count stripes created on MDT$((i - 1))"
22429                 fi
22430         done
22431
22432         max=$($LFS getdirstripe -i $testdir/* | grep ^$max_index$ | wc -l)
22433         min=$($LFS getdirstripe -i $testdir/* | grep ^$min_index$ | wc -l)
22434
22435         # D-value should > 10% of averge
22436         [ $((max - min)) -lt 10 ] &&
22437                 error "subdirs shouldn't be evenly distributed"
22438
22439         # ditto
22440         if [ $stripe_count -gt 1 ]; then
22441                 max=$($LFS getdirstripe $testdir/* |
22442                         grep -P "^\s+$max_index\t" | wc -l)
22443                 min=$($LFS getdirstripe $testdir/* |
22444                         grep -P "^\s+$min_index\t" | wc -l)
22445                 [ $((max - min)) -le $((10 * stripe_count)) ] &&
22446                         error "stripes shouldn't be evenly distributed"|| true
22447         fi
22448 }
22449
22450 test_413a() {
22451         [ $MDSCOUNT -lt 2 ] &&
22452                 skip "We need at least 2 MDTs for this test"
22453
22454         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
22455                 skip "Need server version at least 2.12.52"
22456
22457         local stripe_count
22458
22459         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
22460                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
22461                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
22462                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
22463                 test_qos_mkdir "$LFS mkdir -c $stripe_count" $stripe_count
22464         done
22465 }
22466 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
22467
22468 test_413b() {
22469         [ $MDSCOUNT -lt 2 ] &&
22470                 skip "We need at least 2 MDTs for this test"
22471
22472         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
22473                 skip "Need server version at least 2.12.52"
22474
22475         local stripe_count
22476
22477         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
22478                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
22479                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
22480                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
22481                 $LFS setdirstripe -D -c $stripe_count \
22482                         $DIR/$tdir-s$stripe_count/rr ||
22483                         error "setdirstripe failed"
22484                 $LFS setdirstripe -D -c $stripe_count \
22485                         $DIR/$tdir-s$stripe_count/qos ||
22486                         error "setdirstripe failed"
22487                 test_qos_mkdir "mkdir" $stripe_count
22488         done
22489 }
22490 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
22491
22492 test_414() {
22493 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
22494         $LCTL set_param fail_loc=0x80000521
22495         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
22496         rm -f $DIR/$tfile
22497 }
22498 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
22499
22500 test_415() {
22501         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22502         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22503                 skip "Need server version at least 2.11.52"
22504
22505         # LU-11102
22506         local total
22507         local setattr_pid
22508         local start_time
22509         local end_time
22510         local duration
22511
22512         total=500
22513         # this test may be slow on ZFS
22514         [ "$mds1_FSTYPE" == "zfs" ] && total=100
22515
22516         # though this test is designed for striped directory, let's test normal
22517         # directory too since lock is always saved as CoS lock.
22518         test_mkdir $DIR/$tdir || error "mkdir $tdir"
22519         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
22520
22521         (
22522                 while true; do
22523                         touch $DIR/$tdir
22524                 done
22525         ) &
22526         setattr_pid=$!
22527
22528         start_time=$(date +%s)
22529         for i in $(seq $total); do
22530                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
22531                         > /dev/null
22532         done
22533         end_time=$(date +%s)
22534         duration=$((end_time - start_time))
22535
22536         kill -9 $setattr_pid
22537
22538         echo "rename $total files took $duration sec"
22539         [ $duration -lt 100 ] || error "rename took $duration sec"
22540 }
22541 run_test 415 "lock revoke is not missing"
22542
22543 test_416() {
22544         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
22545                 skip "Need server version at least 2.11.55"
22546
22547         # define OBD_FAIL_OSD_TXN_START    0x19a
22548         do_facet mds1 lctl set_param fail_loc=0x19a
22549
22550         lfs mkdir -c $MDSCOUNT $DIR/$tdir
22551
22552         true
22553 }
22554 run_test 416 "transaction start failure won't cause system hung"
22555
22556 cleanup_417() {
22557         trap 0
22558         do_nodes $(comma_list $(mdts_nodes)) \
22559                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
22560         do_nodes $(comma_list $(mdts_nodes)) \
22561                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
22562         do_nodes $(comma_list $(mdts_nodes)) \
22563                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
22564 }
22565
22566 test_417() {
22567         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22568         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
22569                 skip "Need MDS version at least 2.11.56"
22570
22571         trap cleanup_417 RETURN EXIT
22572
22573         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
22574         do_nodes $(comma_list $(mdts_nodes)) \
22575                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
22576         $LFS migrate -m 0 $DIR/$tdir.1 &&
22577                 error "migrate dir $tdir.1 should fail"
22578
22579         do_nodes $(comma_list $(mdts_nodes)) \
22580                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
22581         $LFS mkdir -i 1 $DIR/$tdir.2 &&
22582                 error "create remote dir $tdir.2 should fail"
22583
22584         do_nodes $(comma_list $(mdts_nodes)) \
22585                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
22586         $LFS mkdir -c 2 $DIR/$tdir.3 &&
22587                 error "create striped dir $tdir.3 should fail"
22588         true
22589 }
22590 run_test 417 "disable remote dir, striped dir and dir migration"
22591
22592 # Checks that the outputs of df [-i] and lfs df [-i] match
22593 #
22594 # usage: check_lfs_df <blocks | inodes> <mountpoint>
22595 check_lfs_df() {
22596         local dir=$2
22597         local inodes
22598         local df_out
22599         local lfs_df_out
22600         local count
22601         local passed=false
22602
22603         # blocks or inodes
22604         [ "$1" == "blocks" ] && inodes= || inodes="-i"
22605
22606         for count in {1..100}; do
22607                 cancel_lru_locks
22608                 sync; sleep 0.2
22609
22610                 # read the lines of interest
22611                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
22612                         error "df $inodes $dir | tail -n +2 failed"
22613                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
22614                         error "lfs df $inodes $dir | grep summary: failed"
22615
22616                 # skip first substrings of each output as they are different
22617                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
22618                 # compare the two outputs
22619                 passed=true
22620                 for i in {1..5}; do
22621                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
22622                 done
22623                 $passed && break
22624         done
22625
22626         if ! $passed; then
22627                 df -P $inodes $dir
22628                 echo
22629                 lfs df $inodes $dir
22630                 error "df and lfs df $1 output mismatch: "      \
22631                       "df ${inodes}: ${df_out[*]}, "            \
22632                       "lfs df ${inodes}: ${lfs_df_out[*]}"
22633         fi
22634 }
22635
22636 test_418() {
22637         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22638
22639         local dir=$DIR/$tdir
22640         local numfiles=$((RANDOM % 4096 + 2))
22641         local numblocks=$((RANDOM % 256 + 1))
22642
22643         wait_delete_completed
22644         test_mkdir $dir
22645
22646         # check block output
22647         check_lfs_df blocks $dir
22648         # check inode output
22649         check_lfs_df inodes $dir
22650
22651         # create a single file and retest
22652         echo "Creating a single file and testing"
22653         createmany -o $dir/$tfile- 1 &>/dev/null ||
22654                 error "creating 1 file in $dir failed"
22655         check_lfs_df blocks $dir
22656         check_lfs_df inodes $dir
22657
22658         # create a random number of files
22659         echo "Creating $((numfiles - 1)) files and testing"
22660         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
22661                 error "creating $((numfiles - 1)) files in $dir failed"
22662
22663         # write a random number of blocks to the first test file
22664         echo "Writing $numblocks 4K blocks and testing"
22665         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
22666                 count=$numblocks &>/dev/null ||
22667                 error "dd to $dir/${tfile}-0 failed"
22668
22669         # retest
22670         check_lfs_df blocks $dir
22671         check_lfs_df inodes $dir
22672
22673         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
22674                 error "unlinking $numfiles files in $dir failed"
22675 }
22676 run_test 418 "df and lfs df outputs match"
22677
22678 test_419()
22679 {
22680         local dir=$DIR/$tdir
22681
22682         mkdir -p $dir
22683         touch $dir/file
22684
22685         cancel_lru_locks mdc
22686
22687         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
22688         $LCTL set_param fail_loc=0x1410
22689         cat $dir/file
22690         $LCTL set_param fail_loc=0
22691         rm -rf $dir
22692 }
22693 run_test 419 "Verify open file by name doesn't crash kernel"
22694
22695 test_420()
22696 {
22697         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
22698                 skip "Need MDS version at least 2.12.53"
22699
22700         local SAVE_UMASK=$(umask)
22701         local dir=$DIR/$tdir
22702         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
22703
22704         mkdir -p $dir
22705         umask 0000
22706         mkdir -m03777 $dir/testdir
22707         ls -dn $dir/testdir
22708         # Need to remove trailing '.' when SELinux is enabled
22709         local dirperms=$(ls -dn $dir/testdir |
22710                          awk '{ sub(/\.$/, "", $1); print $1}')
22711         [ $dirperms == "drwxrwsrwt" ] ||
22712                 error "incorrect perms on $dir/testdir"
22713
22714         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
22715                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
22716         ls -n $dir/testdir/testfile
22717         local fileperms=$(ls -n $dir/testdir/testfile |
22718                           awk '{ sub(/\.$/, "", $1); print $1}')
22719         [ $fileperms == "-rwxr-xr-x" ] ||
22720                 error "incorrect perms on $dir/testdir/testfile"
22721
22722         umask $SAVE_UMASK
22723 }
22724 run_test 420 "clear SGID bit on non-directories for non-members"
22725
22726 test_421a() {
22727         local cnt
22728         local fid1
22729         local fid2
22730
22731         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
22732                 skip "Need MDS version at least 2.12.54"
22733
22734         test_mkdir $DIR/$tdir
22735         createmany -o $DIR/$tdir/f 3
22736         cnt=$(ls -1 $DIR/$tdir | wc -l)
22737         [ $cnt != 3 ] && error "unexpected #files: $cnt"
22738
22739         fid1=$(lfs path2fid $DIR/$tdir/f1)
22740         fid2=$(lfs path2fid $DIR/$tdir/f2)
22741         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
22742
22743         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
22744         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
22745
22746         cnt=$(ls -1 $DIR/$tdir | wc -l)
22747         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
22748
22749         rm -f $DIR/$tdir/f3 || error "can't remove f3"
22750         createmany -o $DIR/$tdir/f 3
22751         cnt=$(ls -1 $DIR/$tdir | wc -l)
22752         [ $cnt != 3 ] && error "unexpected #files: $cnt"
22753
22754         fid1=$(lfs path2fid $DIR/$tdir/f1)
22755         fid2=$(lfs path2fid $DIR/$tdir/f2)
22756         echo "remove using fsname $FSNAME"
22757         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
22758
22759         cnt=$(ls -1 $DIR/$tdir | wc -l)
22760         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
22761 }
22762 run_test 421a "simple rm by fid"
22763
22764 test_421b() {
22765         local cnt
22766         local FID1
22767         local FID2
22768
22769         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
22770                 skip "Need MDS version at least 2.12.54"
22771
22772         test_mkdir $DIR/$tdir
22773         createmany -o $DIR/$tdir/f 3
22774         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
22775         MULTIPID=$!
22776
22777         FID1=$(lfs path2fid $DIR/$tdir/f1)
22778         FID2=$(lfs path2fid $DIR/$tdir/f2)
22779         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
22780
22781         kill -USR1 $MULTIPID
22782         wait
22783
22784         cnt=$(ls $DIR/$tdir | wc -l)
22785         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
22786 }
22787 run_test 421b "rm by fid on open file"
22788
22789 test_421c() {
22790         local cnt
22791         local FIDS
22792
22793         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
22794                 skip "Need MDS version at least 2.12.54"
22795
22796         test_mkdir $DIR/$tdir
22797         createmany -o $DIR/$tdir/f 3
22798         touch $DIR/$tdir/$tfile
22799         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
22800         cnt=$(ls -1 $DIR/$tdir | wc -l)
22801         [ $cnt != 184 ] && error "unexpected #files: $cnt"
22802
22803         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
22804         $LFS rmfid $DIR $FID1 || error "rmfid failed"
22805
22806         cnt=$(ls $DIR/$tdir | wc -l)
22807         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
22808 }
22809 run_test 421c "rm by fid against hardlinked files"
22810
22811 test_421d() {
22812         local cnt
22813         local FIDS
22814
22815         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
22816                 skip "Need MDS version at least 2.12.54"
22817
22818         test_mkdir $DIR/$tdir
22819         createmany -o $DIR/$tdir/f 4097
22820         cnt=$(ls -1 $DIR/$tdir | wc -l)
22821         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
22822
22823         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
22824         $LFS rmfid $DIR $FIDS || error "rmfid failed"
22825
22826         cnt=$(ls $DIR/$tdir | wc -l)
22827         rm -rf $DIR/$tdir
22828         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
22829 }
22830 run_test 421d "rmfid en masse"
22831
22832 test_421e() {
22833         local cnt
22834         local FID
22835
22836         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22837         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
22838                 skip "Need MDS version at least 2.12.54"
22839
22840         mkdir -p $DIR/$tdir
22841         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
22842         createmany -o $DIR/$tdir/striped_dir/f 512
22843         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
22844         [ $cnt != 512 ] && error "unexpected #files: $cnt"
22845
22846         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
22847                 sed "s/[/][^:]*://g")
22848         $LFS rmfid $DIR $FIDS || error "rmfid failed"
22849
22850         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
22851         rm -rf $DIR/$tdir
22852         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
22853 }
22854 run_test 421e "rmfid in DNE"
22855
22856 test_421f() {
22857         local cnt
22858         local FID
22859
22860         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
22861                 skip "Need MDS version at least 2.12.54"
22862
22863         test_mkdir $DIR/$tdir
22864         touch $DIR/$tdir/f
22865         cnt=$(ls -1 $DIR/$tdir | wc -l)
22866         [ $cnt != 1 ] && error "unexpected #files: $cnt"
22867
22868         FID=$(lfs path2fid $DIR/$tdir/f)
22869         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
22870         # rmfid should fail
22871         cnt=$(ls -1 $DIR/$tdir | wc -l)
22872         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
22873
22874         chmod a+rw $DIR/$tdir
22875         ls -la $DIR/$tdir
22876         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
22877         # rmfid should fail
22878         cnt=$(ls -1 $DIR/$tdir | wc -l)
22879         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
22880
22881         rm -f $DIR/$tdir/f
22882         $RUNAS touch $DIR/$tdir/f
22883         FID=$(lfs path2fid $DIR/$tdir/f)
22884         echo "rmfid as root"
22885         $LFS rmfid $DIR $FID || error "rmfid as root failed"
22886         cnt=$(ls -1 $DIR/$tdir | wc -l)
22887         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
22888
22889         rm -f $DIR/$tdir/f
22890         $RUNAS touch $DIR/$tdir/f
22891         cnt=$(ls -1 $DIR/$tdir | wc -l)
22892         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
22893         FID=$(lfs path2fid $DIR/$tdir/f)
22894         # rmfid w/o user_fid2path mount option should fail
22895         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
22896         cnt=$(ls -1 $DIR/$tdir | wc -l)
22897         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
22898
22899         umount_client $MOUNT || error "failed to umount client"
22900         mount_client $MOUNT "$MOUNT_OPTS,user_fid2path" ||
22901                 error "failed to mount client'"
22902
22903         $RUNAS $LFS rmfid $DIR $FID || error "rmfid failed"
22904         # rmfid should succeed
22905         cnt=$(ls -1 $DIR/$tdir | wc -l)
22906         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
22907
22908         # rmfid shouldn't allow to remove files due to dir's permission
22909         chmod a+rwx $DIR/$tdir
22910         touch $DIR/$tdir/f
22911         ls -la $DIR/$tdir
22912         FID=$(lfs path2fid $DIR/$tdir/f)
22913         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail"
22914
22915         umount_client $MOUNT || error "failed to umount client"
22916         mount_client $MOUNT "$MOUNT_OPTS" ||
22917                 error "failed to mount client'"
22918
22919 }
22920 run_test 421f "rmfid checks permissions"
22921
22922 test_421g() {
22923         local cnt
22924         local FIDS
22925
22926         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22927         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
22928                 skip "Need MDS version at least 2.12.54"
22929
22930         mkdir -p $DIR/$tdir
22931         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
22932         createmany -o $DIR/$tdir/striped_dir/f 512
22933         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
22934         [ $cnt != 512 ] && error "unexpected #files: $cnt"
22935
22936         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
22937                 sed "s/[/][^:]*://g")
22938
22939         rm -f $DIR/$tdir/striped_dir/f1*
22940         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
22941         removed=$((512 - cnt))
22942
22943         # few files have been just removed, so we expect
22944         # rmfid to fail on their fids
22945         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
22946         [ $removed != $errors ] && error "$errors != $removed"
22947
22948         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
22949         rm -rf $DIR/$tdir
22950         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
22951 }
22952 run_test 421g "rmfid to return errors properly"
22953
22954 test_422() {
22955         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
22956         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
22957         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
22958         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
22959         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
22960
22961         local amc=$(at_max_get client)
22962         local amo=$(at_max_get mds1)
22963         local timeout=`lctl get_param -n timeout`
22964
22965         at_max_set 0 client
22966         at_max_set 0 mds1
22967
22968 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
22969         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
22970                         fail_val=$(((2*timeout + 10)*1000))
22971         touch $DIR/$tdir/d3/file &
22972         sleep 2
22973 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
22974         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
22975                         fail_val=$((2*timeout + 5))
22976         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
22977         local pid=$!
22978         sleep 1
22979         kill -9 $pid
22980         sleep $((2 * timeout))
22981         echo kill $pid
22982         kill -9 $pid
22983         lctl mark touch
22984         touch $DIR/$tdir/d2/file3
22985         touch $DIR/$tdir/d2/file4
22986         touch $DIR/$tdir/d2/file5
22987
22988         wait
22989         at_max_set $amc client
22990         at_max_set $amo mds1
22991
22992         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
22993         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
22994                 error "Watchdog is always throttled"
22995 }
22996 run_test 422 "kill a process with RPC in progress"
22997
22998 stat_test() {
22999     df -h $MOUNT &
23000     df -h $MOUNT &
23001     df -h $MOUNT &
23002     df -h $MOUNT &
23003     df -h $MOUNT &
23004     df -h $MOUNT &
23005 }
23006
23007 test_423() {
23008     local _stats
23009     # ensure statfs cache is expired
23010     sleep 2;
23011
23012     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
23013     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
23014
23015     return 0
23016 }
23017 run_test 423 "statfs should return a right data"
23018
23019 test_424() {
23020 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
23021         $LCTL set_param fail_loc=0x80000522
23022         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
23023         rm -f $DIR/$tfile
23024 }
23025 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
23026
23027 prep_801() {
23028         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
23029         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
23030                 skip "Need server version at least 2.9.55"
23031
23032         start_full_debug_logging
23033 }
23034
23035 post_801() {
23036         stop_full_debug_logging
23037 }
23038
23039 barrier_stat() {
23040         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
23041                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
23042                            awk '/The barrier for/ { print $7 }')
23043                 echo $st
23044         else
23045                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
23046                 echo \'$st\'
23047         fi
23048 }
23049
23050 barrier_expired() {
23051         local expired
23052
23053         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
23054                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
23055                           awk '/will be expired/ { print $7 }')
23056         else
23057                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
23058         fi
23059
23060         echo $expired
23061 }
23062
23063 test_801a() {
23064         prep_801
23065
23066         echo "Start barrier_freeze at: $(date)"
23067         #define OBD_FAIL_BARRIER_DELAY          0x2202
23068         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
23069         # Do not reduce barrier time - See LU-11873
23070         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
23071
23072         sleep 2
23073         local b_status=$(barrier_stat)
23074         echo "Got barrier status at: $(date)"
23075         [ "$b_status" = "'freezing_p1'" ] ||
23076                 error "(1) unexpected barrier status $b_status"
23077
23078         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
23079         wait
23080         b_status=$(barrier_stat)
23081         [ "$b_status" = "'frozen'" ] ||
23082                 error "(2) unexpected barrier status $b_status"
23083
23084         local expired=$(barrier_expired)
23085         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
23086         sleep $((expired + 3))
23087
23088         b_status=$(barrier_stat)
23089         [ "$b_status" = "'expired'" ] ||
23090                 error "(3) unexpected barrier status $b_status"
23091
23092         # Do not reduce barrier time - See LU-11873
23093         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
23094                 error "(4) fail to freeze barrier"
23095
23096         b_status=$(barrier_stat)
23097         [ "$b_status" = "'frozen'" ] ||
23098                 error "(5) unexpected barrier status $b_status"
23099
23100         echo "Start barrier_thaw at: $(date)"
23101         #define OBD_FAIL_BARRIER_DELAY          0x2202
23102         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
23103         do_facet mgs $LCTL barrier_thaw $FSNAME &
23104
23105         sleep 2
23106         b_status=$(barrier_stat)
23107         echo "Got barrier status at: $(date)"
23108         [ "$b_status" = "'thawing'" ] ||
23109                 error "(6) unexpected barrier status $b_status"
23110
23111         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
23112         wait
23113         b_status=$(barrier_stat)
23114         [ "$b_status" = "'thawed'" ] ||
23115                 error "(7) unexpected barrier status $b_status"
23116
23117         #define OBD_FAIL_BARRIER_FAILURE        0x2203
23118         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
23119         do_facet mgs $LCTL barrier_freeze $FSNAME
23120
23121         b_status=$(barrier_stat)
23122         [ "$b_status" = "'failed'" ] ||
23123                 error "(8) unexpected barrier status $b_status"
23124
23125         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
23126         do_facet mgs $LCTL barrier_thaw $FSNAME
23127
23128         post_801
23129 }
23130 run_test 801a "write barrier user interfaces and stat machine"
23131
23132 test_801b() {
23133         prep_801
23134
23135         mkdir $DIR/$tdir || error "(1) fail to mkdir"
23136         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
23137         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
23138         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
23139         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
23140
23141         cancel_lru_locks mdc
23142
23143         # 180 seconds should be long enough
23144         do_facet mgs $LCTL barrier_freeze $FSNAME 180
23145
23146         local b_status=$(barrier_stat)
23147         [ "$b_status" = "'frozen'" ] ||
23148                 error "(6) unexpected barrier status $b_status"
23149
23150         mkdir $DIR/$tdir/d0/d10 &
23151         mkdir_pid=$!
23152
23153         touch $DIR/$tdir/d1/f13 &
23154         touch_pid=$!
23155
23156         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
23157         ln_pid=$!
23158
23159         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
23160         mv_pid=$!
23161
23162         rm -f $DIR/$tdir/d4/f12 &
23163         rm_pid=$!
23164
23165         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
23166
23167         # To guarantee taht the 'stat' is not blocked
23168         b_status=$(barrier_stat)
23169         [ "$b_status" = "'frozen'" ] ||
23170                 error "(8) unexpected barrier status $b_status"
23171
23172         # let above commands to run at background
23173         sleep 5
23174
23175         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
23176         ps -p $touch_pid || error "(10) touch should be blocked"
23177         ps -p $ln_pid || error "(11) link should be blocked"
23178         ps -p $mv_pid || error "(12) rename should be blocked"
23179         ps -p $rm_pid || error "(13) unlink should be blocked"
23180
23181         b_status=$(barrier_stat)
23182         [ "$b_status" = "'frozen'" ] ||
23183                 error "(14) unexpected barrier status $b_status"
23184
23185         do_facet mgs $LCTL barrier_thaw $FSNAME
23186         b_status=$(barrier_stat)
23187         [ "$b_status" = "'thawed'" ] ||
23188                 error "(15) unexpected barrier status $b_status"
23189
23190         wait $mkdir_pid || error "(16) mkdir should succeed"
23191         wait $touch_pid || error "(17) touch should succeed"
23192         wait $ln_pid || error "(18) link should succeed"
23193         wait $mv_pid || error "(19) rename should succeed"
23194         wait $rm_pid || error "(20) unlink should succeed"
23195
23196         post_801
23197 }
23198 run_test 801b "modification will be blocked by write barrier"
23199
23200 test_801c() {
23201         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
23202
23203         prep_801
23204
23205         stop mds2 || error "(1) Fail to stop mds2"
23206
23207         do_facet mgs $LCTL barrier_freeze $FSNAME 30
23208
23209         local b_status=$(barrier_stat)
23210         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
23211                 do_facet mgs $LCTL barrier_thaw $FSNAME
23212                 error "(2) unexpected barrier status $b_status"
23213         }
23214
23215         do_facet mgs $LCTL barrier_rescan $FSNAME ||
23216                 error "(3) Fail to rescan barrier bitmap"
23217
23218         # Do not reduce barrier time - See LU-11873
23219         do_facet mgs $LCTL barrier_freeze $FSNAME 20
23220
23221         b_status=$(barrier_stat)
23222         [ "$b_status" = "'frozen'" ] ||
23223                 error "(4) unexpected barrier status $b_status"
23224
23225         do_facet mgs $LCTL barrier_thaw $FSNAME
23226         b_status=$(barrier_stat)
23227         [ "$b_status" = "'thawed'" ] ||
23228                 error "(5) unexpected barrier status $b_status"
23229
23230         local devname=$(mdsdevname 2)
23231
23232         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
23233
23234         do_facet mgs $LCTL barrier_rescan $FSNAME ||
23235                 error "(7) Fail to rescan barrier bitmap"
23236
23237         post_801
23238 }
23239 run_test 801c "rescan barrier bitmap"
23240
23241 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
23242 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
23243 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
23244 saved_MOUNT_OPTS=$MOUNT_OPTS
23245
23246 cleanup_802a() {
23247         trap 0
23248
23249         stopall
23250         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
23251         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
23252         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
23253         MOUNT_OPTS=$saved_MOUNT_OPTS
23254         setupall
23255 }
23256
23257 test_802a() {
23258         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
23259         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
23260         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
23261                 skip "Need server version at least 2.9.55"
23262
23263         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
23264
23265         mkdir $DIR/$tdir || error "(1) fail to mkdir"
23266
23267         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
23268                 error "(2) Fail to copy"
23269
23270         trap cleanup_802a EXIT
23271
23272         # sync by force before remount as readonly
23273         sync; sync_all_data; sleep 3; sync_all_data
23274
23275         stopall
23276
23277         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
23278         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
23279         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
23280
23281         echo "Mount the server as read only"
23282         setupall server_only || error "(3) Fail to start servers"
23283
23284         echo "Mount client without ro should fail"
23285         mount_client $MOUNT &&
23286                 error "(4) Mount client without 'ro' should fail"
23287
23288         echo "Mount client with ro should succeed"
23289         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
23290         mount_client $MOUNT ||
23291                 error "(5) Mount client with 'ro' should succeed"
23292
23293         echo "Modify should be refused"
23294         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
23295
23296         echo "Read should be allowed"
23297         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
23298                 error "(7) Read should succeed under ro mode"
23299
23300         cleanup_802a
23301 }
23302 run_test 802a "simulate readonly device"
23303
23304 test_802b() {
23305         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23306         remote_mds_nodsh && skip "remote MDS with nodsh"
23307
23308         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
23309                 skip "readonly option not available"
23310
23311         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
23312
23313         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
23314                 error "(2) Fail to copy"
23315
23316         # write back all cached data before setting MDT to readonly
23317         cancel_lru_locks
23318         sync_all_data
23319
23320         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
23321         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
23322
23323         echo "Modify should be refused"
23324         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
23325
23326         echo "Read should be allowed"
23327         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
23328                 error "(7) Read should succeed under ro mode"
23329
23330         # disable readonly
23331         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
23332 }
23333 run_test 802b "be able to set MDTs to readonly"
23334
23335 test_803() {
23336         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
23337         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
23338                 skip "MDS needs to be newer than 2.10.54"
23339
23340         mkdir -p $DIR/$tdir
23341         # Create some objects on all MDTs to trigger related logs objects
23342         for idx in $(seq $MDSCOUNT); do
23343                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
23344                         $DIR/$tdir/dir${idx} ||
23345                         error "Fail to create $DIR/$tdir/dir${idx}"
23346         done
23347
23348         sync; sleep 3
23349         wait_delete_completed # ensure old test cleanups are finished
23350         echo "before create:"
23351         $LFS df -i $MOUNT
23352         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
23353
23354         for i in {1..10}; do
23355                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
23356                         error "Fail to create $DIR/$tdir/foo$i"
23357         done
23358
23359         sync; sleep 3
23360         echo "after create:"
23361         $LFS df -i $MOUNT
23362         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
23363
23364         # allow for an llog to be cleaned up during the test
23365         [ $after_used -ge $((before_used + 10 - 1)) ] ||
23366                 error "before ($before_used) + 10 > after ($after_used)"
23367
23368         for i in {1..10}; do
23369                 rm -rf $DIR/$tdir/foo$i ||
23370                         error "Fail to remove $DIR/$tdir/foo$i"
23371         done
23372
23373         sleep 3 # avoid MDT return cached statfs
23374         wait_delete_completed
23375         echo "after unlink:"
23376         $LFS df -i $MOUNT
23377         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
23378
23379         # allow for an llog to be created during the test
23380         [ $after_used -le $((before_used + 1)) ] ||
23381                 error "after ($after_used) > before ($before_used) + 1"
23382 }
23383 run_test 803 "verify agent object for remote object"
23384
23385 test_804() {
23386         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
23387         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
23388                 skip "MDS needs to be newer than 2.10.54"
23389         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
23390
23391         mkdir -p $DIR/$tdir
23392         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
23393                 error "Fail to create $DIR/$tdir/dir0"
23394
23395         local fid=$($LFS path2fid $DIR/$tdir/dir0)
23396         local dev=$(mdsdevname 2)
23397
23398         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23399                 grep ${fid} || error "NOT found agent entry for dir0"
23400
23401         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
23402                 error "Fail to create $DIR/$tdir/dir1"
23403
23404         touch $DIR/$tdir/dir1/foo0 ||
23405                 error "Fail to create $DIR/$tdir/dir1/foo0"
23406         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
23407         local rc=0
23408
23409         for idx in $(seq $MDSCOUNT); do
23410                 dev=$(mdsdevname $idx)
23411                 do_facet mds${idx} \
23412                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23413                         grep ${fid} && rc=$idx
23414         done
23415
23416         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
23417                 error "Fail to rename foo0 to foo1"
23418         if [ $rc -eq 0 ]; then
23419                 for idx in $(seq $MDSCOUNT); do
23420                         dev=$(mdsdevname $idx)
23421                         do_facet mds${idx} \
23422                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23423                         grep ${fid} && rc=$idx
23424                 done
23425         fi
23426
23427         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
23428                 error "Fail to rename foo1 to foo2"
23429         if [ $rc -eq 0 ]; then
23430                 for idx in $(seq $MDSCOUNT); do
23431                         dev=$(mdsdevname $idx)
23432                         do_facet mds${idx} \
23433                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23434                         grep ${fid} && rc=$idx
23435                 done
23436         fi
23437
23438         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
23439
23440         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
23441                 error "Fail to link to $DIR/$tdir/dir1/foo2"
23442         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
23443                 error "Fail to rename foo2 to foo0"
23444         unlink $DIR/$tdir/dir1/foo0 ||
23445                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
23446         rm -rf $DIR/$tdir/dir0 ||
23447                 error "Fail to rm $DIR/$tdir/dir0"
23448
23449         for idx in $(seq $MDSCOUNT); do
23450                 dev=$(mdsdevname $idx)
23451                 rc=0
23452
23453                 stop mds${idx}
23454                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
23455                         rc=$?
23456                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
23457                         error "mount mds$idx failed"
23458                 df $MOUNT > /dev/null 2>&1
23459
23460                 # e2fsck should not return error
23461                 [ $rc -eq 0 ] ||
23462                         error "e2fsck detected error on MDT${idx}: rc=$rc"
23463         done
23464 }
23465 run_test 804 "verify agent entry for remote entry"
23466
23467 cleanup_805() {
23468         do_facet $SINGLEMDS zfs set quota=$old $fsset
23469         unlinkmany $DIR/$tdir/f- 1000000
23470         trap 0
23471 }
23472
23473 test_805() {
23474         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
23475         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
23476         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
23477                 skip "netfree not implemented before 0.7"
23478         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
23479                 skip "Need MDS version at least 2.10.57"
23480
23481         local fsset
23482         local freekb
23483         local usedkb
23484         local old
23485         local quota
23486         local pref="osd-zfs.$FSNAME-MDT0000."
23487
23488         # limit available space on MDS dataset to meet nospace issue
23489         # quickly. then ZFS 0.7.2 can use reserved space if asked
23490         # properly (using netfree flag in osd_declare_destroy()
23491         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
23492         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
23493                 gawk '{print $3}')
23494         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
23495         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
23496         let "usedkb=usedkb-freekb"
23497         let "freekb=freekb/2"
23498         if let "freekb > 5000"; then
23499                 let "freekb=5000"
23500         fi
23501         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
23502         trap cleanup_805 EXIT
23503         mkdir $DIR/$tdir
23504         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
23505                 error "Can't set PFL layout"
23506         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
23507         rm -rf $DIR/$tdir || error "not able to remove"
23508         do_facet $SINGLEMDS zfs set quota=$old $fsset
23509         trap 0
23510 }
23511 run_test 805 "ZFS can remove from full fs"
23512
23513 # Size-on-MDS test
23514 check_lsom_data()
23515 {
23516         local file=$1
23517         local size=$($LFS getsom -s $file)
23518         local expect=$(stat -c %s $file)
23519
23520         [[ $size == $expect ]] ||
23521                 error "$file expected size: $expect, got: $size"
23522
23523         local blocks=$($LFS getsom -b $file)
23524         expect=$(stat -c %b $file)
23525         [[ $blocks == $expect ]] ||
23526                 error "$file expected blocks: $expect, got: $blocks"
23527 }
23528
23529 check_lsom_size()
23530 {
23531         local size=$($LFS getsom -s $1)
23532         local expect=$2
23533
23534         [[ $size == $expect ]] ||
23535                 error "$file expected size: $expect, got: $size"
23536 }
23537
23538 test_806() {
23539         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
23540                 skip "Need MDS version at least 2.11.52"
23541
23542         local bs=1048576
23543
23544         touch $DIR/$tfile || error "touch $tfile failed"
23545
23546         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23547         save_lustre_params client "llite.*.xattr_cache" > $save
23548         lctl set_param llite.*.xattr_cache=0
23549         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23550
23551         # single-threaded write
23552         echo "Test SOM for single-threaded write"
23553         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
23554                 error "write $tfile failed"
23555         check_lsom_size $DIR/$tfile $bs
23556
23557         local num=32
23558         local size=$(($num * $bs))
23559         local offset=0
23560         local i
23561
23562         echo "Test SOM for single client multi-threaded($num) write"
23563         $TRUNCATE $DIR/$tfile 0
23564         for ((i = 0; i < $num; i++)); do
23565                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
23566                 local pids[$i]=$!
23567                 offset=$((offset + $bs))
23568         done
23569         for (( i=0; i < $num; i++ )); do
23570                 wait ${pids[$i]}
23571         done
23572         check_lsom_size $DIR/$tfile $size
23573
23574         $TRUNCATE $DIR/$tfile 0
23575         for ((i = 0; i < $num; i++)); do
23576                 offset=$((offset - $bs))
23577                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
23578                 local pids[$i]=$!
23579         done
23580         for (( i=0; i < $num; i++ )); do
23581                 wait ${pids[$i]}
23582         done
23583         check_lsom_size $DIR/$tfile $size
23584
23585         # multi-client writes
23586         num=$(get_node_count ${CLIENTS//,/ })
23587         size=$(($num * $bs))
23588         offset=0
23589         i=0
23590
23591         echo "Test SOM for multi-client ($num) writes"
23592         $TRUNCATE $DIR/$tfile 0
23593         for client in ${CLIENTS//,/ }; do
23594                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
23595                 local pids[$i]=$!
23596                 i=$((i + 1))
23597                 offset=$((offset + $bs))
23598         done
23599         for (( i=0; i < $num; i++ )); do
23600                 wait ${pids[$i]}
23601         done
23602         check_lsom_size $DIR/$tfile $offset
23603
23604         i=0
23605         $TRUNCATE $DIR/$tfile 0
23606         for client in ${CLIENTS//,/ }; do
23607                 offset=$((offset - $bs))
23608                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
23609                 local pids[$i]=$!
23610                 i=$((i + 1))
23611         done
23612         for (( i=0; i < $num; i++ )); do
23613                 wait ${pids[$i]}
23614         done
23615         check_lsom_size $DIR/$tfile $size
23616
23617         # verify truncate
23618         echo "Test SOM for truncate"
23619         $TRUNCATE $DIR/$tfile 1048576
23620         check_lsom_size $DIR/$tfile 1048576
23621         $TRUNCATE $DIR/$tfile 1234
23622         check_lsom_size $DIR/$tfile 1234
23623
23624         # verify SOM blocks count
23625         echo "Verify SOM block count"
23626         $TRUNCATE $DIR/$tfile 0
23627         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
23628                 error "failed to write file $tfile"
23629         check_lsom_data $DIR/$tfile
23630 }
23631 run_test 806 "Verify Lazy Size on MDS"
23632
23633 test_807() {
23634         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
23635         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
23636                 skip "Need MDS version at least 2.11.52"
23637
23638         # Registration step
23639         changelog_register || error "changelog_register failed"
23640         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
23641         changelog_users $SINGLEMDS | grep -q $cl_user ||
23642                 error "User $cl_user not found in changelog_users"
23643
23644         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23645         save_lustre_params client "llite.*.xattr_cache" > $save
23646         lctl set_param llite.*.xattr_cache=0
23647         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23648
23649         rm -rf $DIR/$tdir || error "rm $tdir failed"
23650         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
23651         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
23652         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
23653         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
23654                 error "truncate $tdir/trunc failed"
23655
23656         local bs=1048576
23657         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
23658                 error "write $tfile failed"
23659
23660         # multi-client wirtes
23661         local num=$(get_node_count ${CLIENTS//,/ })
23662         local offset=0
23663         local i=0
23664
23665         echo "Test SOM for multi-client ($num) writes"
23666         touch $DIR/$tfile || error "touch $tfile failed"
23667         $TRUNCATE $DIR/$tfile 0
23668         for client in ${CLIENTS//,/ }; do
23669                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
23670                 local pids[$i]=$!
23671                 i=$((i + 1))
23672                 offset=$((offset + $bs))
23673         done
23674         for (( i=0; i < $num; i++ )); do
23675                 wait ${pids[$i]}
23676         done
23677
23678         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
23679         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
23680         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
23681         check_lsom_data $DIR/$tdir/trunc
23682         check_lsom_data $DIR/$tdir/single_dd
23683         check_lsom_data $DIR/$tfile
23684
23685         rm -rf $DIR/$tdir
23686         # Deregistration step
23687         changelog_deregister || error "changelog_deregister failed"
23688 }
23689 run_test 807 "verify LSOM syncing tool"
23690
23691 check_som_nologged()
23692 {
23693         local lines=$($LFS changelog $FSNAME-MDT0000 |
23694                 grep 'x=trusted.som' | wc -l)
23695         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
23696 }
23697
23698 test_808() {
23699         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
23700                 skip "Need MDS version at least 2.11.55"
23701
23702         # Registration step
23703         changelog_register || error "changelog_register failed"
23704
23705         touch $DIR/$tfile || error "touch $tfile failed"
23706         check_som_nologged
23707
23708         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
23709                 error "write $tfile failed"
23710         check_som_nologged
23711
23712         $TRUNCATE $DIR/$tfile 1234
23713         check_som_nologged
23714
23715         $TRUNCATE $DIR/$tfile 1048576
23716         check_som_nologged
23717
23718         # Deregistration step
23719         changelog_deregister || error "changelog_deregister failed"
23720 }
23721 run_test 808 "Check trusted.som xattr not logged in Changelogs"
23722
23723 check_som_nodata()
23724 {
23725         $LFS getsom $1
23726         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
23727 }
23728
23729 test_809() {
23730         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
23731                 skip "Need MDS version at least 2.11.56"
23732
23733         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
23734                 error "failed to create DoM-only file $DIR/$tfile"
23735         touch $DIR/$tfile || error "touch $tfile failed"
23736         check_som_nodata $DIR/$tfile
23737
23738         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
23739                 error "write $tfile failed"
23740         check_som_nodata $DIR/$tfile
23741
23742         $TRUNCATE $DIR/$tfile 1234
23743         check_som_nodata $DIR/$tfile
23744
23745         $TRUNCATE $DIR/$tfile 4097
23746         check_som_nodata $DIR/$file
23747 }
23748 run_test 809 "Verify no SOM xattr store for DoM-only files"
23749
23750 test_810() {
23751         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23752         $GSS && skip_env "could not run with gss"
23753         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
23754                 skip "OST < 2.12.58 doesn't align checksum"
23755
23756         set_checksums 1
23757         stack_trap "set_checksums $ORIG_CSUM" EXIT
23758         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
23759
23760         local csum
23761         local before
23762         local after
23763         for csum in $CKSUM_TYPES; do
23764                 #define OBD_FAIL_OSC_NO_GRANT   0x411
23765                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
23766                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
23767                         eval set -- $i
23768                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
23769                         before=$(md5sum $DIR/$tfile)
23770                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
23771                         after=$(md5sum $DIR/$tfile)
23772                         [ "$before" == "$after" ] ||
23773                                 error "$csum: $before != $after bs=$1 seek=$2"
23774                 done
23775         done
23776 }
23777 run_test 810 "partial page writes on ZFS (LU-11663)"
23778
23779 test_812a() {
23780         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
23781                 skip "OST < 2.12.51 doesn't support this fail_loc"
23782         [ "$SHARED_KEY" = true ] &&
23783                 skip "OSC connections never go IDLE with Shared-Keys enabled"
23784
23785         $LFS setstripe -c 1 -i 0 $DIR/$tfile
23786         # ensure ost1 is connected
23787         stat $DIR/$tfile >/dev/null || error "can't stat"
23788         wait_osc_import_state client ost1 FULL
23789         # no locks, no reqs to let the connection idle
23790         cancel_lru_locks osc
23791
23792         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
23793 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
23794         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
23795         wait_osc_import_state client ost1 CONNECTING
23796         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
23797
23798         stat $DIR/$tfile >/dev/null || error "can't stat file"
23799 }
23800 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
23801
23802 test_812b() { # LU-12378
23803         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
23804                 skip "OST < 2.12.51 doesn't support this fail_loc"
23805         [ "$SHARED_KEY" = true ] &&
23806                 skip "OSC connections never go IDLE with Shared-Keys enabled"
23807
23808         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
23809         # ensure ost1 is connected
23810         stat $DIR/$tfile >/dev/null || error "can't stat"
23811         wait_osc_import_state client ost1 FULL
23812         # no locks, no reqs to let the connection idle
23813         cancel_lru_locks osc
23814
23815         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
23816 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
23817         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
23818         wait_osc_import_state client ost1 CONNECTING
23819         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
23820
23821         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
23822         wait_osc_import_state client ost1 IDLE
23823 }
23824 run_test 812b "do not drop no resend request for idle connect"
23825
23826 test_813() {
23827         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
23828         [ -z "$file_heat_sav" ] && skip "no file heat support"
23829
23830         local readsample
23831         local writesample
23832         local readbyte
23833         local writebyte
23834         local readsample1
23835         local writesample1
23836         local readbyte1
23837         local writebyte1
23838
23839         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
23840         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
23841
23842         $LCTL set_param -n llite.*.file_heat=1
23843         echo "Turn on file heat"
23844         echo "Period second: $period_second, Decay percentage: $decay_pct"
23845
23846         echo "QQQQ" > $DIR/$tfile
23847         echo "QQQQ" > $DIR/$tfile
23848         echo "QQQQ" > $DIR/$tfile
23849         cat $DIR/$tfile > /dev/null
23850         cat $DIR/$tfile > /dev/null
23851         cat $DIR/$tfile > /dev/null
23852         cat $DIR/$tfile > /dev/null
23853
23854         local out=$($LFS heat_get $DIR/$tfile)
23855
23856         $LFS heat_get $DIR/$tfile
23857         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
23858         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
23859         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
23860         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
23861
23862         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
23863         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
23864         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
23865         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
23866
23867         sleep $((period_second + 3))
23868         echo "Sleep $((period_second + 3)) seconds..."
23869         # The recursion formula to calculate the heat of the file f is as
23870         # follow:
23871         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
23872         # Where Hi is the heat value in the period between time points i*I and
23873         # (i+1)*I; Ci is the access count in the period; the symbol P refers
23874         # to the weight of Ci.
23875         out=$($LFS heat_get $DIR/$tfile)
23876         $LFS heat_get $DIR/$tfile
23877         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
23878         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
23879         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
23880         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
23881
23882         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
23883                 error "read sample ($readsample) is wrong"
23884         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
23885                 error "write sample ($writesample) is wrong"
23886         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
23887                 error "read bytes ($readbyte) is wrong"
23888         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
23889                 error "write bytes ($writebyte) is wrong"
23890
23891         echo "QQQQ" > $DIR/$tfile
23892         echo "QQQQ" > $DIR/$tfile
23893         echo "QQQQ" > $DIR/$tfile
23894         cat $DIR/$tfile > /dev/null
23895         cat $DIR/$tfile > /dev/null
23896         cat $DIR/$tfile > /dev/null
23897         cat $DIR/$tfile > /dev/null
23898
23899         sleep $((period_second + 3))
23900         echo "Sleep $((period_second + 3)) seconds..."
23901
23902         out=$($LFS heat_get $DIR/$tfile)
23903         $LFS heat_get $DIR/$tfile
23904         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
23905         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
23906         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
23907         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
23908
23909         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
23910                 4 * $decay_pct) / 100") -eq 1 ] ||
23911                 error "read sample ($readsample1) is wrong"
23912         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
23913                 3 * $decay_pct) / 100") -eq 1 ] ||
23914                 error "write sample ($writesample1) is wrong"
23915         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
23916                 20 * $decay_pct) / 100") -eq 1 ] ||
23917                 error "read bytes ($readbyte1) is wrong"
23918         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
23919                 15 * $decay_pct) / 100") -eq 1 ] ||
23920                 error "write bytes ($writebyte1) is wrong"
23921
23922         echo "Turn off file heat for the file $DIR/$tfile"
23923         $LFS heat_set -o $DIR/$tfile
23924
23925         echo "QQQQ" > $DIR/$tfile
23926         echo "QQQQ" > $DIR/$tfile
23927         echo "QQQQ" > $DIR/$tfile
23928         cat $DIR/$tfile > /dev/null
23929         cat $DIR/$tfile > /dev/null
23930         cat $DIR/$tfile > /dev/null
23931         cat $DIR/$tfile > /dev/null
23932
23933         out=$($LFS heat_get $DIR/$tfile)
23934         $LFS heat_get $DIR/$tfile
23935         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
23936         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
23937         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
23938         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
23939
23940         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
23941         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
23942         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
23943         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
23944
23945         echo "Trun on file heat for the file $DIR/$tfile"
23946         $LFS heat_set -O $DIR/$tfile
23947
23948         echo "QQQQ" > $DIR/$tfile
23949         echo "QQQQ" > $DIR/$tfile
23950         echo "QQQQ" > $DIR/$tfile
23951         cat $DIR/$tfile > /dev/null
23952         cat $DIR/$tfile > /dev/null
23953         cat $DIR/$tfile > /dev/null
23954         cat $DIR/$tfile > /dev/null
23955
23956         out=$($LFS heat_get $DIR/$tfile)
23957         $LFS heat_get $DIR/$tfile
23958         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
23959         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
23960         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
23961         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
23962
23963         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
23964         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
23965         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
23966         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
23967
23968         $LFS heat_set -c $DIR/$tfile
23969         $LCTL set_param -n llite.*.file_heat=0
23970         echo "Turn off file heat support for the Lustre filesystem"
23971
23972         echo "QQQQ" > $DIR/$tfile
23973         echo "QQQQ" > $DIR/$tfile
23974         echo "QQQQ" > $DIR/$tfile
23975         cat $DIR/$tfile > /dev/null
23976         cat $DIR/$tfile > /dev/null
23977         cat $DIR/$tfile > /dev/null
23978         cat $DIR/$tfile > /dev/null
23979
23980         out=$($LFS heat_get $DIR/$tfile)
23981         $LFS heat_get $DIR/$tfile
23982         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
23983         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
23984         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
23985         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
23986
23987         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
23988         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
23989         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
23990         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
23991
23992         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
23993         rm -f $DIR/$tfile
23994 }
23995 run_test 813 "File heat verfication"
23996
23997 test_814()
23998 {
23999         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
24000         echo -n y >> $DIR/$tfile
24001         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
24002         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
24003 }
24004 run_test 814 "sparse cp works as expected (LU-12361)"
24005
24006 test_815()
24007 {
24008         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
24009         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
24010 }
24011 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
24012
24013 test_816() {
24014         [ "$SHARED_KEY" = true ] &&
24015                 skip "OSC connections never go IDLE with Shared-Keys enabled"
24016
24017         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24018         # ensure ost1 is connected
24019         stat $DIR/$tfile >/dev/null || error "can't stat"
24020         wait_osc_import_state client ost1 FULL
24021         # no locks, no reqs to let the connection idle
24022         cancel_lru_locks osc
24023         lru_resize_disable osc
24024         local before
24025         local now
24026         before=$($LCTL get_param -n \
24027                  ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
24028
24029         wait_osc_import_state client ost1 IDLE
24030         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
24031         now=$($LCTL get_param -n \
24032               ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
24033         [ $before == $now ] || error "lru_size changed $before != $now"
24034 }
24035 run_test 816 "do not reset lru_resize on idle reconnect"
24036
24037 cleanup_817() {
24038         umount $tmpdir
24039         exportfs -u localhost:$DIR/nfsexp
24040         rm -rf $DIR/nfsexp
24041 }
24042
24043 test_817() {
24044         systemctl restart nfs-server.service || skip "failed to restart nfsd"
24045
24046         mkdir -p $DIR/nfsexp
24047         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
24048                 error "failed to export nfs"
24049
24050         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
24051         stack_trap cleanup_817 EXIT
24052
24053         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
24054                 error "failed to mount nfs to $tmpdir"
24055
24056         cp /bin/true $tmpdir
24057         $DIR/nfsexp/true || error "failed to execute 'true' command"
24058 }
24059 run_test 817 "nfsd won't cache write lock for exec file"
24060
24061 test_818() {
24062         mkdir $DIR/$tdir
24063         $LFS setstripe -c1 -i0 $DIR/$tfile
24064         $LFS setstripe -c1 -i1 $DIR/$tfile
24065         stop $SINGLEMDS
24066         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
24067         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
24068         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
24069                 error "start $SINGLEMDS failed"
24070         rm -rf $DIR/$tdir
24071 }
24072 run_test 818 "unlink with failed llog"
24073
24074 test_819a() {
24075         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24076         cancel_lru_locks osc
24077         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
24078         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
24079         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
24080         rm -f $TDIR/$tfile
24081 }
24082 run_test 819a "too big niobuf in read"
24083
24084 test_819b() {
24085         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
24086         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
24087         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24088         cancel_lru_locks osc
24089         sleep 1
24090         rm -f $TDIR/$tfile
24091 }
24092 run_test 819b "too big niobuf in write"
24093
24094
24095 function test_820_start_ost() {
24096         sleep 5
24097
24098         for num in $(seq $OSTCOUNT); do
24099                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
24100         done
24101 }
24102
24103 test_820() {
24104         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24105
24106         mkdir $DIR/$tdir
24107         umount_client $MOUNT || error "umount failed"
24108         for num in $(seq $OSTCOUNT); do
24109                 stop ost$num
24110         done
24111
24112         # mount client with no active OSTs
24113         # so that the client can't initialize max LOV EA size
24114         # from OSC notifications
24115         mount_client $MOUNT || error "mount failed"
24116         # delay OST starting to keep this 0 max EA size for a while
24117         test_820_start_ost &
24118
24119         # create a directory on MDS2
24120         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
24121                 error "Failed to create directory"
24122         # open intent should update default EA size
24123         # see mdc_update_max_ea_from_body()
24124         # notice this is the very first RPC to MDS2
24125         cp /etc/services $DIR/$tdir/mds2 ||
24126                 error "Failed to copy files to mds$n"
24127 }
24128 run_test 820 "update max EA from open intent"
24129
24130 #
24131 # tests that do cleanup/setup should be run at the end
24132 #
24133
24134 test_900() {
24135         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24136         local ls
24137
24138         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
24139         $LCTL set_param fail_loc=0x903
24140
24141         cancel_lru_locks MGC
24142
24143         FAIL_ON_ERROR=true cleanup
24144         FAIL_ON_ERROR=true setup
24145 }
24146 run_test 900 "umount should not race with any mgc requeue thread"
24147
24148 # LUS-6253/LU-11185
24149 test_901() {
24150         local oldc
24151         local newc
24152         local olds
24153         local news
24154         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24155
24156         # some get_param have a bug to handle dot in param name
24157         cancel_lru_locks MGC
24158         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
24159         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
24160         umount_client $MOUNT || error "umount failed"
24161         mount_client $MOUNT || error "mount failed"
24162         cancel_lru_locks MGC
24163         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
24164         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
24165
24166         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
24167         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
24168
24169         return 0
24170 }
24171 run_test 901 "don't leak a mgc lock on client umount"
24172
24173 # LU-13377
24174 test_902() {
24175         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
24176                 skip "client does not have LU-13377 fix"
24177         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
24178         $LCTL set_param fail_loc=0x1415
24179         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24180         cancel_lru_locks osc
24181         rm -f $DIR/$tfile
24182 }
24183 run_test 902 "test short write doesn't hang lustre"
24184
24185 complete $SECONDS
24186 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
24187 check_and_cleanup_lustre
24188 if [ "$I_MOUNTED" != "yes" ]; then
24189         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
24190 fi
24191 exit_status