Whamcloud - gitweb
c44f73100ed4e9f9b3d46789105cf566f6c6c17f
[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
1785         local list=$(comma_list $(osts_nodes))
1786         [ "$OSTIDX" ] && list=$(facet_host ost$((OSTIDX + 1)))
1787
1788         do_nodes $list lctl set_param fail_loc=0
1789         sync    # initiate all OST_DESTROYs from MDS to OST
1790         sleep_maxage
1791 }
1792
1793 exhaust_precreations() {
1794         local OSTIDX=$1
1795         local FAILLOC=$2
1796         local FAILIDX=${3:-$OSTIDX}
1797         local ofacet=ost$((OSTIDX + 1))
1798
1799         test_mkdir -p -c1 $DIR/$tdir
1800         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
1801         local mfacet=mds$((mdtidx + 1))
1802         echo OSTIDX=$OSTIDX MDTIDX=$mdtidx
1803
1804         local OST=$(ostname_from_index $OSTIDX)
1805
1806         # on the mdt's osc
1807         local mdtosc_proc1=$(get_mdtosc_proc_path $mfacet $OST)
1808         local last_id=$(do_facet $mfacet lctl get_param -n \
1809                         osp.$mdtosc_proc1.prealloc_last_id)
1810         local next_id=$(do_facet $mfacet lctl get_param -n \
1811                         osp.$mdtosc_proc1.prealloc_next_id)
1812
1813         local mdtosc_proc2=$(get_mdtosc_proc_path $mfacet)
1814         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1815
1816         test_mkdir -p $DIR/$tdir/${OST}
1817         $LFS setstripe -i $OSTIDX -c 1 $DIR/$tdir/${OST}
1818 #define OBD_FAIL_OST_ENOSPC              0x215
1819         do_facet $ofacet lctl set_param fail_val=$FAILIDX fail_loc=0x215
1820         echo "Creating to objid $last_id on ost $OST..."
1821         createmany -o $DIR/$tdir/${OST}/f $next_id $((last_id - next_id + 2))
1822         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1823         do_facet $ofacet lctl set_param fail_loc=$FAILLOC
1824         sleep_maxage
1825 }
1826
1827 exhaust_all_precreations() {
1828         local i
1829         for (( i=0; i < OSTCOUNT; i++ )) ; do
1830                 exhaust_precreations $i $1 -1
1831         done
1832 }
1833
1834 test_27n() {
1835         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1836         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1837         remote_mds_nodsh && skip "remote MDS with nodsh"
1838         remote_ost_nodsh && skip "remote OST with nodsh"
1839
1840         reset_enospc
1841         rm -f $DIR/$tdir/$tfile
1842         exhaust_precreations 0 0x80000215
1843         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1844         touch $DIR/$tdir/$tfile || error "touch failed"
1845         $LFS getstripe $DIR/$tdir/$tfile
1846         reset_enospc
1847 }
1848 run_test 27n "create file with some full OSTs"
1849
1850 test_27o() {
1851         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1852         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1853         remote_mds_nodsh && skip "remote MDS with nodsh"
1854         remote_ost_nodsh && skip "remote OST with nodsh"
1855
1856         reset_enospc
1857         rm -f $DIR/$tdir/$tfile
1858         exhaust_all_precreations 0x215
1859
1860         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1861
1862         reset_enospc
1863         rm -rf $DIR/$tdir/*
1864 }
1865 run_test 27o "create file with all full OSTs (should error)"
1866
1867 test_27p() {
1868         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1869         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1870         remote_mds_nodsh && skip "remote MDS with nodsh"
1871         remote_ost_nodsh && skip "remote OST with nodsh"
1872
1873         reset_enospc
1874         rm -f $DIR/$tdir/$tfile
1875         test_mkdir $DIR/$tdir
1876
1877         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1878         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1879         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1880
1881         exhaust_precreations 0 0x80000215
1882         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1883         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1884         $LFS getstripe $DIR/$tdir/$tfile
1885
1886         reset_enospc
1887 }
1888 run_test 27p "append to a truncated file with some full OSTs"
1889
1890 test_27q() {
1891         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1892         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1893         remote_mds_nodsh && skip "remote MDS with nodsh"
1894         remote_ost_nodsh && skip "remote OST with nodsh"
1895
1896         reset_enospc
1897         rm -f $DIR/$tdir/$tfile
1898
1899         test_mkdir $DIR/$tdir
1900         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1901         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1902                 error "truncate $DIR/$tdir/$tfile failed"
1903         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1904
1905         exhaust_all_precreations 0x215
1906
1907         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1908         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1909
1910         reset_enospc
1911 }
1912 run_test 27q "append to truncated file with all OSTs full (should error)"
1913
1914 test_27r() {
1915         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1916         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1917         remote_mds_nodsh && skip "remote MDS with nodsh"
1918         remote_ost_nodsh && skip "remote OST with nodsh"
1919
1920         reset_enospc
1921         rm -f $DIR/$tdir/$tfile
1922         exhaust_precreations 0 0x80000215
1923
1924         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1925
1926         reset_enospc
1927 }
1928 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
1929
1930 test_27s() { # bug 10725
1931         test_mkdir $DIR/$tdir
1932         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
1933         local stripe_count=0
1934         [ $OSTCOUNT -eq 1 ] || stripe_count=2
1935         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
1936                 error "stripe width >= 2^32 succeeded" || true
1937
1938 }
1939 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
1940
1941 test_27t() { # bug 10864
1942         WDIR=$(pwd)
1943         WLFS=$(which lfs)
1944         cd $DIR
1945         touch $tfile
1946         $WLFS getstripe $tfile
1947         cd $WDIR
1948 }
1949 run_test 27t "check that utils parse path correctly"
1950
1951 test_27u() { # bug 4900
1952         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1953         remote_mds_nodsh && skip "remote MDS with nodsh"
1954
1955         local index
1956         local list=$(comma_list $(mdts_nodes))
1957
1958 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
1959         do_nodes $list $LCTL set_param fail_loc=0x139
1960         test_mkdir -p $DIR/$tdir
1961         trap simple_cleanup_common EXIT
1962         createmany -o $DIR/$tdir/t- 1000
1963         do_nodes $list $LCTL set_param fail_loc=0
1964
1965         TLOG=$TMP/$tfile.getstripe
1966         $LFS getstripe $DIR/$tdir > $TLOG
1967         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
1968         unlinkmany $DIR/$tdir/t- 1000
1969         trap 0
1970         [[ $OBJS -gt 0 ]] &&
1971                 error "$OBJS objects created on OST-0. See $TLOG" ||
1972                 rm -f $TLOG
1973 }
1974 run_test 27u "skip object creation on OSC w/o objects"
1975
1976 test_27v() { # bug 4900
1977         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1978         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1979         remote_mds_nodsh && skip "remote MDS with nodsh"
1980         remote_ost_nodsh && skip "remote OST with nodsh"
1981
1982         exhaust_all_precreations 0x215
1983         reset_enospc
1984
1985         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
1986
1987         touch $DIR/$tdir/$tfile
1988         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
1989         # all except ost1
1990         for (( i=1; i < OSTCOUNT; i++ )); do
1991                 do_facet ost$i lctl set_param fail_loc=0x705
1992         done
1993         local START=`date +%s`
1994         createmany -o $DIR/$tdir/$tfile 32
1995
1996         local FINISH=`date +%s`
1997         local TIMEOUT=`lctl get_param -n timeout`
1998         local PROCESS=$((FINISH - START))
1999         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2000                error "$FINISH - $START >= $TIMEOUT / 2"
2001         sleep $((TIMEOUT / 2 - PROCESS))
2002         reset_enospc
2003 }
2004 run_test 27v "skip object creation on slow OST"
2005
2006 test_27w() { # bug 10997
2007         test_mkdir $DIR/$tdir
2008         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2009         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2010                 error "stripe size $size != 65536" || true
2011         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2012                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2013 }
2014 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2015
2016 test_27wa() {
2017         [[ $OSTCOUNT -lt 2 ]] &&
2018                 skip_env "skipping multiple stripe count/offset test"
2019
2020         test_mkdir $DIR/$tdir
2021         for i in $(seq 1 $OSTCOUNT); do
2022                 offset=$((i - 1))
2023                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2024                         error "setstripe -c $i -i $offset failed"
2025                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2026                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2027                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2028                 [ $index -ne $offset ] &&
2029                         error "stripe offset $index != $offset" || true
2030         done
2031 }
2032 run_test 27wa "check $LFS setstripe -c -i options"
2033
2034 test_27x() {
2035         remote_ost_nodsh && skip "remote OST with nodsh"
2036         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2037         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2038
2039         OFFSET=$(($OSTCOUNT - 1))
2040         OSTIDX=0
2041         local OST=$(ostname_from_index $OSTIDX)
2042
2043         test_mkdir $DIR/$tdir
2044         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2045         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2046         sleep_maxage
2047         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2048         for i in $(seq 0 $OFFSET); do
2049                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2050                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2051                 error "OST0 was degraded but new created file still use it"
2052         done
2053         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2054 }
2055 run_test 27x "create files while OST0 is degraded"
2056
2057 test_27y() {
2058         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2059         remote_mds_nodsh && skip "remote MDS with nodsh"
2060         remote_ost_nodsh && skip "remote OST with nodsh"
2061         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2062
2063         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2064         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2065                 osp.$mdtosc.prealloc_last_id)
2066         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2067                 osp.$mdtosc.prealloc_next_id)
2068         local fcount=$((last_id - next_id))
2069         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2070         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2071
2072         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2073                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2074         local OST_DEACTIVE_IDX=-1
2075         local OSC
2076         local OSTIDX
2077         local OST
2078
2079         for OSC in $MDS_OSCS; do
2080                 OST=$(osc_to_ost $OSC)
2081                 OSTIDX=$(index_from_ostuuid $OST)
2082                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2083                         OST_DEACTIVE_IDX=$OSTIDX
2084                 fi
2085                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2086                         echo $OSC "is Deactivated:"
2087                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2088                 fi
2089         done
2090
2091         OSTIDX=$(index_from_ostuuid $OST)
2092         test_mkdir $DIR/$tdir
2093         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2094
2095         for OSC in $MDS_OSCS; do
2096                 OST=$(osc_to_ost $OSC)
2097                 OSTIDX=$(index_from_ostuuid $OST)
2098                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2099                         echo $OST "is degraded:"
2100                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2101                                                 obdfilter.$OST.degraded=1
2102                 fi
2103         done
2104
2105         sleep_maxage
2106         createmany -o $DIR/$tdir/$tfile $fcount
2107
2108         for OSC in $MDS_OSCS; do
2109                 OST=$(osc_to_ost $OSC)
2110                 OSTIDX=$(index_from_ostuuid $OST)
2111                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2112                         echo $OST "is recovered from degraded:"
2113                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2114                                                 obdfilter.$OST.degraded=0
2115                 else
2116                         do_facet $SINGLEMDS lctl --device %$OSC activate
2117                 fi
2118         done
2119
2120         # all osp devices get activated, hence -1 stripe count restored
2121         local stripe_count=0
2122
2123         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2124         # devices get activated.
2125         sleep_maxage
2126         $LFS setstripe -c -1 $DIR/$tfile
2127         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2128         rm -f $DIR/$tfile
2129         [ $stripe_count -ne $OSTCOUNT ] &&
2130                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2131         return 0
2132 }
2133 run_test 27y "create files while OST0 is degraded and the rest inactive"
2134
2135 check_seq_oid()
2136 {
2137         log "check file $1"
2138
2139         lmm_count=$($LFS getstripe -c $1)
2140         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2141         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2142
2143         local old_ifs="$IFS"
2144         IFS=$'[:]'
2145         fid=($($LFS path2fid $1))
2146         IFS="$old_ifs"
2147
2148         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2149         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2150
2151         # compare lmm_seq and lu_fid->f_seq
2152         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2153         # compare lmm_object_id and lu_fid->oid
2154         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2155
2156         # check the trusted.fid attribute of the OST objects of the file
2157         local have_obdidx=false
2158         local stripe_nr=0
2159         $LFS getstripe $1 | while read obdidx oid hex seq; do
2160                 # skip lines up to and including "obdidx"
2161                 [ -z "$obdidx" ] && break
2162                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2163                 $have_obdidx || continue
2164
2165                 local ost=$((obdidx + 1))
2166                 local dev=$(ostdevname $ost)
2167                 local oid_hex
2168
2169                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2170
2171                 seq=$(echo $seq | sed -e "s/^0x//g")
2172                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2173                         oid_hex=$(echo $oid)
2174                 else
2175                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2176                 fi
2177                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2178
2179                 local ff=""
2180                 #
2181                 # Don't unmount/remount the OSTs if we don't need to do that.
2182                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2183                 # update too, until that use mount/ll_decode_filter_fid/mount.
2184                 # Re-enable when debugfs will understand new filter_fid.
2185                 #
2186                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2187                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2188                                 $dev 2>/dev/null" | grep "parent=")
2189                 fi
2190                 if [ -z "$ff" ]; then
2191                         stop ost$ost
2192                         mount_fstype ost$ost
2193                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2194                                 $(facet_mntpt ost$ost)/$obj_file)
2195                         unmount_fstype ost$ost
2196                         start ost$ost $dev $OST_MOUNT_OPTS
2197                         clients_up
2198                 fi
2199
2200                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2201
2202                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2203
2204                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2205                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2206                 #
2207                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2208                 #       stripe_size=1048576 component_id=1 component_start=0 \
2209                 #       component_end=33554432
2210                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2211                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2212                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2213                 local ff_pstripe
2214                 if grep -q 'stripe=' <<<$ff; then
2215                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2216                 else
2217                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2218                         # into f_ver in this case.  See comment on ff_parent.
2219                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2220                 fi
2221
2222                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2223                 [ $ff_pseq = $lmm_seq ] ||
2224                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2225                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2226                 [ $ff_poid = $lmm_oid ] ||
2227                         error "FF parent OID $ff_poid != $lmm_oid"
2228                 (($ff_pstripe == $stripe_nr)) ||
2229                         error "FF stripe $ff_pstripe != $stripe_nr"
2230
2231                 stripe_nr=$((stripe_nr + 1))
2232                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2233                         continue
2234                 if grep -q 'stripe_count=' <<<$ff; then
2235                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2236                                             -e 's/ .*//' <<<$ff)
2237                         [ $lmm_count = $ff_scnt ] ||
2238                                 error "FF stripe count $lmm_count != $ff_scnt"
2239                 fi
2240         done
2241 }
2242
2243 test_27z() {
2244         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2245         remote_ost_nodsh && skip "remote OST with nodsh"
2246
2247         test_mkdir $DIR/$tdir
2248         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2249                 { error "setstripe -c -1 failed"; return 1; }
2250         # We need to send a write to every object to get parent FID info set.
2251         # This _should_ also work for setattr, but does not currently.
2252         # touch $DIR/$tdir/$tfile-1 ||
2253         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2254                 { error "dd $tfile-1 failed"; return 2; }
2255         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2256                 { error "setstripe -c -1 failed"; return 3; }
2257         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2258                 { error "dd $tfile-2 failed"; return 4; }
2259
2260         # make sure write RPCs have been sent to OSTs
2261         sync; sleep 5; sync
2262
2263         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2264         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2265 }
2266 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2267
2268 test_27A() { # b=19102
2269         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2270
2271         save_layout_restore_at_exit $MOUNT
2272         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2273         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2274                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2275         local default_size=$($LFS getstripe -S $MOUNT)
2276         local default_offset=$($LFS getstripe -i $MOUNT)
2277         local dsize=$(do_facet $SINGLEMDS \
2278                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2279         [ $default_size -eq $dsize ] ||
2280                 error "stripe size $default_size != $dsize"
2281         [ $default_offset -eq -1 ] ||
2282                 error "stripe offset $default_offset != -1"
2283 }
2284 run_test 27A "check filesystem-wide default LOV EA values"
2285
2286 test_27B() { # LU-2523
2287         test_mkdir $DIR/$tdir
2288         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2289         touch $DIR/$tdir/f0
2290         # open f1 with O_LOV_DELAY_CREATE
2291         # rename f0 onto f1
2292         # call setstripe ioctl on open file descriptor for f1
2293         # close
2294         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2295                 $DIR/$tdir/f0
2296
2297         rm -f $DIR/$tdir/f1
2298         # open f1 with O_LOV_DELAY_CREATE
2299         # unlink f1
2300         # call setstripe ioctl on open file descriptor for f1
2301         # close
2302         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2303
2304         # Allow multiop to fail in imitation of NFS's busted semantics.
2305         true
2306 }
2307 run_test 27B "call setstripe on open unlinked file/rename victim"
2308
2309 # 27C family tests full striping and overstriping
2310 test_27Ca() { #LU-2871
2311         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2312
2313         declare -a ost_idx
2314         local index
2315         local found
2316         local i
2317         local j
2318
2319         test_mkdir $DIR/$tdir
2320         cd $DIR/$tdir
2321         for i in $(seq 0 $((OSTCOUNT - 1))); do
2322                 # set stripe across all OSTs starting from OST$i
2323                 $LFS setstripe -i $i -c -1 $tfile$i
2324                 # get striping information
2325                 ost_idx=($($LFS getstripe $tfile$i |
2326                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2327                 echo ${ost_idx[@]}
2328
2329                 # check the layout
2330                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2331                         error "${#ost_idx[@]} != $OSTCOUNT"
2332
2333                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2334                         found=0
2335                         for j in $(echo ${ost_idx[@]}); do
2336                                 if [ $index -eq $j ]; then
2337                                         found=1
2338                                         break
2339                                 fi
2340                         done
2341                         [ $found = 1 ] ||
2342                                 error "Can not find $index in ${ost_idx[@]}"
2343                 done
2344         done
2345 }
2346 run_test 27Ca "check full striping across all OSTs"
2347
2348 test_27Cb() {
2349         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2350                 skip "server does not support overstriping"
2351         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2352                 skip_env "too many osts, skipping"
2353
2354         test_mkdir -p $DIR/$tdir
2355         local setcount=$(($OSTCOUNT * 2))
2356         [ $setcount -ge 160 ] || large_xattr_enabled ||
2357                 skip_env "ea_inode feature disabled"
2358
2359         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2360                 error "setstripe failed"
2361
2362         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2363         [ $count -eq $setcount ] ||
2364                 error "stripe count $count, should be $setcount"
2365
2366         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2367                 error "overstriped should be set in pattern"
2368
2369         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2370                 error "dd failed"
2371 }
2372 run_test 27Cb "more stripes than OSTs with -C"
2373
2374 test_27Cc() {
2375         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2376                 skip "server does not support overstriping"
2377         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2378
2379         test_mkdir -p $DIR/$tdir
2380         local setcount=$(($OSTCOUNT - 1))
2381
2382         [ $setcount -ge 160 ] || large_xattr_enabled ||
2383                 skip_env "ea_inode feature disabled"
2384
2385         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2386                 error "setstripe failed"
2387
2388         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2389         [ $count -eq $setcount ] ||
2390                 error "stripe count $count, should be $setcount"
2391
2392         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2393                 error "overstriped should not be set in pattern"
2394
2395         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2396                 error "dd failed"
2397 }
2398 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2399
2400 test_27Cd() {
2401         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2402                 skip "server does not support overstriping"
2403         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2404         large_xattr_enabled || skip_env "ea_inode feature disabled"
2405
2406         test_mkdir -p $DIR/$tdir
2407         local setcount=$LOV_MAX_STRIPE_COUNT
2408
2409         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2410                 error "setstripe failed"
2411
2412         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2413         [ $count -eq $setcount ] ||
2414                 error "stripe count $count, should be $setcount"
2415
2416         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2417                 error "overstriped should be set in pattern"
2418
2419         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2420                 error "dd failed"
2421
2422         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2423 }
2424 run_test 27Cd "test maximum stripe count"
2425
2426 test_27Ce() {
2427         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2428                 skip "server does not support overstriping"
2429         test_mkdir -p $DIR/$tdir
2430
2431         pool_add $TESTNAME || error "Pool creation failed"
2432         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2433
2434         local setcount=8
2435
2436         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2437                 error "setstripe failed"
2438
2439         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2440         [ $count -eq $setcount ] ||
2441                 error "stripe count $count, should be $setcount"
2442
2443         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2444                 error "overstriped should be set in pattern"
2445
2446         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2447                 error "dd failed"
2448
2449         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2450 }
2451 run_test 27Ce "test pool with overstriping"
2452
2453 test_27Cf() {
2454         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2455                 skip "server does not support overstriping"
2456         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2457                 skip_env "too many osts, skipping"
2458
2459         test_mkdir -p $DIR/$tdir
2460
2461         local setcount=$(($OSTCOUNT * 2))
2462         [ $setcount -ge 160 ] || large_xattr_enabled ||
2463                 skip_env "ea_inode feature disabled"
2464
2465         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2466                 error "setstripe failed"
2467
2468         echo 1 > $DIR/$tdir/$tfile
2469
2470         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2471         [ $count -eq $setcount ] ||
2472                 error "stripe count $count, should be $setcount"
2473
2474         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2475                 error "overstriped should be set in pattern"
2476
2477         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2478                 error "dd failed"
2479
2480         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2481 }
2482 run_test 27Cf "test default inheritance with overstriping"
2483
2484 test_27D() {
2485         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2486         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2487         remote_mds_nodsh && skip "remote MDS with nodsh"
2488
2489         local POOL=${POOL:-testpool}
2490         local first_ost=0
2491         local last_ost=$(($OSTCOUNT - 1))
2492         local ost_step=1
2493         local ost_list=$(seq $first_ost $ost_step $last_ost)
2494         local ost_range="$first_ost $last_ost $ost_step"
2495
2496         test_mkdir $DIR/$tdir
2497         pool_add $POOL || error "pool_add failed"
2498         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2499
2500         local skip27D
2501         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2502                 skip27D+="-s 29"
2503         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2504                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2505                         skip27D+=" -s 30,31"
2506         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2507           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2508                 skip27D+=" -s 32,33"
2509         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2510                 skip27D+=" -s 34"
2511         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2512                 error "llapi_layout_test failed"
2513
2514         destroy_test_pools || error "destroy test pools failed"
2515 }
2516 run_test 27D "validate llapi_layout API"
2517
2518 # Verify that default_easize is increased from its initial value after
2519 # accessing a widely striped file.
2520 test_27E() {
2521         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2522         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2523                 skip "client does not have LU-3338 fix"
2524
2525         # 72 bytes is the minimum space required to store striping
2526         # information for a file striped across one OST:
2527         # (sizeof(struct lov_user_md_v3) +
2528         #  sizeof(struct lov_user_ost_data_v1))
2529         local min_easize=72
2530         $LCTL set_param -n llite.*.default_easize $min_easize ||
2531                 error "lctl set_param failed"
2532         local easize=$($LCTL get_param -n llite.*.default_easize)
2533
2534         [ $easize -eq $min_easize ] ||
2535                 error "failed to set default_easize"
2536
2537         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2538                 error "setstripe failed"
2539         # In order to ensure stat() call actually talks to MDS we need to
2540         # do something drastic to this file to shake off all lock, e.g.
2541         # rename it (kills lookup lock forcing cache cleaning)
2542         mv $DIR/$tfile $DIR/${tfile}-1
2543         ls -l $DIR/${tfile}-1
2544         rm $DIR/${tfile}-1
2545
2546         easize=$($LCTL get_param -n llite.*.default_easize)
2547
2548         [ $easize -gt $min_easize ] ||
2549                 error "default_easize not updated"
2550 }
2551 run_test 27E "check that default extended attribute size properly increases"
2552
2553 test_27F() { # LU-5346/LU-7975
2554         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2555         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2556         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2557                 skip "Need MDS version at least 2.8.51"
2558         remote_ost_nodsh && skip "remote OST with nodsh"
2559
2560         test_mkdir $DIR/$tdir
2561         rm -f $DIR/$tdir/f0
2562         $LFS setstripe -c 2 $DIR/$tdir
2563
2564         # stop all OSTs to reproduce situation for LU-7975 ticket
2565         for num in $(seq $OSTCOUNT); do
2566                 stop ost$num
2567         done
2568
2569         # open/create f0 with O_LOV_DELAY_CREATE
2570         # truncate f0 to a non-0 size
2571         # close
2572         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2573
2574         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2575         # open/write it again to force delayed layout creation
2576         cat /etc/hosts > $DIR/$tdir/f0 &
2577         catpid=$!
2578
2579         # restart OSTs
2580         for num in $(seq $OSTCOUNT); do
2581                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2582                         error "ost$num failed to start"
2583         done
2584
2585         wait $catpid || error "cat failed"
2586
2587         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2588         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2589                 error "wrong stripecount"
2590
2591 }
2592 run_test 27F "Client resend delayed layout creation with non-zero size"
2593
2594 test_27G() { #LU-10629
2595         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2596                 skip "Need MDS version at least 2.11.51"
2597         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2598         remote_mds_nodsh && skip "remote MDS with nodsh"
2599         local POOL=${POOL:-testpool}
2600         local ostrange="0 0 1"
2601
2602         test_mkdir $DIR/$tdir
2603         pool_add $POOL || error "pool_add failed"
2604         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2605         $LFS setstripe -p $POOL $DIR/$tdir
2606
2607         local pool=$($LFS getstripe -p $DIR/$tdir)
2608
2609         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2610
2611         $LFS setstripe -d $DIR/$tdir
2612
2613         pool=$($LFS getstripe -p $DIR/$tdir)
2614
2615         rmdir $DIR/$tdir
2616
2617         [ -z "$pool" ] || error "'$pool' is not empty"
2618 }
2619 run_test 27G "Clear OST pool from stripe"
2620
2621 test_27H() {
2622         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2623                 skip "Need MDS version newer than 2.11.54"
2624         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2625         test_mkdir $DIR/$tdir
2626         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2627         touch $DIR/$tdir/$tfile
2628         $LFS getstripe -c $DIR/$tdir/$tfile
2629         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2630                 error "two-stripe file doesn't have two stripes"
2631
2632         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2633         $LFS getstripe -y $DIR/$tdir/$tfile
2634         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2635              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2636                 error "expected l_ost_idx: [02]$ not matched"
2637
2638         # make sure ost list has been cleared
2639         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2640         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2641                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2642         touch $DIR/$tdir/f3
2643         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2644 }
2645 run_test 27H "Set specific OSTs stripe"
2646
2647 test_27I() {
2648         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2649         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2650         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2651                 skip "Need MDS version newer than 2.12.52"
2652         local pool=$TESTNAME
2653         local ostrange="1 1 1"
2654
2655         save_layout_restore_at_exit $MOUNT
2656         $LFS setstripe -c 2 -i 0 $MOUNT
2657         pool_add $pool || error "pool_add failed"
2658         pool_add_targets $pool $ostrange || "pool_add_targets failed"
2659         test_mkdir $DIR/$tdir
2660         $LFS setstripe -p $pool $DIR/$tdir
2661         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2662         $LFS getstripe $DIR/$tdir/$tfile
2663 }
2664 run_test 27I "check that root dir striping does not break parent dir one"
2665
2666 test_27J() {
2667         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2668                 skip "Need MDS version newer than 2.12.51"
2669
2670         test_mkdir $DIR/$tdir
2671         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2672         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2673
2674         # create foreign file (raw way)
2675         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2676                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2677
2678         # verify foreign file (raw way)
2679         parse_foreign_file -f $DIR/$tdir/$tfile |
2680                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2681                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2682         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2683                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2684         parse_foreign_file -f $DIR/$tdir/$tfile |
2685                 grep "lov_foreign_size: 73" ||
2686                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2687         parse_foreign_file -f $DIR/$tdir/$tfile |
2688                 grep "lov_foreign_type: 1" ||
2689                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2690         parse_foreign_file -f $DIR/$tdir/$tfile |
2691                 grep "lov_foreign_flags: 0x0000DA08" ||
2692                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2693         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2694                 grep "lov_foreign_value: 0x" |
2695                 sed -e 's/lov_foreign_value: 0x//')
2696         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2697         [[ $lov = ${lov2// /} ]] ||
2698                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2699
2700         # create foreign file (lfs + API)
2701         $LFS setstripe --foreign=daos --flags 0xda08 \
2702                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2703                 error "$DIR/$tdir/${tfile}2: create failed"
2704
2705         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2706                 grep "lfm_magic:.*0x0BD70BD0" ||
2707                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2708         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2709         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2710                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2711         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*daos" ||
2712                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2713         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2714                 grep "lfm_flags:.*0x0000DA08" ||
2715                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2716         $LFS getstripe $DIR/$tdir/${tfile}2 |
2717                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2718                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2719
2720         # modify striping should fail
2721         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2722                 error "$DIR/$tdir/$tfile: setstripe should fail"
2723         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2724                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2725
2726         # R/W should fail
2727         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2728         cat $DIR/$tdir/${tfile}2 &&
2729                 error "$DIR/$tdir/${tfile}2: read should fail"
2730         cat /etc/passwd > $DIR/$tdir/$tfile &&
2731                 error "$DIR/$tdir/$tfile: write should fail"
2732         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2733                 error "$DIR/$tdir/${tfile}2: write should fail"
2734
2735         # chmod should work
2736         chmod 222 $DIR/$tdir/$tfile ||
2737                 error "$DIR/$tdir/$tfile: chmod failed"
2738         chmod 222 $DIR/$tdir/${tfile}2 ||
2739                 error "$DIR/$tdir/${tfile}2: chmod failed"
2740
2741         # chown should work
2742         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2743                 error "$DIR/$tdir/$tfile: chown failed"
2744         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2745                 error "$DIR/$tdir/${tfile}2: chown failed"
2746
2747         # rename should work
2748         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2749                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2750         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2751                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2752
2753         #remove foreign file
2754         rm $DIR/$tdir/${tfile}.new ||
2755                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2756         rm $DIR/$tdir/${tfile}2.new ||
2757                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2758 }
2759 run_test 27J "basic ops on file with foreign LOV"
2760
2761 test_27K() {
2762         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2763                 skip "Need MDS version newer than 2.12.49"
2764
2765         test_mkdir $DIR/$tdir
2766         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2767         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2768
2769         # create foreign dir (raw way)
2770         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2771                 error "create_foreign_dir FAILED"
2772
2773         # verify foreign dir (raw way)
2774         parse_foreign_dir -d $DIR/$tdir/$tdir |
2775                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2776                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2777         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2778                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2779         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2780                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2781         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_flags: 0$" ||
2782                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2783         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2784                 grep "lmv_foreign_value: 0x" |
2785                 sed 's/lmv_foreign_value: 0x//')
2786         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2787                 sed 's/ //g')
2788         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2789
2790         # create foreign dir (lfs + API)
2791         $LFS mkdir --foreign=daos --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2792                 $DIR/$tdir/${tdir}2 ||
2793                 error "$DIR/$tdir/${tdir}2: create failed"
2794
2795         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2796                 grep "lfm_magic:.*0x0CD50CD0" ||
2797                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2798         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2799         # - sizeof(lfm_type) - sizeof(lfm_flags)
2800         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2801                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2802         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*daos" ||
2803                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2804         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2805                 grep "lfm_flags:.*0x0000DA05" ||
2806                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2807         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2808                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2809                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2810
2811         # file create in dir should fail
2812         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
2813         touch $DIR/$tdir/${tdir}2/$tfile &&
2814                 "$DIR/${tdir}2: file create should fail"
2815
2816         # chmod should work
2817         chmod 777 $DIR/$tdir/$tdir ||
2818                 error "$DIR/$tdir: chmod failed"
2819         chmod 777 $DIR/$tdir/${tdir}2 ||
2820                 error "$DIR/${tdir}2: chmod failed"
2821
2822         # chown should work
2823         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2824                 error "$DIR/$tdir: chown failed"
2825         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2826                 error "$DIR/${tdir}2: chown failed"
2827
2828         # rename should work
2829         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2830                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2831         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2832                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2833
2834         #remove foreign dir
2835         rmdir $DIR/$tdir/${tdir}.new ||
2836                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2837         rmdir $DIR/$tdir/${tdir}2.new ||
2838                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2839 }
2840 run_test 27K "basic ops on dir with foreign LMV"
2841
2842 test_27L() {
2843         remote_mds_nodsh && skip "remote MDS with nodsh"
2844
2845         local POOL=${POOL:-$TESTNAME}
2846
2847         pool_add $POOL || error "pool_add failed"
2848
2849         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2850                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2851                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2852 }
2853 run_test 27L "lfs pool_list gives correct pool name"
2854
2855 test_27M() {
2856         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2857                 skip "Need MDS version >= than 2.12.57"
2858         remote_mds_nodsh && skip "remote MDS with nodsh"
2859         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2860
2861         test_mkdir $DIR/$tdir
2862
2863         # Set default striping on directory
2864         $LFS setstripe -C 4 $DIR/$tdir
2865
2866         echo 1 > $DIR/$tdir/${tfile}.1
2867         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2868         local setcount=4
2869         [ $count -eq $setcount ] ||
2870                 error "(1) stripe count $count, should be $setcount"
2871
2872         # Capture existing append_stripe_count setting for restore
2873         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2874         local mdts=$(comma_list $(mdts_nodes))
2875         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$orig_count" EXIT
2876
2877         local appendcount=$orig_count
2878         echo 1 >> $DIR/$tdir/${tfile}.2_append
2879         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
2880         [ $count -eq $appendcount ] ||
2881                 error "(2)stripe count $count, should be $appendcount for append"
2882
2883         # Disable O_APPEND striping, verify it works
2884         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
2885
2886         # Should now get the default striping, which is 4
2887         setcount=4
2888         echo 1 >> $DIR/$tdir/${tfile}.3_append
2889         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
2890         [ $count -eq $setcount ] ||
2891                 error "(3) stripe count $count, should be $setcount"
2892
2893         # Try changing the stripe count for append files
2894         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
2895
2896         # Append striping is now 2 (directory default is still 4)
2897         appendcount=2
2898         echo 1 >> $DIR/$tdir/${tfile}.4_append
2899         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
2900         [ $count -eq $appendcount ] ||
2901                 error "(4) stripe count $count, should be $appendcount for append"
2902
2903         # Test append stripe count of -1
2904         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
2905         appendcount=$OSTCOUNT
2906         echo 1 >> $DIR/$tdir/${tfile}.5
2907         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
2908         [ $count -eq $appendcount ] ||
2909                 error "(5) stripe count $count, should be $appendcount for append"
2910
2911         # Set append striping back to default of 1
2912         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
2913
2914         # Try a new default striping, PFL + DOM
2915         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
2916
2917         # Create normal DOM file, DOM returns stripe count == 0
2918         setcount=0
2919         touch $DIR/$tdir/${tfile}.6
2920         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
2921         [ $count -eq $setcount ] ||
2922                 error "(6) stripe count $count, should be $setcount"
2923
2924         # Show
2925         appendcount=1
2926         echo 1 >> $DIR/$tdir/${tfile}.7_append
2927         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
2928         [ $count -eq $appendcount ] ||
2929                 error "(7) stripe count $count, should be $appendcount for append"
2930
2931         # Clean up DOM layout
2932         $LFS setstripe -d $DIR/$tdir
2933
2934         # Now test that append striping works when layout is from root
2935         $LFS setstripe -c 2 $MOUNT
2936         # Make a special directory for this
2937         mkdir $DIR/${tdir}/${tdir}.2
2938         stack_trap "$LFS setstripe -d $MOUNT" EXIT
2939
2940         # Verify for normal file
2941         setcount=2
2942         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
2943         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
2944         [ $count -eq $setcount ] ||
2945                 error "(8) stripe count $count, should be $setcount"
2946
2947         appendcount=1
2948         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
2949         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
2950         [ $count -eq $appendcount ] ||
2951                 error "(9) stripe count $count, should be $appendcount for append"
2952
2953         # Now test O_APPEND striping with pools
2954         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
2955         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'" EXIT
2956
2957         # Create the pool
2958         pool_add $TESTNAME || error "pool creation failed"
2959         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
2960
2961         echo 1 >> $DIR/$tdir/${tfile}.10_append
2962
2963         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
2964         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
2965
2966         # Check that count is still correct
2967         appendcount=1
2968         echo 1 >> $DIR/$tdir/${tfile}.11_append
2969         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
2970         [ $count -eq $appendcount ] ||
2971                 error "(11) stripe count $count, should be $appendcount for append"
2972
2973         # Disable O_APPEND stripe count, verify pool works separately
2974         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
2975
2976         echo 1 >> $DIR/$tdir/${tfile}.12_append
2977
2978         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
2979         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
2980
2981         # Remove pool setting, verify it's not applied
2982         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
2983
2984         echo 1 >> $DIR/$tdir/${tfile}.13_append
2985
2986         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
2987         [ "$pool" = "" ] || error "(13) pool found: $pool"
2988 }
2989 run_test 27M "test O_APPEND striping"
2990
2991 test_27N() {
2992         combined_mgs_mds && skip "needs separate MGS/MDT"
2993
2994         pool_add $TESTNAME || error "pool_add failed"
2995         do_facet mgs "$LCTL pool_list $FSNAME" |
2996                 grep -Fx "${FSNAME}.${TESTNAME}" ||
2997                 error "lctl pool_list on MGS failed"
2998 }
2999 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3000
3001 # createtest also checks that device nodes are created and
3002 # then visible correctly (#2091)
3003 test_28() { # bug 2091
3004         test_mkdir $DIR/d28
3005         $CREATETEST $DIR/d28/ct || error "createtest failed"
3006 }
3007 run_test 28 "create/mknod/mkdir with bad file types ============"
3008
3009 test_29() {
3010         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3011
3012         sync; sleep 1; sync # flush out any dirty pages from previous tests
3013         cancel_lru_locks
3014         test_mkdir $DIR/d29
3015         touch $DIR/d29/foo
3016         log 'first d29'
3017         ls -l $DIR/d29
3018
3019         declare -i LOCKCOUNTORIG=0
3020         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3021                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3022         done
3023         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3024
3025         declare -i LOCKUNUSEDCOUNTORIG=0
3026         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3027                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3028         done
3029
3030         log 'second d29'
3031         ls -l $DIR/d29
3032         log 'done'
3033
3034         declare -i LOCKCOUNTCURRENT=0
3035         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3036                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3037         done
3038
3039         declare -i LOCKUNUSEDCOUNTCURRENT=0
3040         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3041                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3042         done
3043
3044         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3045                 $LCTL set_param -n ldlm.dump_namespaces ""
3046                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3047                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3048                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3049                 return 2
3050         fi
3051         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3052                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3053                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3054                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3055                 return 3
3056         fi
3057 }
3058 run_test 29 "IT_GETATTR regression  ============================"
3059
3060 test_30a() { # was test_30
3061         cp $(which ls) $DIR || cp /bin/ls $DIR
3062         $DIR/ls / || error "Can't execute binary from lustre"
3063         rm $DIR/ls
3064 }
3065 run_test 30a "execute binary from Lustre (execve) =============="
3066
3067 test_30b() {
3068         cp `which ls` $DIR || cp /bin/ls $DIR
3069         chmod go+rx $DIR/ls
3070         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3071         rm $DIR/ls
3072 }
3073 run_test 30b "execute binary from Lustre as non-root ==========="
3074
3075 test_30c() { # b=22376
3076         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3077
3078         cp $(which ls) $DIR || cp /bin/ls $DIR
3079         chmod a-rw $DIR/ls
3080         cancel_lru_locks mdc
3081         cancel_lru_locks osc
3082         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3083         rm -f $DIR/ls
3084 }
3085 run_test 30c "execute binary from Lustre without read perms ===="
3086
3087 test_30d() {
3088         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3089
3090         for i in {1..10}; do
3091                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3092                 local PID=$!
3093                 sleep 1
3094                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3095                 wait $PID || error "executing dd from Lustre failed"
3096                 rm -f $DIR/$tfile
3097         done
3098
3099         rm -f $DIR/dd
3100 }
3101 run_test 30d "execute binary from Lustre while clear locks"
3102
3103 test_31a() {
3104         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3105         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3106 }
3107 run_test 31a "open-unlink file =================================="
3108
3109 test_31b() {
3110         touch $DIR/f31 || error "touch $DIR/f31 failed"
3111         ln $DIR/f31 $DIR/f31b || error "ln failed"
3112         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3113         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3114 }
3115 run_test 31b "unlink file with multiple links while open ======="
3116
3117 test_31c() {
3118         touch $DIR/f31 || error "touch $DIR/f31 failed"
3119         ln $DIR/f31 $DIR/f31c || error "ln failed"
3120         multiop_bg_pause $DIR/f31 O_uc ||
3121                 error "multiop_bg_pause for $DIR/f31 failed"
3122         MULTIPID=$!
3123         $MULTIOP $DIR/f31c Ouc
3124         kill -USR1 $MULTIPID
3125         wait $MULTIPID
3126 }
3127 run_test 31c "open-unlink file with multiple links ============="
3128
3129 test_31d() {
3130         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3131         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3132 }
3133 run_test 31d "remove of open directory ========================="
3134
3135 test_31e() { # bug 2904
3136         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3137 }
3138 run_test 31e "remove of open non-empty directory ==============="
3139
3140 test_31f() { # bug 4554
3141         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3142
3143         set -vx
3144         test_mkdir $DIR/d31f
3145         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3146         cp /etc/hosts $DIR/d31f
3147         ls -l $DIR/d31f
3148         $LFS getstripe $DIR/d31f/hosts
3149         multiop_bg_pause $DIR/d31f D_c || return 1
3150         MULTIPID=$!
3151
3152         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3153         test_mkdir $DIR/d31f
3154         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3155         cp /etc/hosts $DIR/d31f
3156         ls -l $DIR/d31f
3157         $LFS getstripe $DIR/d31f/hosts
3158         multiop_bg_pause $DIR/d31f D_c || return 1
3159         MULTIPID2=$!
3160
3161         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3162         wait $MULTIPID || error "first opendir $MULTIPID failed"
3163
3164         sleep 6
3165
3166         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3167         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3168         set +vx
3169 }
3170 run_test 31f "remove of open directory with open-unlink file ==="
3171
3172 test_31g() {
3173         echo "-- cross directory link --"
3174         test_mkdir -c1 $DIR/${tdir}ga
3175         test_mkdir -c1 $DIR/${tdir}gb
3176         touch $DIR/${tdir}ga/f
3177         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3178         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3179         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3180         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3181         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3182 }
3183 run_test 31g "cross directory link==============="
3184
3185 test_31h() {
3186         echo "-- cross directory link --"
3187         test_mkdir -c1 $DIR/${tdir}
3188         test_mkdir -c1 $DIR/${tdir}/dir
3189         touch $DIR/${tdir}/f
3190         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3191         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3192         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3193         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3194         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3195 }
3196 run_test 31h "cross directory link under child==============="
3197
3198 test_31i() {
3199         echo "-- cross directory link --"
3200         test_mkdir -c1 $DIR/$tdir
3201         test_mkdir -c1 $DIR/$tdir/dir
3202         touch $DIR/$tdir/dir/f
3203         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3204         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3205         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3206         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3207         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3208 }
3209 run_test 31i "cross directory link under parent==============="
3210
3211 test_31j() {
3212         test_mkdir -c1 -p $DIR/$tdir
3213         test_mkdir -c1 -p $DIR/$tdir/dir1
3214         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3215         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3216         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3217         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3218         return 0
3219 }
3220 run_test 31j "link for directory==============="
3221
3222 test_31k() {
3223         test_mkdir -c1 -p $DIR/$tdir
3224         touch $DIR/$tdir/s
3225         touch $DIR/$tdir/exist
3226         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3227         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3228         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3229         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3230         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3231         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3232         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3233         return 0
3234 }
3235 run_test 31k "link to file: the same, non-existing, dir==============="
3236
3237 test_31m() {
3238         mkdir $DIR/d31m
3239         touch $DIR/d31m/s
3240         mkdir $DIR/d31m2
3241         touch $DIR/d31m2/exist
3242         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3243         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3244         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3245         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3246         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3247         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3248         return 0
3249 }
3250 run_test 31m "link to file: the same, non-existing, dir==============="
3251
3252 test_31n() {
3253         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3254         nlink=$(stat --format=%h $DIR/$tfile)
3255         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3256         local fd=$(free_fd)
3257         local cmd="exec $fd<$DIR/$tfile"
3258         eval $cmd
3259         cmd="exec $fd<&-"
3260         trap "eval $cmd" EXIT
3261         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3262         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3263         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3264         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3265         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3266         eval $cmd
3267 }
3268 run_test 31n "check link count of unlinked file"
3269
3270 link_one() {
3271         local tempfile=$(mktemp $1_XXXXXX)
3272         mlink $tempfile $1 2> /dev/null &&
3273                 echo "$BASHPID: link $tempfile to $1 succeeded"
3274         munlink $tempfile
3275 }
3276
3277 test_31o() { # LU-2901
3278         test_mkdir $DIR/$tdir
3279         for LOOP in $(seq 100); do
3280                 rm -f $DIR/$tdir/$tfile*
3281                 for THREAD in $(seq 8); do
3282                         link_one $DIR/$tdir/$tfile.$LOOP &
3283                 done
3284                 wait
3285                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3286                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3287                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3288                         break || true
3289         done
3290 }
3291 run_test 31o "duplicate hard links with same filename"
3292
3293 test_31p() {
3294         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3295
3296         test_mkdir $DIR/$tdir
3297         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3298         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3299
3300         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3301                 error "open unlink test1 failed"
3302         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3303                 error "open unlink test2 failed"
3304
3305         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3306                 error "test1 still exists"
3307         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3308                 error "test2 still exists"
3309 }
3310 run_test 31p "remove of open striped directory"
3311
3312 cleanup_test32_mount() {
3313         local rc=0
3314         trap 0
3315         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3316         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3317         losetup -d $loopdev || true
3318         rm -rf $DIR/$tdir
3319         return $rc
3320 }
3321
3322 test_32a() {
3323         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3324
3325         echo "== more mountpoints and symlinks ================="
3326         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3327         trap cleanup_test32_mount EXIT
3328         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3329         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3330                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3331         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3332                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3333         cleanup_test32_mount
3334 }
3335 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3336
3337 test_32b() {
3338         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3339
3340         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3341         trap cleanup_test32_mount EXIT
3342         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3343         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3344                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3345         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3346                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3347         cleanup_test32_mount
3348 }
3349 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3350
3351 test_32c() {
3352         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3353
3354         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3355         trap cleanup_test32_mount EXIT
3356         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3357         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3358                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3359         test_mkdir -p $DIR/$tdir/d2/test_dir
3360         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3361                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3362         cleanup_test32_mount
3363 }
3364 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3365
3366 test_32d() {
3367         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3368
3369         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3370         trap cleanup_test32_mount EXIT
3371         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3372         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3373                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3374         test_mkdir -p $DIR/$tdir/d2/test_dir
3375         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3376                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3377         cleanup_test32_mount
3378 }
3379 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3380
3381 test_32e() {
3382         rm -fr $DIR/$tdir
3383         test_mkdir -p $DIR/$tdir/tmp
3384         local tmp_dir=$DIR/$tdir/tmp
3385         ln -s $DIR/$tdir $tmp_dir/symlink11
3386         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3387         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3388         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3389 }
3390 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3391
3392 test_32f() {
3393         rm -fr $DIR/$tdir
3394         test_mkdir -p $DIR/$tdir/tmp
3395         local tmp_dir=$DIR/$tdir/tmp
3396         ln -s $DIR/$tdir $tmp_dir/symlink11
3397         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3398         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3399         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3400 }
3401 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3402
3403 test_32g() {
3404         local tmp_dir=$DIR/$tdir/tmp
3405         test_mkdir -p $tmp_dir
3406         test_mkdir $DIR/${tdir}2
3407         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3408         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3409         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3410         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3411         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3412         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3413 }
3414 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3415
3416 test_32h() {
3417         rm -fr $DIR/$tdir $DIR/${tdir}2
3418         tmp_dir=$DIR/$tdir/tmp
3419         test_mkdir -p $tmp_dir
3420         test_mkdir $DIR/${tdir}2
3421         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3422         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3423         ls $tmp_dir/symlink12 || error "listing symlink12"
3424         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3425 }
3426 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3427
3428 test_32i() {
3429         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3430
3431         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3432         trap cleanup_test32_mount EXIT
3433         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3434         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3435                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3436         touch $DIR/$tdir/test_file
3437         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3438                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3439         cleanup_test32_mount
3440 }
3441 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3442
3443 test_32j() {
3444         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3445
3446         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3447         trap cleanup_test32_mount EXIT
3448         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3449         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3450                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3451         touch $DIR/$tdir/test_file
3452         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3453                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3454         cleanup_test32_mount
3455 }
3456 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3457
3458 test_32k() {
3459         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3460
3461         rm -fr $DIR/$tdir
3462         trap cleanup_test32_mount EXIT
3463         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3464         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3465                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3466         test_mkdir -p $DIR/$tdir/d2
3467         touch $DIR/$tdir/d2/test_file || error "touch failed"
3468         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3469                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3470         cleanup_test32_mount
3471 }
3472 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3473
3474 test_32l() {
3475         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3476
3477         rm -fr $DIR/$tdir
3478         trap cleanup_test32_mount EXIT
3479         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3480         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3481                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3482         test_mkdir -p $DIR/$tdir/d2
3483         touch $DIR/$tdir/d2/test_file || error "touch failed"
3484         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3485                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3486         cleanup_test32_mount
3487 }
3488 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3489
3490 test_32m() {
3491         rm -fr $DIR/d32m
3492         test_mkdir -p $DIR/d32m/tmp
3493         TMP_DIR=$DIR/d32m/tmp
3494         ln -s $DIR $TMP_DIR/symlink11
3495         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3496         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3497                 error "symlink11 not a link"
3498         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3499                 error "symlink01 not a link"
3500 }
3501 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3502
3503 test_32n() {
3504         rm -fr $DIR/d32n
3505         test_mkdir -p $DIR/d32n/tmp
3506         TMP_DIR=$DIR/d32n/tmp
3507         ln -s $DIR $TMP_DIR/symlink11
3508         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3509         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3510         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3511 }
3512 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3513
3514 test_32o() {
3515         touch $DIR/$tfile
3516         test_mkdir -p $DIR/d32o/tmp
3517         TMP_DIR=$DIR/d32o/tmp
3518         ln -s $DIR/$tfile $TMP_DIR/symlink12
3519         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3520         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3521                 error "symlink12 not a link"
3522         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3523         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3524                 error "$DIR/d32o/tmp/symlink12 not file type"
3525         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3526                 error "$DIR/d32o/symlink02 not file type"
3527 }
3528 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3529
3530 test_32p() {
3531         log 32p_1
3532         rm -fr $DIR/d32p
3533         log 32p_2
3534         rm -f $DIR/$tfile
3535         log 32p_3
3536         touch $DIR/$tfile
3537         log 32p_4
3538         test_mkdir -p $DIR/d32p/tmp
3539         log 32p_5
3540         TMP_DIR=$DIR/d32p/tmp
3541         log 32p_6
3542         ln -s $DIR/$tfile $TMP_DIR/symlink12
3543         log 32p_7
3544         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3545         log 32p_8
3546         cat $DIR/d32p/tmp/symlink12 ||
3547                 error "Can't open $DIR/d32p/tmp/symlink12"
3548         log 32p_9
3549         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3550         log 32p_10
3551 }
3552 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3553
3554 test_32q() {
3555         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3556
3557         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3558         trap cleanup_test32_mount EXIT
3559         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3560         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3561         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3562                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3563         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3564         cleanup_test32_mount
3565 }
3566 run_test 32q "stat follows mountpoints in Lustre (should return error)"
3567
3568 test_32r() {
3569         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3570
3571         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3572         trap cleanup_test32_mount EXIT
3573         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3574         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3575         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3576                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3577         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
3578         cleanup_test32_mount
3579 }
3580 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
3581
3582 test_33aa() {
3583         rm -f $DIR/$tfile
3584         touch $DIR/$tfile
3585         chmod 444 $DIR/$tfile
3586         chown $RUNAS_ID $DIR/$tfile
3587         log 33_1
3588         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3589         log 33_2
3590 }
3591 run_test 33aa "write file with mode 444 (should return error)"
3592
3593 test_33a() {
3594         rm -fr $DIR/$tdir
3595         test_mkdir $DIR/$tdir
3596         chown $RUNAS_ID $DIR/$tdir
3597         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
3598                 error "$RUNAS create $tdir/$tfile failed"
3599         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
3600                 error "open RDWR" || true
3601 }
3602 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
3603
3604 test_33b() {
3605         rm -fr $DIR/$tdir
3606         test_mkdir $DIR/$tdir
3607         chown $RUNAS_ID $DIR/$tdir
3608         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
3609 }
3610 run_test 33b "test open file with malformed flags (No panic)"
3611
3612 test_33c() {
3613         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3614         remote_ost_nodsh && skip "remote OST with nodsh"
3615
3616         local ostnum
3617         local ostname
3618         local write_bytes
3619         local all_zeros
3620
3621         all_zeros=:
3622         rm -fr $DIR/$tdir
3623         test_mkdir $DIR/$tdir
3624         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
3625
3626         sync
3627         for ostnum in $(seq $OSTCOUNT); do
3628                 # test-framework's OST numbering is one-based, while Lustre's
3629                 # is zero-based
3630                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3631                 # Parsing llobdstat's output sucks; we could grep the /proc
3632                 # path, but that's likely to not be as portable as using the
3633                 # llobdstat utility.  So we parse lctl output instead.
3634                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3635                         obdfilter/$ostname/stats |
3636                         awk '/^write_bytes/ {print $7}' )
3637                 echo "baseline_write_bytes@$OSTnum/$ostname=$write_bytes"
3638                 if (( ${write_bytes:-0} > 0 ))
3639                 then
3640                         all_zeros=false
3641                         break;
3642                 fi
3643         done
3644
3645         $all_zeros || return 0
3646
3647         # Write four bytes
3648         echo foo > $DIR/$tdir/bar
3649         # Really write them
3650         sync
3651
3652         # Total up write_bytes after writing.  We'd better find non-zeros.
3653         for ostnum in $(seq $OSTCOUNT); do
3654                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3655                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3656                         obdfilter/$ostname/stats |
3657                         awk '/^write_bytes/ {print $7}' )
3658                 echo "write_bytes@$OSTnum/$ostname=$write_bytes"
3659                 if (( ${write_bytes:-0} > 0 ))
3660                 then
3661                         all_zeros=false
3662                         break;
3663                 fi
3664         done
3665
3666         if $all_zeros
3667         then
3668                 for ostnum in $(seq $OSTCOUNT); do
3669                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3670                         echo "Check that write_bytes is present in obdfilter/*/stats:"
3671                         do_facet ost$ostnum lctl get_param -n \
3672                                 obdfilter/$ostname/stats
3673                 done
3674                 error "OST not keeping write_bytes stats (b22312)"
3675         fi
3676 }
3677 run_test 33c "test llobdstat and write_bytes"
3678
3679 test_33d() {
3680         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
3681         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3682
3683         local MDTIDX=1
3684         local remote_dir=$DIR/$tdir/remote_dir
3685
3686         test_mkdir $DIR/$tdir
3687         $LFS mkdir -i $MDTIDX $remote_dir ||
3688                 error "create remote directory failed"
3689
3690         touch $remote_dir/$tfile
3691         chmod 444 $remote_dir/$tfile
3692         chown $RUNAS_ID $remote_dir/$tfile
3693
3694         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3695
3696         chown $RUNAS_ID $remote_dir
3697         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
3698                                         error "create" || true
3699         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
3700                                     error "open RDWR" || true
3701         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
3702 }
3703 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
3704
3705 test_33e() {
3706         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3707
3708         mkdir $DIR/$tdir
3709
3710         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3711         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3712         mkdir $DIR/$tdir/local_dir
3713
3714         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3715         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3716         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3717
3718         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3719                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
3720
3721         rmdir $DIR/$tdir/* || error "rmdir failed"
3722
3723         umask 777
3724         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3725         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3726         mkdir $DIR/$tdir/local_dir
3727
3728         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3729         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3730         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3731
3732         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3733                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
3734
3735         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
3736
3737         umask 000
3738         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3739         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3740         mkdir $DIR/$tdir/local_dir
3741
3742         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3743         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3744         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3745
3746         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3747                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
3748 }
3749 run_test 33e "mkdir and striped directory should have same mode"
3750
3751 cleanup_33f() {
3752         trap 0
3753         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
3754 }
3755
3756 test_33f() {
3757         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3758         remote_mds_nodsh && skip "remote MDS with nodsh"
3759
3760         mkdir $DIR/$tdir
3761         chmod go+rwx $DIR/$tdir
3762         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
3763         trap cleanup_33f EXIT
3764
3765         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
3766                 error "cannot create striped directory"
3767
3768         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
3769                 error "cannot create files in striped directory"
3770
3771         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
3772                 error "cannot remove files in striped directory"
3773
3774         $RUNAS rmdir $DIR/$tdir/striped_dir ||
3775                 error "cannot remove striped directory"
3776
3777         cleanup_33f
3778 }
3779 run_test 33f "nonroot user can create, access, and remove a striped directory"
3780
3781 test_33g() {
3782         mkdir -p $DIR/$tdir/dir2
3783
3784         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
3785         echo $err
3786         [[ $err =~ "exists" ]] || error "Not exists error"
3787 }
3788 run_test 33g "nonroot user create already existing root created file"
3789
3790 test_33h() {
3791         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3792         [ $MDS1_VERSION -lt $(version_code 2.13.50) ] &&
3793                 skip "Need MDS version at least 2.13.50"
3794
3795         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir ||
3796                 error "mkdir $tdir failed"
3797         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
3798
3799         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
3800         local index2
3801
3802         for fname in $DIR/$tdir/$tfile.bak \
3803                      $DIR/$tdir/$tfile.SAV \
3804                      $DIR/$tdir/$tfile.orig \
3805                      $DIR/$tdir/$tfile~; do
3806                 touch $fname  || error "touch $fname failed"
3807                 index2=$($LFS getstripe -m $fname)
3808                 [ $index -eq $index2 ] ||
3809                         error "$fname MDT index mismatch $index != $index2"
3810         done
3811
3812         local failed=0
3813         for i in {1..50}; do
3814                 for fname in $(mktemp -u $DIR/$tdir/.$tfile.XXXXXX) \
3815                              $(mktemp $DIR/$tdir/$tfile.XXXXXXXX); do
3816                         touch $fname  || error "touch $fname failed"
3817                         index2=$($LFS getstripe -m $fname)
3818                         if [[ $index != $index2 ]]; then
3819                                 failed=$((failed + 1))
3820                                 echo "$fname MDT index mismatch $index != $index2"
3821                         fi
3822                 done
3823         done
3824         echo "$failed MDT index mismatches"
3825         (( failed < 4 )) || error "MDT index mismatch $failed times"
3826
3827 }
3828 run_test 33h "temp file is located on the same MDT as target"
3829
3830 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
3831 test_34a() {
3832         rm -f $DIR/f34
3833         $MCREATE $DIR/f34 || error "mcreate failed"
3834         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3835                 error "getstripe failed"
3836         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
3837         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3838                 error "getstripe failed"
3839         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3840                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3841 }
3842 run_test 34a "truncate file that has not been opened ==========="
3843
3844 test_34b() {
3845         [ ! -f $DIR/f34 ] && test_34a
3846         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3847                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3848         $OPENFILE -f O_RDONLY $DIR/f34
3849         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3850                 error "getstripe failed"
3851         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3852                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3853 }
3854 run_test 34b "O_RDONLY opening file doesn't create objects ====="
3855
3856 test_34c() {
3857         [ ! -f $DIR/f34 ] && test_34a
3858         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3859                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3860         $OPENFILE -f O_RDWR $DIR/f34
3861         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
3862                 error "$LFS getstripe failed"
3863         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3864                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3865 }
3866 run_test 34c "O_RDWR opening file-with-size works =============="
3867
3868 test_34d() {
3869         [ ! -f $DIR/f34 ] && test_34a
3870         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
3871                 error "dd failed"
3872         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3873                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3874         rm $DIR/f34
3875 }
3876 run_test 34d "write to sparse file ============================="
3877
3878 test_34e() {
3879         rm -f $DIR/f34e
3880         $MCREATE $DIR/f34e || error "mcreate failed"
3881         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
3882         $CHECKSTAT -s 1000 $DIR/f34e ||
3883                 error "Size of $DIR/f34e not equal to 1000 bytes"
3884         $OPENFILE -f O_RDWR $DIR/f34e
3885         $CHECKSTAT -s 1000 $DIR/f34e ||
3886                 error "Size of $DIR/f34e not equal to 1000 bytes"
3887 }
3888 run_test 34e "create objects, some with size and some without =="
3889
3890 test_34f() { # bug 6242, 6243
3891         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3892
3893         SIZE34F=48000
3894         rm -f $DIR/f34f
3895         $MCREATE $DIR/f34f || error "mcreate failed"
3896         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
3897         dd if=$DIR/f34f of=$TMP/f34f
3898         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
3899         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
3900         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
3901         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
3902         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
3903 }
3904 run_test 34f "read from a file with no objects until EOF ======="
3905
3906 test_34g() {
3907         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3908
3909         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
3910                 error "dd failed"
3911         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
3912         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3913                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
3914         cancel_lru_locks osc
3915         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3916                 error "wrong size after lock cancel"
3917
3918         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
3919         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3920                 error "expanding truncate failed"
3921         cancel_lru_locks osc
3922         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3923                 error "wrong expanded size after lock cancel"
3924 }
3925 run_test 34g "truncate long file ==============================="
3926
3927 test_34h() {
3928         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3929
3930         local gid=10
3931         local sz=1000
3932
3933         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
3934         sync # Flush the cache so that multiop below does not block on cache
3935              # flush when getting the group lock
3936         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
3937         MULTIPID=$!
3938
3939         # Since just timed wait is not good enough, let's do a sync write
3940         # that way we are sure enough time for a roundtrip + processing
3941         # passed + 2 seconds of extra margin.
3942         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
3943         rm $DIR/${tfile}-1
3944         sleep 2
3945
3946         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
3947                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
3948                 kill -9 $MULTIPID
3949         fi
3950         wait $MULTIPID
3951         local nsz=`stat -c %s $DIR/$tfile`
3952         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
3953 }
3954 run_test 34h "ftruncate file under grouplock should not block"
3955
3956 test_35a() {
3957         cp /bin/sh $DIR/f35a
3958         chmod 444 $DIR/f35a
3959         chown $RUNAS_ID $DIR/f35a
3960         $RUNAS $DIR/f35a && error || true
3961         rm $DIR/f35a
3962 }
3963 run_test 35a "exec file with mode 444 (should return and not leak)"
3964
3965 test_36a() {
3966         rm -f $DIR/f36
3967         utime $DIR/f36 || error "utime failed for MDS"
3968 }
3969 run_test 36a "MDS utime check (mknod, utime)"
3970
3971 test_36b() {
3972         echo "" > $DIR/f36
3973         utime $DIR/f36 || error "utime failed for OST"
3974 }
3975 run_test 36b "OST utime check (open, utime)"
3976
3977 test_36c() {
3978         rm -f $DIR/d36/f36
3979         test_mkdir $DIR/d36
3980         chown $RUNAS_ID $DIR/d36
3981         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
3982 }
3983 run_test 36c "non-root MDS utime check (mknod, utime)"
3984
3985 test_36d() {
3986         [ ! -d $DIR/d36 ] && test_36c
3987         echo "" > $DIR/d36/f36
3988         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
3989 }
3990 run_test 36d "non-root OST utime check (open, utime)"
3991
3992 test_36e() {
3993         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
3994
3995         test_mkdir $DIR/$tdir
3996         touch $DIR/$tdir/$tfile
3997         $RUNAS utime $DIR/$tdir/$tfile &&
3998                 error "utime worked, expected failure" || true
3999 }
4000 run_test 36e "utime on non-owned file (should return error)"
4001
4002 subr_36fh() {
4003         local fl="$1"
4004         local LANG_SAVE=$LANG
4005         local LC_LANG_SAVE=$LC_LANG
4006         export LANG=C LC_LANG=C # for date language
4007
4008         DATESTR="Dec 20  2000"
4009         test_mkdir $DIR/$tdir
4010         lctl set_param fail_loc=$fl
4011         date; date +%s
4012         cp /etc/hosts $DIR/$tdir/$tfile
4013         sync & # write RPC generated with "current" inode timestamp, but delayed
4014         sleep 1
4015         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4016         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4017         cancel_lru_locks $OSC
4018         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4019         date; date +%s
4020         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4021                 echo "BEFORE: $LS_BEFORE" && \
4022                 echo "AFTER : $LS_AFTER" && \
4023                 echo "WANT  : $DATESTR" && \
4024                 error "$DIR/$tdir/$tfile timestamps changed" || true
4025
4026         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4027 }
4028
4029 test_36f() {
4030         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4031
4032         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4033         subr_36fh "0x80000214"
4034 }
4035 run_test 36f "utime on file racing with OST BRW write =========="
4036
4037 test_36g() {
4038         remote_ost_nodsh && skip "remote OST with nodsh"
4039         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4040         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4041                 skip "Need MDS version at least 2.12.51"
4042
4043         local fmd_max_age
4044         local fmd
4045         local facet="ost1"
4046         local tgt="obdfilter"
4047
4048         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4049
4050         test_mkdir $DIR/$tdir
4051         fmd_max_age=$(do_facet $facet \
4052                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4053                 head -n 1")
4054
4055         echo "FMD max age: ${fmd_max_age}s"
4056         touch $DIR/$tdir/$tfile
4057         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4058                 gawk '{cnt=cnt+$1}  END{print cnt}')
4059         echo "FMD before: $fmd"
4060         [[ $fmd == 0 ]] &&
4061                 error "FMD wasn't create by touch"
4062         sleep $((fmd_max_age + 12))
4063         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4064                 gawk '{cnt=cnt+$1}  END{print cnt}')
4065         echo "FMD after: $fmd"
4066         [[ $fmd == 0 ]] ||
4067                 error "FMD wasn't expired by ping"
4068 }
4069 run_test 36g "FMD cache expiry ====================="
4070
4071 test_36h() {
4072         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4073
4074         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4075         subr_36fh "0x80000227"
4076 }
4077 run_test 36h "utime on file racing with OST BRW write =========="
4078
4079 test_36i() {
4080         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4081
4082         test_mkdir $DIR/$tdir
4083         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4084
4085         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4086         local new_mtime=$((mtime + 200))
4087
4088         #change Modify time of striped dir
4089         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4090                         error "change mtime failed"
4091
4092         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4093
4094         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4095 }
4096 run_test 36i "change mtime on striped directory"
4097
4098 # test_37 - duplicate with tests 32q 32r
4099
4100 test_38() {
4101         local file=$DIR/$tfile
4102         touch $file
4103         openfile -f O_DIRECTORY $file
4104         local RC=$?
4105         local ENOTDIR=20
4106         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4107         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4108 }
4109 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4110
4111 test_39a() { # was test_39
4112         touch $DIR/$tfile
4113         touch $DIR/${tfile}2
4114 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4115 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4116 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4117         sleep 2
4118         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4119         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4120                 echo "mtime"
4121                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4122                 echo "atime"
4123                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4124                 echo "ctime"
4125                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4126                 error "O_TRUNC didn't change timestamps"
4127         fi
4128 }
4129 run_test 39a "mtime changed on create"
4130
4131 test_39b() {
4132         test_mkdir -c1 $DIR/$tdir
4133         cp -p /etc/passwd $DIR/$tdir/fopen
4134         cp -p /etc/passwd $DIR/$tdir/flink
4135         cp -p /etc/passwd $DIR/$tdir/funlink
4136         cp -p /etc/passwd $DIR/$tdir/frename
4137         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4138
4139         sleep 1
4140         echo "aaaaaa" >> $DIR/$tdir/fopen
4141         echo "aaaaaa" >> $DIR/$tdir/flink
4142         echo "aaaaaa" >> $DIR/$tdir/funlink
4143         echo "aaaaaa" >> $DIR/$tdir/frename
4144
4145         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4146         local link_new=`stat -c %Y $DIR/$tdir/flink`
4147         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4148         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4149
4150         cat $DIR/$tdir/fopen > /dev/null
4151         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4152         rm -f $DIR/$tdir/funlink2
4153         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4154
4155         for (( i=0; i < 2; i++ )) ; do
4156                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4157                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4158                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4159                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4160
4161                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4162                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4163                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4164                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4165
4166                 cancel_lru_locks $OSC
4167                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4168         done
4169 }
4170 run_test 39b "mtime change on open, link, unlink, rename  ======"
4171
4172 # this should be set to past
4173 TEST_39_MTIME=`date -d "1 year ago" +%s`
4174
4175 # bug 11063
4176 test_39c() {
4177         touch $DIR1/$tfile
4178         sleep 2
4179         local mtime0=`stat -c %Y $DIR1/$tfile`
4180
4181         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4182         local mtime1=`stat -c %Y $DIR1/$tfile`
4183         [ "$mtime1" = $TEST_39_MTIME ] || \
4184                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4185
4186         local d1=`date +%s`
4187         echo hello >> $DIR1/$tfile
4188         local d2=`date +%s`
4189         local mtime2=`stat -c %Y $DIR1/$tfile`
4190         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4191                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4192
4193         mv $DIR1/$tfile $DIR1/$tfile-1
4194
4195         for (( i=0; i < 2; i++ )) ; do
4196                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4197                 [ "$mtime2" = "$mtime3" ] || \
4198                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4199
4200                 cancel_lru_locks $OSC
4201                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4202         done
4203 }
4204 run_test 39c "mtime change on rename ==========================="
4205
4206 # bug 21114
4207 test_39d() {
4208         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4209
4210         touch $DIR1/$tfile
4211         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4212
4213         for (( i=0; i < 2; i++ )) ; do
4214                 local mtime=`stat -c %Y $DIR1/$tfile`
4215                 [ $mtime = $TEST_39_MTIME ] || \
4216                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4217
4218                 cancel_lru_locks $OSC
4219                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4220         done
4221 }
4222 run_test 39d "create, utime, stat =============================="
4223
4224 # bug 21114
4225 test_39e() {
4226         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4227
4228         touch $DIR1/$tfile
4229         local mtime1=`stat -c %Y $DIR1/$tfile`
4230
4231         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4232
4233         for (( i=0; i < 2; i++ )) ; do
4234                 local mtime2=`stat -c %Y $DIR1/$tfile`
4235                 [ $mtime2 = $TEST_39_MTIME ] || \
4236                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4237
4238                 cancel_lru_locks $OSC
4239                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4240         done
4241 }
4242 run_test 39e "create, stat, utime, stat ========================"
4243
4244 # bug 21114
4245 test_39f() {
4246         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4247
4248         touch $DIR1/$tfile
4249         mtime1=`stat -c %Y $DIR1/$tfile`
4250
4251         sleep 2
4252         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4253
4254         for (( i=0; i < 2; i++ )) ; do
4255                 local mtime2=`stat -c %Y $DIR1/$tfile`
4256                 [ $mtime2 = $TEST_39_MTIME ] || \
4257                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4258
4259                 cancel_lru_locks $OSC
4260                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4261         done
4262 }
4263 run_test 39f "create, stat, sleep, utime, stat ================="
4264
4265 # bug 11063
4266 test_39g() {
4267         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4268
4269         echo hello >> $DIR1/$tfile
4270         local mtime1=`stat -c %Y $DIR1/$tfile`
4271
4272         sleep 2
4273         chmod o+r $DIR1/$tfile
4274
4275         for (( i=0; i < 2; i++ )) ; do
4276                 local mtime2=`stat -c %Y $DIR1/$tfile`
4277                 [ "$mtime1" = "$mtime2" ] || \
4278                         error "lost mtime: $mtime2, should be $mtime1"
4279
4280                 cancel_lru_locks $OSC
4281                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4282         done
4283 }
4284 run_test 39g "write, chmod, stat ==============================="
4285
4286 # bug 11063
4287 test_39h() {
4288         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4289
4290         touch $DIR1/$tfile
4291         sleep 1
4292
4293         local d1=`date`
4294         echo hello >> $DIR1/$tfile
4295         local mtime1=`stat -c %Y $DIR1/$tfile`
4296
4297         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4298         local d2=`date`
4299         if [ "$d1" != "$d2" ]; then
4300                 echo "write and touch not within one second"
4301         else
4302                 for (( i=0; i < 2; i++ )) ; do
4303                         local mtime2=`stat -c %Y $DIR1/$tfile`
4304                         [ "$mtime2" = $TEST_39_MTIME ] || \
4305                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4306
4307                         cancel_lru_locks $OSC
4308                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4309                 done
4310         fi
4311 }
4312 run_test 39h "write, utime within one second, stat ============="
4313
4314 test_39i() {
4315         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4316
4317         touch $DIR1/$tfile
4318         sleep 1
4319
4320         echo hello >> $DIR1/$tfile
4321         local mtime1=`stat -c %Y $DIR1/$tfile`
4322
4323         mv $DIR1/$tfile $DIR1/$tfile-1
4324
4325         for (( i=0; i < 2; i++ )) ; do
4326                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4327
4328                 [ "$mtime1" = "$mtime2" ] || \
4329                         error "lost mtime: $mtime2, should be $mtime1"
4330
4331                 cancel_lru_locks $OSC
4332                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4333         done
4334 }
4335 run_test 39i "write, rename, stat =============================="
4336
4337 test_39j() {
4338         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4339
4340         start_full_debug_logging
4341         touch $DIR1/$tfile
4342         sleep 1
4343
4344         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4345         lctl set_param fail_loc=0x80000412
4346         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4347                 error "multiop failed"
4348         local multipid=$!
4349         local mtime1=`stat -c %Y $DIR1/$tfile`
4350
4351         mv $DIR1/$tfile $DIR1/$tfile-1
4352
4353         kill -USR1 $multipid
4354         wait $multipid || error "multiop close failed"
4355
4356         for (( i=0; i < 2; i++ )) ; do
4357                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4358                 [ "$mtime1" = "$mtime2" ] ||
4359                         error "mtime is lost on close: $mtime2, " \
4360                               "should be $mtime1"
4361
4362                 cancel_lru_locks
4363                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4364         done
4365         lctl set_param fail_loc=0
4366         stop_full_debug_logging
4367 }
4368 run_test 39j "write, rename, close, stat ======================="
4369
4370 test_39k() {
4371         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4372
4373         touch $DIR1/$tfile
4374         sleep 1
4375
4376         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4377         local multipid=$!
4378         local mtime1=`stat -c %Y $DIR1/$tfile`
4379
4380         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4381
4382         kill -USR1 $multipid
4383         wait $multipid || error "multiop close failed"
4384
4385         for (( i=0; i < 2; i++ )) ; do
4386                 local mtime2=`stat -c %Y $DIR1/$tfile`
4387
4388                 [ "$mtime2" = $TEST_39_MTIME ] || \
4389                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4390
4391                 cancel_lru_locks
4392                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4393         done
4394 }
4395 run_test 39k "write, utime, close, stat ========================"
4396
4397 # this should be set to future
4398 TEST_39_ATIME=`date -d "1 year" +%s`
4399
4400 test_39l() {
4401         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4402         remote_mds_nodsh && skip "remote MDS with nodsh"
4403
4404         local atime_diff=$(do_facet $SINGLEMDS \
4405                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4406         rm -rf $DIR/$tdir
4407         mkdir -p $DIR/$tdir
4408
4409         # test setting directory atime to future
4410         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4411         local atime=$(stat -c %X $DIR/$tdir)
4412         [ "$atime" = $TEST_39_ATIME ] ||
4413                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4414
4415         # test setting directory atime from future to now
4416         local now=$(date +%s)
4417         touch -a -d @$now $DIR/$tdir
4418
4419         atime=$(stat -c %X $DIR/$tdir)
4420         [ "$atime" -eq "$now"  ] ||
4421                 error "atime is not updated from future: $atime, $now"
4422
4423         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4424         sleep 3
4425
4426         # test setting directory atime when now > dir atime + atime_diff
4427         local d1=$(date +%s)
4428         ls $DIR/$tdir
4429         local d2=$(date +%s)
4430         cancel_lru_locks mdc
4431         atime=$(stat -c %X $DIR/$tdir)
4432         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4433                 error "atime is not updated  : $atime, should be $d2"
4434
4435         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4436         sleep 3
4437
4438         # test not setting directory atime when now < dir atime + atime_diff
4439         ls $DIR/$tdir
4440         cancel_lru_locks mdc
4441         atime=$(stat -c %X $DIR/$tdir)
4442         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4443                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4444
4445         do_facet $SINGLEMDS \
4446                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4447 }
4448 run_test 39l "directory atime update ==========================="
4449
4450 test_39m() {
4451         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4452
4453         touch $DIR1/$tfile
4454         sleep 2
4455         local far_past_mtime=$(date -d "May 29 1953" +%s)
4456         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4457
4458         touch -m -d @$far_past_mtime $DIR1/$tfile
4459         touch -a -d @$far_past_atime $DIR1/$tfile
4460
4461         for (( i=0; i < 2; i++ )) ; do
4462                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4463                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4464                         error "atime or mtime set incorrectly"
4465
4466                 cancel_lru_locks $OSC
4467                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4468         done
4469 }
4470 run_test 39m "test atime and mtime before 1970"
4471
4472 test_39n() { # LU-3832
4473         remote_mds_nodsh && skip "remote MDS with nodsh"
4474
4475         local atime_diff=$(do_facet $SINGLEMDS \
4476                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4477         local atime0
4478         local atime1
4479         local atime2
4480
4481         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4482
4483         rm -rf $DIR/$tfile
4484         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4485         atime0=$(stat -c %X $DIR/$tfile)
4486
4487         sleep 5
4488         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4489         atime1=$(stat -c %X $DIR/$tfile)
4490
4491         sleep 5
4492         cancel_lru_locks mdc
4493         cancel_lru_locks osc
4494         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4495         atime2=$(stat -c %X $DIR/$tfile)
4496
4497         do_facet $SINGLEMDS \
4498                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4499
4500         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4501         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4502 }
4503 run_test 39n "check that O_NOATIME is honored"
4504
4505 test_39o() {
4506         TESTDIR=$DIR/$tdir/$tfile
4507         [ -e $TESTDIR ] && rm -rf $TESTDIR
4508         mkdir -p $TESTDIR
4509         cd $TESTDIR
4510         links1=2
4511         ls
4512         mkdir a b
4513         ls
4514         links2=$(stat -c %h .)
4515         [ $(($links1 + 2)) != $links2 ] &&
4516                 error "wrong links count $(($links1 + 2)) != $links2"
4517         rmdir b
4518         links3=$(stat -c %h .)
4519         [ $(($links1 + 1)) != $links3 ] &&
4520                 error "wrong links count $links1 != $links3"
4521         return 0
4522 }
4523 run_test 39o "directory cached attributes updated after create"
4524
4525 test_39p() {
4526         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4527
4528         local MDTIDX=1
4529         TESTDIR=$DIR/$tdir/$tdir
4530         [ -e $TESTDIR ] && rm -rf $TESTDIR
4531         test_mkdir -p $TESTDIR
4532         cd $TESTDIR
4533         links1=2
4534         ls
4535         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4536         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4537         ls
4538         links2=$(stat -c %h .)
4539         [ $(($links1 + 2)) != $links2 ] &&
4540                 error "wrong links count $(($links1 + 2)) != $links2"
4541         rmdir remote_dir2
4542         links3=$(stat -c %h .)
4543         [ $(($links1 + 1)) != $links3 ] &&
4544                 error "wrong links count $links1 != $links3"
4545         return 0
4546 }
4547 run_test 39p "remote directory cached attributes updated after create ========"
4548
4549 test_39r() {
4550         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
4551                 skip "no atime update on old OST"
4552         if [ "$ost1_FSTYPE" != ldiskfs ]; then
4553                 skip_env "ldiskfs only test"
4554         fi
4555
4556         local saved_adiff
4557         saved_adiff=$(do_facet ost1 \
4558                 lctl get_param -n obdfilter.*OST0000.atime_diff)
4559         stack_trap "do_facet ost1 \
4560                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
4561
4562         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
4563
4564         $LFS setstripe -i 0 $DIR/$tfile
4565         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
4566                 error "can't write initial file"
4567         cancel_lru_locks osc
4568
4569         # exceed atime_diff and access file
4570         sleep 6
4571         dd if=$DIR/$tfile of=/dev/null || error "can't udpate atime"
4572
4573         local atime_cli=$(stat -c %X $DIR/$tfile)
4574         echo "client atime: $atime_cli"
4575         # allow atime update to be written to device
4576         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
4577         sleep 5
4578
4579         local ostdev=$(ostdevname 1)
4580         local fid=($(lfs getstripe -y $DIR/$tfile |
4581                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
4582         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
4583         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
4584
4585         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
4586         local atime_ost=$(do_facet ost1 "$cmd" |&
4587                           awk -F'[: ]' '/atime:/ { print $4 }')
4588         (( atime_cli == atime_ost )) ||
4589                 error "atime on client $atime_cli != ost $atime_ost"
4590 }
4591 run_test 39r "lazy atime update on OST"
4592
4593 test_39q() { # LU-8041
4594         local testdir=$DIR/$tdir
4595         mkdir -p $testdir
4596         multiop_bg_pause $testdir D_c || error "multiop failed"
4597         local multipid=$!
4598         cancel_lru_locks mdc
4599         kill -USR1 $multipid
4600         local atime=$(stat -c %X $testdir)
4601         [ "$atime" -ne 0 ] || error "atime is zero"
4602 }
4603 run_test 39q "close won't zero out atime"
4604
4605 test_40() {
4606         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
4607         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
4608                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
4609         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
4610                 error "$tfile is not 4096 bytes in size"
4611 }
4612 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
4613
4614 test_41() {
4615         # bug 1553
4616         small_write $DIR/f41 18
4617 }
4618 run_test 41 "test small file write + fstat ====================="
4619
4620 count_ost_writes() {
4621         lctl get_param -n ${OSC}.*.stats |
4622                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
4623                         END { printf("%0.0f", writes) }'
4624 }
4625
4626 # decent default
4627 WRITEBACK_SAVE=500
4628 DIRTY_RATIO_SAVE=40
4629 MAX_DIRTY_RATIO=50
4630 BG_DIRTY_RATIO_SAVE=10
4631 MAX_BG_DIRTY_RATIO=25
4632
4633 start_writeback() {
4634         trap 0
4635         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
4636         # dirty_ratio, dirty_background_ratio
4637         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4638                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
4639                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
4640                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
4641         else
4642                 # if file not here, we are a 2.4 kernel
4643                 kill -CONT `pidof kupdated`
4644         fi
4645 }
4646
4647 stop_writeback() {
4648         # setup the trap first, so someone cannot exit the test at the
4649         # exact wrong time and mess up a machine
4650         trap start_writeback EXIT
4651         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
4652         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4653                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
4654                 sysctl -w vm.dirty_writeback_centisecs=0
4655                 sysctl -w vm.dirty_writeback_centisecs=0
4656                 # save and increase /proc/sys/vm/dirty_ratio
4657                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
4658                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
4659                 # save and increase /proc/sys/vm/dirty_background_ratio
4660                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
4661                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
4662         else
4663                 # if file not here, we are a 2.4 kernel
4664                 kill -STOP `pidof kupdated`
4665         fi
4666 }
4667
4668 # ensure that all stripes have some grant before we test client-side cache
4669 setup_test42() {
4670         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
4671                 dd if=/dev/zero of=$i bs=4k count=1
4672                 rm $i
4673         done
4674 }
4675
4676 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
4677 # file truncation, and file removal.
4678 test_42a() {
4679         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4680
4681         setup_test42
4682         cancel_lru_locks $OSC
4683         stop_writeback
4684         sync; sleep 1; sync # just to be safe
4685         BEFOREWRITES=`count_ost_writes`
4686         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
4687         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
4688         AFTERWRITES=`count_ost_writes`
4689         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
4690                 error "$BEFOREWRITES < $AFTERWRITES"
4691         start_writeback
4692 }
4693 run_test 42a "ensure that we don't flush on close"
4694
4695 test_42b() {
4696         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4697
4698         setup_test42
4699         cancel_lru_locks $OSC
4700         stop_writeback
4701         sync
4702         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
4703         BEFOREWRITES=$(count_ost_writes)
4704         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
4705         AFTERWRITES=$(count_ost_writes)
4706         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4707                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
4708         fi
4709         BEFOREWRITES=$(count_ost_writes)
4710         sync || error "sync: $?"
4711         AFTERWRITES=$(count_ost_writes)
4712         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4713                 error "$BEFOREWRITES < $AFTERWRITES on sync"
4714         fi
4715         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
4716         start_writeback
4717         return 0
4718 }
4719 run_test 42b "test destroy of file with cached dirty data ======"
4720
4721 # if these tests just want to test the effect of truncation,
4722 # they have to be very careful.  consider:
4723 # - the first open gets a {0,EOF}PR lock
4724 # - the first write conflicts and gets a {0, count-1}PW
4725 # - the rest of the writes are under {count,EOF}PW
4726 # - the open for truncate tries to match a {0,EOF}PR
4727 #   for the filesize and cancels the PWs.
4728 # any number of fixes (don't get {0,EOF} on open, match
4729 # composite locks, do smarter file size management) fix
4730 # this, but for now we want these tests to verify that
4731 # the cancellation with truncate intent works, so we
4732 # start the file with a full-file pw lock to match against
4733 # until the truncate.
4734 trunc_test() {
4735         test=$1
4736         file=$DIR/$test
4737         offset=$2
4738         cancel_lru_locks $OSC
4739         stop_writeback
4740         # prime the file with 0,EOF PW to match
4741         touch $file
4742         $TRUNCATE $file 0
4743         sync; sync
4744         # now the real test..
4745         dd if=/dev/zero of=$file bs=1024 count=100
4746         BEFOREWRITES=`count_ost_writes`
4747         $TRUNCATE $file $offset
4748         cancel_lru_locks $OSC
4749         AFTERWRITES=`count_ost_writes`
4750         start_writeback
4751 }
4752
4753 test_42c() {
4754         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4755
4756         trunc_test 42c 1024
4757         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
4758                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
4759         rm $file
4760 }
4761 run_test 42c "test partial truncate of file with cached dirty data"
4762
4763 test_42d() {
4764         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4765
4766         trunc_test 42d 0
4767         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
4768                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
4769         rm $file
4770 }
4771 run_test 42d "test complete truncate of file with cached dirty data"
4772
4773 test_42e() { # bug22074
4774         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4775
4776         local TDIR=$DIR/${tdir}e
4777         local pages=16 # hardcoded 16 pages, don't change it.
4778         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
4779         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
4780         local max_dirty_mb
4781         local warmup_files
4782
4783         test_mkdir $DIR/${tdir}e
4784         $LFS setstripe -c 1 $TDIR
4785         createmany -o $TDIR/f $files
4786
4787         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
4788
4789         # we assume that with $OSTCOUNT files, at least one of them will
4790         # be allocated on OST0.
4791         warmup_files=$((OSTCOUNT * max_dirty_mb))
4792         createmany -o $TDIR/w $warmup_files
4793
4794         # write a large amount of data into one file and sync, to get good
4795         # avail_grant number from OST.
4796         for ((i=0; i<$warmup_files; i++)); do
4797                 idx=$($LFS getstripe -i $TDIR/w$i)
4798                 [ $idx -ne 0 ] && continue
4799                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
4800                 break
4801         done
4802         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
4803         sync
4804         $LCTL get_param $proc_osc0/cur_dirty_bytes
4805         $LCTL get_param $proc_osc0/cur_grant_bytes
4806
4807         # create as much dirty pages as we can while not to trigger the actual
4808         # RPCs directly. but depends on the env, VFS may trigger flush during this
4809         # period, hopefully we are good.
4810         for ((i=0; i<$warmup_files; i++)); do
4811                 idx=$($LFS getstripe -i $TDIR/w$i)
4812                 [ $idx -ne 0 ] && continue
4813                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
4814         done
4815         $LCTL get_param $proc_osc0/cur_dirty_bytes
4816         $LCTL get_param $proc_osc0/cur_grant_bytes
4817
4818         # perform the real test
4819         $LCTL set_param $proc_osc0/rpc_stats 0
4820         for ((;i<$files; i++)); do
4821                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
4822                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
4823         done
4824         sync
4825         $LCTL get_param $proc_osc0/rpc_stats
4826
4827         local percent=0
4828         local have_ppr=false
4829         $LCTL get_param $proc_osc0/rpc_stats |
4830                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
4831                         # skip lines until we are at the RPC histogram data
4832                         [ "$PPR" == "pages" ] && have_ppr=true && continue
4833                         $have_ppr || continue
4834
4835                         # we only want the percent stat for < 16 pages
4836                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
4837
4838                         percent=$((percent + WPCT))
4839                         if [[ $percent -gt 15 ]]; then
4840                                 error "less than 16-pages write RPCs" \
4841                                       "$percent% > 15%"
4842                                 break
4843                         fi
4844                 done
4845         rm -rf $TDIR
4846 }
4847 run_test 42e "verify sub-RPC writes are not done synchronously"
4848
4849 test_43A() { # was test_43
4850         test_mkdir $DIR/$tdir
4851         cp -p /bin/ls $DIR/$tdir/$tfile
4852         $MULTIOP $DIR/$tdir/$tfile Ow_c &
4853         pid=$!
4854         # give multiop a chance to open
4855         sleep 1
4856
4857         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
4858         kill -USR1 $pid
4859 }
4860 run_test 43A "execution of file opened for write should return -ETXTBSY"
4861
4862 test_43a() {
4863         test_mkdir $DIR/$tdir
4864         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4865         $DIR/$tdir/sleep 60 &
4866         SLEEP_PID=$!
4867         # Make sure exec of $tdir/sleep wins race with truncate
4868         sleep 1
4869         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
4870         kill $SLEEP_PID
4871 }
4872 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
4873
4874 test_43b() {
4875         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4876
4877         test_mkdir $DIR/$tdir
4878         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4879         $DIR/$tdir/sleep 60 &
4880         SLEEP_PID=$!
4881         # Make sure exec of $tdir/sleep wins race with truncate
4882         sleep 1
4883         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
4884         kill $SLEEP_PID
4885 }
4886 run_test 43b "truncate of file being executed should return -ETXTBSY"
4887
4888 test_43c() {
4889         local testdir="$DIR/$tdir"
4890         test_mkdir $testdir
4891         cp $SHELL $testdir/
4892         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
4893                 ( cd $testdir && md5sum -c )
4894 }
4895 run_test 43c "md5sum of copy into lustre"
4896
4897 test_44A() { # was test_44
4898         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4899
4900         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
4901         dd if=$DIR/f1 bs=4k count=1 > /dev/null
4902 }
4903 run_test 44A "zero length read from a sparse stripe"
4904
4905 test_44a() {
4906         local nstripe=$($LCTL lov_getconfig $DIR | grep default_stripe_count: |
4907                 awk '{ print $2 }')
4908         [ -z "$nstripe" ] && skip "can't get stripe info"
4909         [[ $nstripe -gt $OSTCOUNT ]] &&
4910                 skip "Wrong default_stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
4911
4912         local stride=$($LCTL lov_getconfig $DIR | grep default_stripe_size: |
4913                 awk '{ print $2 }')
4914         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
4915                 nstripe=$($LCTL lov_getconfig $DIR | grep obd_count: |
4916                         awk '{ print $2 }')
4917         fi
4918
4919         OFFSETS="0 $((stride/2)) $((stride-1))"
4920         for offset in $OFFSETS; do
4921                 for i in $(seq 0 $((nstripe-1))); do
4922                         local GLOBALOFFSETS=""
4923                         # size in Bytes
4924                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
4925                         local myfn=$DIR/d44a-$size
4926                         echo "--------writing $myfn at $size"
4927                         ll_sparseness_write $myfn $size ||
4928                                 error "ll_sparseness_write"
4929                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
4930                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4931                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4932
4933                         for j in $(seq 0 $((nstripe-1))); do
4934                                 # size in Bytes
4935                                 size=$((((j + $nstripe )*$stride + $offset)))
4936                                 ll_sparseness_write $myfn $size ||
4937                                         error "ll_sparseness_write"
4938                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
4939                         done
4940                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4941                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4942                         rm -f $myfn
4943                 done
4944         done
4945 }
4946 run_test 44a "test sparse pwrite ==============================="
4947
4948 dirty_osc_total() {
4949         tot=0
4950         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
4951                 tot=$(($tot + $d))
4952         done
4953         echo $tot
4954 }
4955 do_dirty_record() {
4956         before=`dirty_osc_total`
4957         echo executing "\"$*\""
4958         eval $*
4959         after=`dirty_osc_total`
4960         echo before $before, after $after
4961 }
4962 test_45() {
4963         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4964
4965         f="$DIR/f45"
4966         # Obtain grants from OST if it supports it
4967         echo blah > ${f}_grant
4968         stop_writeback
4969         sync
4970         do_dirty_record "echo blah > $f"
4971         [[ $before -eq $after ]] && error "write wasn't cached"
4972         do_dirty_record "> $f"
4973         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
4974         do_dirty_record "echo blah > $f"
4975         [[ $before -eq $after ]] && error "write wasn't cached"
4976         do_dirty_record "sync"
4977         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
4978         do_dirty_record "echo blah > $f"
4979         [[ $before -eq $after ]] && error "write wasn't cached"
4980         do_dirty_record "cancel_lru_locks osc"
4981         [[ $before -gt $after ]] ||
4982                 error "lock cancellation didn't lower dirty count"
4983         start_writeback
4984 }
4985 run_test 45 "osc io page accounting ============================"
4986
4987 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
4988 # test tickles a bug where re-dirtying a page was failing to be mapped to the
4989 # objects offset and an assert hit when an rpc was built with 1023's mapped
4990 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
4991 test_46() {
4992         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4993
4994         f="$DIR/f46"
4995         stop_writeback
4996         sync
4997         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
4998         sync
4999         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5000         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5001         sync
5002         start_writeback
5003 }
5004 run_test 46 "dirtying a previously written page ================"
5005
5006 # test_47 is removed "Device nodes check" is moved to test_28
5007
5008 test_48a() { # bug 2399
5009         [ "$mds1_FSTYPE" = "zfs" ] &&
5010         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5011                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5012
5013         test_mkdir $DIR/$tdir
5014         cd $DIR/$tdir
5015         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5016         test_mkdir $DIR/$tdir
5017         touch foo || error "'touch foo' failed after recreating cwd"
5018         test_mkdir bar
5019         touch .foo || error "'touch .foo' failed after recreating cwd"
5020         test_mkdir .bar
5021         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5022         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5023         cd . || error "'cd .' failed after recreating cwd"
5024         mkdir . && error "'mkdir .' worked after recreating cwd"
5025         rmdir . && error "'rmdir .' worked after recreating cwd"
5026         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5027         cd .. || error "'cd ..' failed after recreating cwd"
5028 }
5029 run_test 48a "Access renamed working dir (should return errors)="
5030
5031 test_48b() { # bug 2399
5032         rm -rf $DIR/$tdir
5033         test_mkdir $DIR/$tdir
5034         cd $DIR/$tdir
5035         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5036         touch foo && error "'touch foo' worked after removing cwd"
5037         mkdir foo && error "'mkdir foo' worked after removing cwd"
5038         touch .foo && error "'touch .foo' worked after removing cwd"
5039         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5040         ls . > /dev/null && error "'ls .' worked after removing cwd"
5041         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5042         mkdir . && error "'mkdir .' worked after removing cwd"
5043         rmdir . && error "'rmdir .' worked after removing cwd"
5044         ln -s . foo && error "'ln -s .' worked after removing cwd"
5045         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5046 }
5047 run_test 48b "Access removed working dir (should return errors)="
5048
5049 test_48c() { # bug 2350
5050         #lctl set_param debug=-1
5051         #set -vx
5052         rm -rf $DIR/$tdir
5053         test_mkdir -p $DIR/$tdir/dir
5054         cd $DIR/$tdir/dir
5055         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5056         $TRACE touch foo && error "touch foo worked after removing cwd"
5057         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5058         touch .foo && error "touch .foo worked after removing cwd"
5059         mkdir .foo && error "mkdir .foo worked after removing cwd"
5060         $TRACE ls . && error "'ls .' worked after removing cwd"
5061         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5062         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5063         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5064         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5065         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5066 }
5067 run_test 48c "Access removed working subdir (should return errors)"
5068
5069 test_48d() { # bug 2350
5070         #lctl set_param debug=-1
5071         #set -vx
5072         rm -rf $DIR/$tdir
5073         test_mkdir -p $DIR/$tdir/dir
5074         cd $DIR/$tdir/dir
5075         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5076         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5077         $TRACE touch foo && error "'touch foo' worked after removing parent"
5078         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5079         touch .foo && error "'touch .foo' worked after removing parent"
5080         mkdir .foo && error "mkdir .foo worked after removing parent"
5081         $TRACE ls . && error "'ls .' worked after removing parent"
5082         $TRACE ls .. && error "'ls ..' worked after removing parent"
5083         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5084         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5085         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5086         true
5087 }
5088 run_test 48d "Access removed parent subdir (should return errors)"
5089
5090 test_48e() { # bug 4134
5091         #lctl set_param debug=-1
5092         #set -vx
5093         rm -rf $DIR/$tdir
5094         test_mkdir -p $DIR/$tdir/dir
5095         cd $DIR/$tdir/dir
5096         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5097         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5098         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5099         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5100         # On a buggy kernel addition of "touch foo" after cd .. will
5101         # produce kernel oops in lookup_hash_it
5102         touch ../foo && error "'cd ..' worked after recreate parent"
5103         cd $DIR
5104         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5105 }
5106 run_test 48e "Access to recreated parent subdir (should return errors)"
5107
5108 test_49() { # LU-1030
5109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5110         remote_ost_nodsh && skip "remote OST with nodsh"
5111
5112         # get ost1 size - $FSNAME-OST0000
5113         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5114                 awk '{ print $4 }')
5115         # write 800M at maximum
5116         [[ $ost1_size -lt 2 ]] && ost1_size=2
5117         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5118
5119         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5120         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5121         local dd_pid=$!
5122
5123         # change max_pages_per_rpc while writing the file
5124         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5125         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5126         # loop until dd process exits
5127         while ps ax -opid | grep -wq $dd_pid; do
5128                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5129                 sleep $((RANDOM % 5 + 1))
5130         done
5131         # restore original max_pages_per_rpc
5132         $LCTL set_param $osc1_mppc=$orig_mppc
5133         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5134 }
5135 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5136
5137 test_50() {
5138         # bug 1485
5139         test_mkdir $DIR/$tdir
5140         cd $DIR/$tdir
5141         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5142 }
5143 run_test 50 "special situations: /proc symlinks  ==============="
5144
5145 test_51a() {    # was test_51
5146         # bug 1516 - create an empty entry right after ".." then split dir
5147         test_mkdir -c1 $DIR/$tdir
5148         touch $DIR/$tdir/foo
5149         $MCREATE $DIR/$tdir/bar
5150         rm $DIR/$tdir/foo
5151         createmany -m $DIR/$tdir/longfile 201
5152         FNUM=202
5153         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5154                 $MCREATE $DIR/$tdir/longfile$FNUM
5155                 FNUM=$(($FNUM + 1))
5156                 echo -n "+"
5157         done
5158         echo
5159         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5160 }
5161 run_test 51a "special situations: split htree with empty entry =="
5162
5163 cleanup_print_lfs_df () {
5164         trap 0
5165         $LFS df
5166         $LFS df -i
5167 }
5168
5169 test_51b() {
5170         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5171
5172         local dir=$DIR/$tdir
5173         local nrdirs=$((65536 + 100))
5174
5175         # cleanup the directory
5176         rm -fr $dir
5177
5178         test_mkdir -c1 $dir
5179
5180         $LFS df
5181         $LFS df -i
5182         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5183         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5184         [[ $numfree -lt $nrdirs ]] &&
5185                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5186
5187         # need to check free space for the directories as well
5188         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5189         numfree=$(( blkfree / $(fs_inode_ksize) ))
5190         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5191
5192         trap cleanup_print_lfs_df EXIT
5193
5194         # create files
5195         createmany -d $dir/d $nrdirs || {
5196                 unlinkmany $dir/d $nrdirs
5197                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5198         }
5199
5200         # really created :
5201         nrdirs=$(ls -U $dir | wc -l)
5202
5203         # unlink all but 100 subdirectories, then check it still works
5204         local left=100
5205         local delete=$((nrdirs - left))
5206
5207         $LFS df
5208         $LFS df -i
5209
5210         # for ldiskfs the nlink count should be 1, but this is OSD specific
5211         # and so this is listed for informational purposes only
5212         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5213         unlinkmany -d $dir/d $delete ||
5214                 error "unlink of first $delete subdirs failed"
5215
5216         echo "nlink between: $(stat -c %h $dir)"
5217         local found=$(ls -U $dir | wc -l)
5218         [ $found -ne $left ] &&
5219                 error "can't find subdirs: found only $found, expected $left"
5220
5221         unlinkmany -d $dir/d $delete $left ||
5222                 error "unlink of second $left subdirs failed"
5223         # regardless of whether the backing filesystem tracks nlink accurately
5224         # or not, the nlink count shouldn't be more than "." and ".." here
5225         local after=$(stat -c %h $dir)
5226         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5227                 echo "nlink after: $after"
5228
5229         cleanup_print_lfs_df
5230 }
5231 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5232
5233 test_51d() {
5234         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5235         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5236
5237         test_mkdir $DIR/$tdir
5238         createmany -o $DIR/$tdir/t- 1000
5239         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5240         for N in $(seq 0 $((OSTCOUNT - 1))); do
5241                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
5242                         END { printf("%0.0f", objs) }' $TMP/$tfile)
5243                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5244                         '($1 == '$N') { objs += 1 } \
5245                         END { printf("%0.0f", objs) }')
5246                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
5247         done
5248         unlinkmany $DIR/$tdir/t- 1000
5249
5250         NLAST=0
5251         for N in $(seq 1 $((OSTCOUNT - 1))); do
5252                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
5253                         error "OST $N has less objects vs OST $NLAST" \
5254                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5255                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
5256                         error "OST $N has less objects vs OST $NLAST" \
5257                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5258
5259                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
5260                         error "OST $N has less #0 objects vs OST $NLAST" \
5261                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5262                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
5263                         error "OST $N has less #0 objects vs OST $NLAST" \
5264                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5265                 NLAST=$N
5266         done
5267         rm -f $TMP/$tfile
5268 }
5269 run_test 51d "check object distribution"
5270
5271 test_51e() {
5272         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5273                 skip_env "ldiskfs only test"
5274         fi
5275
5276         test_mkdir -c1 $DIR/$tdir
5277         test_mkdir -c1 $DIR/$tdir/d0
5278
5279         touch $DIR/$tdir/d0/foo
5280         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5281                 error "file exceed 65000 nlink limit!"
5282         unlinkmany $DIR/$tdir/d0/f- 65001
5283         return 0
5284 }
5285 run_test 51e "check file nlink limit"
5286
5287 test_51f() {
5288         test_mkdir $DIR/$tdir
5289
5290         local max=100000
5291         local ulimit_old=$(ulimit -n)
5292         local spare=20 # number of spare fd's for scripts/libraries, etc.
5293         local mdt=$($LFS getstripe -m $DIR/$tdir)
5294         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5295
5296         echo "MDT$mdt numfree=$numfree, max=$max"
5297         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5298         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5299                 while ! ulimit -n $((numfree + spare)); do
5300                         numfree=$((numfree * 3 / 4))
5301                 done
5302                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5303         else
5304                 echo "left ulimit at $ulimit_old"
5305         fi
5306
5307         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5308                 unlinkmany $DIR/$tdir/f $numfree
5309                 error "create+open $numfree files in $DIR/$tdir failed"
5310         }
5311         ulimit -n $ulimit_old
5312
5313         # if createmany exits at 120s there will be fewer than $numfree files
5314         unlinkmany $DIR/$tdir/f $numfree || true
5315 }
5316 run_test 51f "check many open files limit"
5317
5318 test_52a() {
5319         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5320         test_mkdir $DIR/$tdir
5321         touch $DIR/$tdir/foo
5322         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5323         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5324         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5325         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5326         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5327                                         error "link worked"
5328         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5329         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5330         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5331                                                      error "lsattr"
5332         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5333         cp -r $DIR/$tdir $TMP/
5334         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5335 }
5336 run_test 52a "append-only flag test (should return errors)"
5337
5338 test_52b() {
5339         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5340         test_mkdir $DIR/$tdir
5341         touch $DIR/$tdir/foo
5342         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5343         cat test > $DIR/$tdir/foo && error "cat test worked"
5344         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5345         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5346         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5347                                         error "link worked"
5348         echo foo >> $DIR/$tdir/foo && error "echo worked"
5349         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5350         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5351         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5352         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5353                                                         error "lsattr"
5354         chattr -i $DIR/$tdir/foo || error "chattr failed"
5355
5356         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5357 }
5358 run_test 52b "immutable flag test (should return errors) ======="
5359
5360 test_53() {
5361         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5362         remote_mds_nodsh && skip "remote MDS with nodsh"
5363         remote_ost_nodsh && skip "remote OST with nodsh"
5364
5365         local param
5366         local param_seq
5367         local ostname
5368         local mds_last
5369         local mds_last_seq
5370         local ost_last
5371         local ost_last_seq
5372         local ost_last_id
5373         local ostnum
5374         local node
5375         local found=false
5376         local support_last_seq=true
5377
5378         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5379                 support_last_seq=false
5380
5381         # only test MDT0000
5382         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5383         local value
5384         for value in $(do_facet $SINGLEMDS \
5385                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5386                 param=$(echo ${value[0]} | cut -d "=" -f1)
5387                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5388
5389                 if $support_last_seq; then
5390                         param_seq=$(echo $param |
5391                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5392                         mds_last_seq=$(do_facet $SINGLEMDS \
5393                                        $LCTL get_param -n $param_seq)
5394                 fi
5395                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5396
5397                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5398                 node=$(facet_active_host ost$((ostnum+1)))
5399                 param="obdfilter.$ostname.last_id"
5400                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5401                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5402                         ost_last_id=$ost_last
5403
5404                         if $support_last_seq; then
5405                                 ost_last_id=$(echo $ost_last |
5406                                               awk -F':' '{print $2}' |
5407                                               sed -e "s/^0x//g")
5408                                 ost_last_seq=$(echo $ost_last |
5409                                                awk -F':' '{print $1}')
5410                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5411                         fi
5412
5413                         if [[ $ost_last_id != $mds_last ]]; then
5414                                 error "$ost_last_id != $mds_last"
5415                         else
5416                                 found=true
5417                                 break
5418                         fi
5419                 done
5420         done
5421         $found || error "can not match last_seq/last_id for $mdtosc"
5422         return 0
5423 }
5424 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5425
5426 test_54a() {
5427         perl -MSocket -e ';' || skip "no Socket perl module installed"
5428
5429         $SOCKETSERVER $DIR/socket ||
5430                 error "$SOCKETSERVER $DIR/socket failed: $?"
5431         $SOCKETCLIENT $DIR/socket ||
5432                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5433         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5434 }
5435 run_test 54a "unix domain socket test =========================="
5436
5437 test_54b() {
5438         f="$DIR/f54b"
5439         mknod $f c 1 3
5440         chmod 0666 $f
5441         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5442 }
5443 run_test 54b "char device works in lustre ======================"
5444
5445 find_loop_dev() {
5446         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5447         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5448         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5449
5450         for i in $(seq 3 7); do
5451                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5452                 LOOPDEV=$LOOPBASE$i
5453                 LOOPNUM=$i
5454                 break
5455         done
5456 }
5457
5458 cleanup_54c() {
5459         local rc=0
5460         loopdev="$DIR/loop54c"
5461
5462         trap 0
5463         $UMOUNT $DIR/$tdir || rc=$?
5464         losetup -d $loopdev || true
5465         losetup -d $LOOPDEV || true
5466         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5467         return $rc
5468 }
5469
5470 test_54c() {
5471         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5472
5473         loopdev="$DIR/loop54c"
5474
5475         find_loop_dev
5476         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5477         trap cleanup_54c EXIT
5478         mknod $loopdev b 7 $LOOPNUM
5479         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5480         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5481         losetup $loopdev $DIR/$tfile ||
5482                 error "can't set up $loopdev for $DIR/$tfile"
5483         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5484         test_mkdir $DIR/$tdir
5485         mount -t ext2 $loopdev $DIR/$tdir ||
5486                 error "error mounting $loopdev on $DIR/$tdir"
5487         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5488                 error "dd write"
5489         df $DIR/$tdir
5490         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5491                 error "dd read"
5492         cleanup_54c
5493 }
5494 run_test 54c "block device works in lustre ====================="
5495
5496 test_54d() {
5497         f="$DIR/f54d"
5498         string="aaaaaa"
5499         mknod $f p
5500         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5501 }
5502 run_test 54d "fifo device works in lustre ======================"
5503
5504 test_54e() {
5505         f="$DIR/f54e"
5506         string="aaaaaa"
5507         cp -aL /dev/console $f
5508         echo $string > $f || error "echo $string to $f failed"
5509 }
5510 run_test 54e "console/tty device works in lustre ======================"
5511
5512 test_56a() {
5513         local numfiles=3
5514         local dir=$DIR/$tdir
5515
5516         rm -rf $dir
5517         test_mkdir -p $dir/dir
5518         for i in $(seq $numfiles); do
5519                 touch $dir/file$i
5520                 touch $dir/dir/file$i
5521         done
5522
5523         local numcomp=$($LFS getstripe --component-count $dir)
5524
5525         [[ $numcomp == 0 ]] && numcomp=1
5526
5527         # test lfs getstripe with --recursive
5528         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5529
5530         [[ $filenum -eq $((numfiles * 2)) ]] ||
5531                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5532         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5533         [[ $filenum -eq $numfiles ]] ||
5534                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5535         echo "$LFS getstripe showed obdidx or l_ost_idx"
5536
5537         # test lfs getstripe with file instead of dir
5538         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5539         [[ $filenum -eq 1 ]] ||
5540                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5541         echo "$LFS getstripe file1 passed"
5542
5543         #test lfs getstripe with --verbose
5544         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5545         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5546                 error "$LFS getstripe --verbose $dir: "\
5547                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5548         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5549                 error "$LFS getstripe $dir: showed lmm_magic"
5550
5551         #test lfs getstripe with -v prints lmm_fid
5552         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5553         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5554                 error "$LFS getstripe -v $dir: "\
5555                       "got $filenum want $((numfiles * numcomp)) lmm_fid"
5556         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5557                 error "$LFS getstripe $dir: showed lmm_fid by default"
5558         echo "$LFS getstripe --verbose passed"
5559
5560         #check for FID information
5561         local fid1=$($LFS getstripe --fid $dir/file1)
5562         local fid2=$($LFS getstripe --verbose $dir/file1 |
5563                      awk '/lmm_fid: / { print $2; exit; }')
5564         local fid3=$($LFS path2fid $dir/file1)
5565
5566         [ "$fid1" != "$fid2" ] &&
5567                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5568         [ "$fid1" != "$fid3" ] &&
5569                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5570         echo "$LFS getstripe --fid passed"
5571
5572         #test lfs getstripe with --obd
5573         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
5574                 error "$LFS getstripe --obd wrong_uuid: should return error"
5575
5576         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5577
5578         local ostidx=1
5579         local obduuid=$(ostuuid_from_index $ostidx)
5580         local found=$($LFS getstripe -r --obd $obduuid $dir |
5581                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
5582
5583         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
5584         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
5585                 ((filenum--))
5586         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
5587                 ((filenum--))
5588
5589         [[ $found -eq $filenum ]] ||
5590                 error "$LFS getstripe --obd: found $found expect $filenum"
5591         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
5592                 sed '/^[         ]*'${ostidx}'[  ]/d' |
5593                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
5594                 error "$LFS getstripe --obd: should not show file on other obd"
5595         echo "$LFS getstripe --obd passed"
5596 }
5597 run_test 56a "check $LFS getstripe"
5598
5599 test_56b() {
5600         local dir=$DIR/$tdir
5601         local numdirs=3
5602
5603         test_mkdir $dir
5604         for i in $(seq $numdirs); do
5605                 test_mkdir $dir/dir$i
5606         done
5607
5608         # test lfs getdirstripe default mode is non-recursion, which is
5609         # different from lfs getstripe
5610         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
5611
5612         [[ $dircnt -eq 1 ]] ||
5613                 error "$LFS getdirstripe: found $dircnt, not 1"
5614         dircnt=$($LFS getdirstripe --recursive $dir |
5615                 grep -c lmv_stripe_count)
5616         [[ $dircnt -eq $((numdirs + 1)) ]] ||
5617                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
5618 }
5619 run_test 56b "check $LFS getdirstripe"
5620
5621 test_56c() {
5622         remote_ost_nodsh && skip "remote OST with nodsh"
5623
5624         local ost_idx=0
5625         local ost_name=$(ostname_from_index $ost_idx)
5626         local old_status=$(ost_dev_status $ost_idx)
5627
5628         [[ -z "$old_status" ]] ||
5629                 skip_env "OST $ost_name is in $old_status status"
5630
5631         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
5632         [[ $OST1_VERSION -ge $(version_code 2.12.55) ]] && do_facet ost1 \
5633                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
5634         sleep_maxage
5635
5636         local new_status=$(ost_dev_status $ost_idx)
5637
5638         [[ "$new_status" =~ "D" ]] ||
5639                 error "$ost_name status is '$new_status', missing 'D'"
5640         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
5641                 [[ "$new_status" =~ "N" ]] ||
5642                         error "$ost_name status is '$new_status', missing 'N'"
5643         fi
5644
5645         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
5646         [[ $OST1_VERSION -ge $(version_code 2.12.55) ]] && do_facet ost1 \
5647                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
5648         sleep_maxage
5649
5650         new_status=$(ost_dev_status $ost_idx)
5651         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
5652                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
5653 }
5654 run_test 56c "check 'lfs df' showing device status"
5655
5656 NUMFILES=3
5657 NUMDIRS=3
5658 setup_56() {
5659         local local_tdir="$1"
5660         local local_numfiles="$2"
5661         local local_numdirs="$3"
5662         local dir_params="$4"
5663         local dir_stripe_params="$5"
5664
5665         if [ ! -d "$local_tdir" ] ; then
5666                 test_mkdir -p $dir_stripe_params $local_tdir
5667                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
5668                 for i in $(seq $local_numfiles) ; do
5669                         touch $local_tdir/file$i
5670                 done
5671                 for i in $(seq $local_numdirs) ; do
5672                         test_mkdir $dir_stripe_params $local_tdir/dir$i
5673                         for j in $(seq $local_numfiles) ; do
5674                                 touch $local_tdir/dir$i/file$j
5675                         done
5676                 done
5677         fi
5678 }
5679
5680 setup_56_special() {
5681         local local_tdir=$1
5682         local local_numfiles=$2
5683         local local_numdirs=$3
5684
5685         setup_56 $local_tdir $local_numfiles $local_numdirs
5686
5687         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
5688                 for i in $(seq $local_numfiles) ; do
5689                         mknod $local_tdir/loop${i}b b 7 $i
5690                         mknod $local_tdir/null${i}c c 1 3
5691                         ln -s $local_tdir/file1 $local_tdir/link${i}
5692                 done
5693                 for i in $(seq $local_numdirs) ; do
5694                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
5695                         mknod $local_tdir/dir$i/null${i}c c 1 3
5696                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
5697                 done
5698         fi
5699 }
5700
5701 test_56g() {
5702         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5703         local expected=$(($NUMDIRS + 2))
5704
5705         setup_56 $dir $NUMFILES $NUMDIRS
5706
5707         # test lfs find with -name
5708         for i in $(seq $NUMFILES) ; do
5709                 local nums=$($LFS find -name "*$i" $dir | wc -l)
5710
5711                 [ $nums -eq $expected ] ||
5712                         error "lfs find -name '*$i' $dir wrong: "\
5713                               "found $nums, expected $expected"
5714         done
5715 }
5716 run_test 56g "check lfs find -name"
5717
5718 test_56h() {
5719         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5720         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
5721
5722         setup_56 $dir $NUMFILES $NUMDIRS
5723
5724         # test lfs find with ! -name
5725         for i in $(seq $NUMFILES) ; do
5726                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
5727
5728                 [ $nums -eq $expected ] ||
5729                         error "lfs find ! -name '*$i' $dir wrong: "\
5730                               "found $nums, expected $expected"
5731         done
5732 }
5733 run_test 56h "check lfs find ! -name"
5734
5735 test_56i() {
5736         local dir=$DIR/$tdir
5737
5738         test_mkdir $dir
5739
5740         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
5741         local out=$($cmd)
5742
5743         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
5744 }
5745 run_test 56i "check 'lfs find -ost UUID' skips directories"
5746
5747 test_56j() {
5748         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5749
5750         setup_56_special $dir $NUMFILES $NUMDIRS
5751
5752         local expected=$((NUMDIRS + 1))
5753         local cmd="$LFS find -type d $dir"
5754         local nums=$($cmd | wc -l)
5755
5756         [ $nums -eq $expected ] ||
5757                 error "'$cmd' wrong: found $nums, expected $expected"
5758 }
5759 run_test 56j "check lfs find -type d"
5760
5761 test_56k() {
5762         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5763
5764         setup_56_special $dir $NUMFILES $NUMDIRS
5765
5766         local expected=$(((NUMDIRS + 1) * NUMFILES))
5767         local cmd="$LFS find -type f $dir"
5768         local nums=$($cmd | wc -l)
5769
5770         [ $nums -eq $expected ] ||
5771                 error "'$cmd' wrong: found $nums, expected $expected"
5772 }
5773 run_test 56k "check lfs find -type f"
5774
5775 test_56l() {
5776         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5777
5778         setup_56_special $dir $NUMFILES $NUMDIRS
5779
5780         local expected=$((NUMDIRS + NUMFILES))
5781         local cmd="$LFS find -type b $dir"
5782         local nums=$($cmd | wc -l)
5783
5784         [ $nums -eq $expected ] ||
5785                 error "'$cmd' wrong: found $nums, expected $expected"
5786 }
5787 run_test 56l "check lfs find -type b"
5788
5789 test_56m() {
5790         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5791
5792         setup_56_special $dir $NUMFILES $NUMDIRS
5793
5794         local expected=$((NUMDIRS + NUMFILES))
5795         local cmd="$LFS find -type c $dir"
5796         local nums=$($cmd | wc -l)
5797         [ $nums -eq $expected ] ||
5798                 error "'$cmd' wrong: found $nums, expected $expected"
5799 }
5800 run_test 56m "check lfs find -type c"
5801
5802 test_56n() {
5803         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5804         setup_56_special $dir $NUMFILES $NUMDIRS
5805
5806         local expected=$((NUMDIRS + NUMFILES))
5807         local cmd="$LFS find -type l $dir"
5808         local nums=$($cmd | wc -l)
5809
5810         [ $nums -eq $expected ] ||
5811                 error "'$cmd' wrong: found $nums, expected $expected"
5812 }
5813 run_test 56n "check lfs find -type l"
5814
5815 test_56o() {
5816         local dir=$DIR/$tdir
5817
5818         setup_56 $dir $NUMFILES $NUMDIRS
5819         utime $dir/file1 > /dev/null || error "utime (1)"
5820         utime $dir/file2 > /dev/null || error "utime (2)"
5821         utime $dir/dir1 > /dev/null || error "utime (3)"
5822         utime $dir/dir2 > /dev/null || error "utime (4)"
5823         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
5824         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
5825
5826         local expected=4
5827         local nums=$($LFS find -mtime +0 $dir | wc -l)
5828
5829         [ $nums -eq $expected ] ||
5830                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
5831
5832         expected=12
5833         cmd="$LFS find -mtime 0 $dir"
5834         nums=$($cmd | wc -l)
5835         [ $nums -eq $expected ] ||
5836                 error "'$cmd' wrong: found $nums, expected $expected"
5837 }
5838 run_test 56o "check lfs find -mtime for old files"
5839
5840 test_56ob() {
5841         local dir=$DIR/$tdir
5842         local expected=1
5843         local count=0
5844
5845         # just to make sure there is something that won't be found
5846         test_mkdir $dir
5847         touch $dir/$tfile.now
5848
5849         for age in year week day hour min; do
5850                 count=$((count + 1))
5851
5852                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
5853                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
5854                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
5855
5856                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
5857                 local nums=$($cmd | wc -l)
5858                 [ $nums -eq $expected ] ||
5859                         error "'$cmd' wrong: found $nums, expected $expected"
5860
5861                 cmd="$LFS find $dir -atime $count${age:0:1}"
5862                 nums=$($cmd | wc -l)
5863                 [ $nums -eq $expected ] ||
5864                         error "'$cmd' wrong: found $nums, expected $expected"
5865         done
5866
5867         sleep 2
5868         cmd="$LFS find $dir -ctime +1s -type f"
5869         nums=$($cmd | wc -l)
5870         (( $nums == $count * 2 + 1)) ||
5871                 error "'$cmd' wrong: found $nums, expected $((expected*2+1))"
5872 }
5873 run_test 56ob "check lfs find -atime -mtime -ctime with units"
5874
5875 test_newerXY_base() {
5876         local x=$1
5877         local y=$2
5878         local dir=$DIR/$tdir
5879         local ref
5880         local negref
5881
5882         if [ $y == "t" ]; then
5883                 ref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
5884         else
5885                 ref=$DIR/$tfile.newer
5886                 touch $ref || error "touch $ref failed"
5887         fi
5888         sleep 2
5889         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
5890         sleep 2
5891         if [ $y == "t" ]; then
5892                 negref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
5893         else
5894                 negref=$DIR/$tfile.newerneg
5895                 touch $negref || error "touch $negref failed"
5896         fi
5897
5898         local cmd="$LFS find $dir -newer$x$y $ref"
5899         local nums=$(eval $cmd | wc -l)
5900         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
5901
5902         [ $nums -eq $expected ] ||
5903                 error "'$cmd' wrong: found $nums, expected $expected"
5904
5905         cmd="$LFS find $dir ! -newer$x$y $negref"
5906         nums=$(eval $cmd | wc -l)
5907         [ $nums -eq $expected ] ||
5908                 error "'$cmd' wrong: found $nums, expected $expected"
5909
5910         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
5911         nums=$(eval $cmd | wc -l)
5912         [ $nums -eq $expected ] ||
5913                 error "'$cmd' wrong: found $nums, expected $expected"
5914
5915         rm -rf $DIR/*
5916 }
5917
5918 test_56oc() {
5919         test_newerXY_base "a" "a"
5920         test_newerXY_base "a" "m"
5921         test_newerXY_base "a" "c"
5922         test_newerXY_base "m" "a"
5923         test_newerXY_base "m" "m"
5924         test_newerXY_base "m" "c"
5925         test_newerXY_base "c" "a"
5926         test_newerXY_base "c" "m"
5927         test_newerXY_base "c" "c"
5928         test_newerXY_base "a" "t"
5929         test_newerXY_base "m" "t"
5930         test_newerXY_base "c" "t"
5931 }
5932 run_test 56oc "check lfs find -newerXY work"
5933
5934 test_56p() {
5935         [ $RUNAS_ID -eq $UID ] &&
5936                 skip_env "RUNAS_ID = UID = $UID -- skipping"
5937
5938         local dir=$DIR/$tdir
5939
5940         setup_56 $dir $NUMFILES $NUMDIRS
5941         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
5942
5943         local expected=$NUMFILES
5944         local cmd="$LFS find -uid $RUNAS_ID $dir"
5945         local nums=$($cmd | wc -l)
5946
5947         [ $nums -eq $expected ] ||
5948                 error "'$cmd' wrong: found $nums, expected $expected"
5949
5950         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
5951         cmd="$LFS find ! -uid $RUNAS_ID $dir"
5952         nums=$($cmd | wc -l)
5953         [ $nums -eq $expected ] ||
5954                 error "'$cmd' wrong: found $nums, expected $expected"
5955 }
5956 run_test 56p "check lfs find -uid and ! -uid"
5957
5958 test_56q() {
5959         [ $RUNAS_ID -eq $UID ] &&
5960                 skip_env "RUNAS_ID = UID = $UID -- skipping"
5961
5962         local dir=$DIR/$tdir
5963
5964         setup_56 $dir $NUMFILES $NUMDIRS
5965         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
5966
5967         local expected=$NUMFILES
5968         local cmd="$LFS find -gid $RUNAS_GID $dir"
5969         local nums=$($cmd | wc -l)
5970
5971         [ $nums -eq $expected ] ||
5972                 error "'$cmd' wrong: found $nums, expected $expected"
5973
5974         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
5975         cmd="$LFS find ! -gid $RUNAS_GID $dir"
5976         nums=$($cmd | wc -l)
5977         [ $nums -eq $expected ] ||
5978                 error "'$cmd' wrong: found $nums, expected $expected"
5979 }
5980 run_test 56q "check lfs find -gid and ! -gid"
5981
5982 test_56r() {
5983         local dir=$DIR/$tdir
5984
5985         setup_56 $dir $NUMFILES $NUMDIRS
5986
5987         local expected=12
5988         local cmd="$LFS find -size 0 -type f -lazy $dir"
5989         local nums=$($cmd | wc -l)
5990
5991         [ $nums -eq $expected ] ||
5992                 error "'$cmd' wrong: found $nums, expected $expected"
5993         cmd="$LFS find -size 0 -type f $dir"
5994         nums=$($cmd | wc -l)
5995         [ $nums -eq $expected ] ||
5996                 error "'$cmd' wrong: found $nums, expected $expected"
5997
5998         expected=0
5999         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6000         nums=$($cmd | wc -l)
6001         [ $nums -eq $expected ] ||
6002                 error "'$cmd' wrong: found $nums, expected $expected"
6003         cmd="$LFS find ! -size 0 -type f $dir"
6004         nums=$($cmd | wc -l)
6005         [ $nums -eq $expected ] ||
6006                 error "'$cmd' wrong: found $nums, expected $expected"
6007
6008         echo "test" > $dir/$tfile
6009         echo "test2" > $dir/$tfile.2 && sync
6010         expected=1
6011         cmd="$LFS find -size 5 -type f -lazy $dir"
6012         nums=$($cmd | wc -l)
6013         [ $nums -eq $expected ] ||
6014                 error "'$cmd' wrong: found $nums, expected $expected"
6015         cmd="$LFS find -size 5 -type f $dir"
6016         nums=$($cmd | wc -l)
6017         [ $nums -eq $expected ] ||
6018                 error "'$cmd' wrong: found $nums, expected $expected"
6019
6020         expected=1
6021         cmd="$LFS find -size +5 -type f -lazy $dir"
6022         nums=$($cmd | wc -l)
6023         [ $nums -eq $expected ] ||
6024                 error "'$cmd' wrong: found $nums, expected $expected"
6025         cmd="$LFS find -size +5 -type f $dir"
6026         nums=$($cmd | wc -l)
6027         [ $nums -eq $expected ] ||
6028                 error "'$cmd' wrong: found $nums, expected $expected"
6029
6030         expected=2
6031         cmd="$LFS find -size +0 -type f -lazy $dir"
6032         nums=$($cmd | wc -l)
6033         [ $nums -eq $expected ] ||
6034                 error "'$cmd' wrong: found $nums, expected $expected"
6035         cmd="$LFS find -size +0 -type f $dir"
6036         nums=$($cmd | wc -l)
6037         [ $nums -eq $expected ] ||
6038                 error "'$cmd' wrong: found $nums, expected $expected"
6039
6040         expected=2
6041         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6042         nums=$($cmd | wc -l)
6043         [ $nums -eq $expected ] ||
6044                 error "'$cmd' wrong: found $nums, expected $expected"
6045         cmd="$LFS find ! -size -5 -type f $dir"
6046         nums=$($cmd | wc -l)
6047         [ $nums -eq $expected ] ||
6048                 error "'$cmd' wrong: found $nums, expected $expected"
6049
6050         expected=12
6051         cmd="$LFS find -size -5 -type f -lazy $dir"
6052         nums=$($cmd | wc -l)
6053         [ $nums -eq $expected ] ||
6054                 error "'$cmd' wrong: found $nums, expected $expected"
6055         cmd="$LFS find -size -5 -type f $dir"
6056         nums=$($cmd | wc -l)
6057         [ $nums -eq $expected ] ||
6058                 error "'$cmd' wrong: found $nums, expected $expected"
6059 }
6060 run_test 56r "check lfs find -size works"
6061
6062 test_56ra() {
6063         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6064                 skip "MDS < 2.12.58 doesn't return LSOM data"
6065         local dir=$DIR/$tdir
6066
6067         [[ $OSC == "mdc" ]] && skip "DoM files" && return
6068
6069         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6070
6071         cancel_lru_locks $OSC
6072
6073         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6074         local expected=12
6075         local cmd="$LFS find -size 0 -type f -lazy $dir"
6076         local nums=$($cmd | wc -l)
6077
6078         [ $nums -eq $expected ] ||
6079                 error "'$cmd' wrong: found $nums, expected $expected"
6080
6081         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6082         [ $rpcs_before -eq $rpcs_after ] ||
6083                 error "'$cmd' should not send glimpse RPCs to OST"
6084         cmd="$LFS find -size 0 -type f $dir"
6085         nums=$($cmd | wc -l)
6086         [ $nums -eq $expected ] ||
6087                 error "'$cmd' wrong: found $nums, expected $expected"
6088         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6089         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6090         $LCTL get_param osc.*.stats
6091         [ $rpcs_after -eq $((rpcs_before + 12)) ] ||
6092                 error "'$cmd' should send 12 glimpse RPCs to OST"
6093
6094         cancel_lru_locks $OSC
6095         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6096         expected=0
6097         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6098         nums=$($cmd | wc -l)
6099         [ $nums -eq $expected ] ||
6100                 error "'$cmd' wrong: found $nums, expected $expected"
6101         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6102         $LCTL get_param mdc.*.stats
6103         [ $rpcs_before -eq $rpcs_after ] ||
6104                 error "'$cmd' should not send glimpse RPCs to OST"
6105         cmd="$LFS find ! -size 0 -type f $dir"
6106         nums=$($cmd | wc -l)
6107         [ $nums -eq $expected ] ||
6108                 error "'$cmd' wrong: found $nums, expected $expected"
6109         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6110         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6111         [ $rpcs_after -eq $((rpcs_before + 12)) ] ||
6112                 error "'$cmd' should send 12 glimpse RPCs to OST"
6113
6114         echo "test" > $dir/$tfile
6115         echo "test2" > $dir/$tfile.2 && sync
6116         cancel_lru_locks $OSC
6117         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6118         expected=1
6119         cmd="$LFS find -size 5 -type f -lazy $dir"
6120         nums=$($cmd | wc -l)
6121         [ $nums -eq $expected ] ||
6122                 error "'$cmd' wrong: found $nums, expected $expected"
6123         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6124         [ $rpcs_before -eq $rpcs_after ] ||
6125                 error "'$cmd' should not send glimpse RPCs to OST"
6126         cmd="$LFS find -size 5 -type f $dir"
6127         nums=$($cmd | wc -l)
6128         [ $nums -eq $expected ] ||
6129                 error "'$cmd' wrong: found $nums, expected $expected"
6130         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6131         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6132         [ $rpcs_after -eq $((rpcs_before + 14)) ] ||
6133                 error "'$cmd' should send 14 glimpse RPCs to OST"
6134
6135         cancel_lru_locks $OSC
6136         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6137         expected=1
6138         cmd="$LFS find -size +5 -type f -lazy $dir"
6139         nums=$($cmd | wc -l)
6140         [ $nums -eq $expected ] ||
6141                 error "'$cmd' wrong: found $nums, expected $expected"
6142         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6143         [ $rpcs_before -eq $rpcs_after ] ||
6144                 error "'$cmd' should not send glimpse RPCs to OST"
6145         cmd="$LFS find -size +5 -type f $dir"
6146         nums=$($cmd | wc -l)
6147         [ $nums -eq $expected ] ||
6148                 error "'$cmd' wrong: found $nums, expected $expected"
6149         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6150         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6151         [ $rpcs_after -eq $((rpcs_before + 14)) ] ||
6152                 error "'$cmd' should send 14 glimpse RPCs to OST"
6153
6154         cancel_lru_locks $OSC
6155         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6156         expected=2
6157         cmd="$LFS find -size +0 -type f -lazy $dir"
6158         nums=$($cmd | wc -l)
6159         [ $nums -eq $expected ] ||
6160                 error "'$cmd' wrong: found $nums, expected $expected"
6161         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6162         [ $rpcs_before -eq $rpcs_after ] ||
6163                 error "'$cmd' should not send glimpse RPCs to OST"
6164         cmd="$LFS find -size +0 -type f $dir"
6165         nums=$($cmd | wc -l)
6166         [ $nums -eq $expected ] ||
6167                 error "'$cmd' wrong: found $nums, expected $expected"
6168         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6169         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6170         [ $rpcs_after -eq $((rpcs_before + 14)) ] ||
6171                 error "'$cmd' should send 14 glimpse RPCs to OST"
6172
6173         cancel_lru_locks $OSC
6174         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6175         expected=2
6176         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6177         nums=$($cmd | wc -l)
6178         [ $nums -eq $expected ] ||
6179                 error "'$cmd' wrong: found $nums, expected $expected"
6180         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6181         [ $rpcs_before -eq $rpcs_after ] ||
6182                 error "'$cmd' should not send glimpse RPCs to OST"
6183         cmd="$LFS find ! -size -5 -type f $dir"
6184         nums=$($cmd | wc -l)
6185         [ $nums -eq $expected ] ||
6186                 error "'$cmd' wrong: found $nums, expected $expected"
6187         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6188         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6189         [ $rpcs_after -eq $((rpcs_before + 14)) ] ||
6190                 error "'$cmd' should send 14 glimpse RPCs to OST"
6191
6192         cancel_lru_locks $OSC
6193         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6194         expected=12
6195         cmd="$LFS find -size -5 -type f -lazy $dir"
6196         nums=$($cmd | wc -l)
6197         [ $nums -eq $expected ] ||
6198                 error "'$cmd' wrong: found $nums, expected $expected"
6199         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6200         [ $rpcs_before -eq $rpcs_after ] ||
6201                 error "'$cmd' should not send glimpse RPCs to OST"
6202         cmd="$LFS find -size -5 -type f $dir"
6203         nums=$($cmd | wc -l)
6204         [ $nums -eq $expected ] ||
6205                 error "'$cmd' wrong: found $nums, expected $expected"
6206         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6207         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6208         [ $rpcs_after -eq $((rpcs_before + 14)) ] ||
6209                 error "'$cmd' should send 14 glimpse RPCs to OST"
6210 }
6211 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6212
6213 test_56rb() {
6214         local dir=$DIR/$tdir
6215         local tmp=$TMP/$tfile.log
6216         local mdt_idx;
6217
6218         test_mkdir -p $dir || error "failed to mkdir $dir"
6219         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6220                 error "failed to setstripe $dir/$tfile"
6221         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6222
6223         stack_trap "rm -f $tmp" EXIT
6224         $LFS find --size +100K --ost 0 $dir 2>&1 | tee $tmp
6225         [ -z "$(cat $tmp | grep "obd_uuid: ")" ] ||
6226                 error "failed to find --size +100K --ost 0 $dir"
6227         $LFS find --size +100K --mdt $mdt_idx $dir 2>&1 | tee $tmp
6228         [ -z "$(cat $tmp | grep "obd_uuid: ")" ] ||
6229                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6230 }
6231 run_test 56rb "check lfs find --size --ost/--mdt works"
6232
6233 test_56s() { # LU-611 #LU-9369
6234         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6235
6236         local dir=$DIR/$tdir
6237         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6238
6239         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6240         for i in $(seq $NUMDIRS); do
6241                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6242         done
6243
6244         local expected=$NUMDIRS
6245         local cmd="$LFS find -c $OSTCOUNT $dir"
6246         local nums=$($cmd | wc -l)
6247
6248         [ $nums -eq $expected ] || {
6249                 $LFS getstripe -R $dir
6250                 error "'$cmd' wrong: found $nums, expected $expected"
6251         }
6252
6253         expected=$((NUMDIRS + onestripe))
6254         cmd="$LFS find -stripe-count +0 -type f $dir"
6255         nums=$($cmd | wc -l)
6256         [ $nums -eq $expected ] || {
6257                 $LFS getstripe -R $dir
6258                 error "'$cmd' wrong: found $nums, expected $expected"
6259         }
6260
6261         expected=$onestripe
6262         cmd="$LFS find -stripe-count 1 -type f $dir"
6263         nums=$($cmd | wc -l)
6264         [ $nums -eq $expected ] || {
6265                 $LFS getstripe -R $dir
6266                 error "'$cmd' wrong: found $nums, expected $expected"
6267         }
6268
6269         cmd="$LFS find -stripe-count -2 -type f $dir"
6270         nums=$($cmd | wc -l)
6271         [ $nums -eq $expected ] || {
6272                 $LFS getstripe -R $dir
6273                 error "'$cmd' wrong: found $nums, expected $expected"
6274         }
6275
6276         expected=0
6277         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6278         nums=$($cmd | wc -l)
6279         [ $nums -eq $expected ] || {
6280                 $LFS getstripe -R $dir
6281                 error "'$cmd' wrong: found $nums, expected $expected"
6282         }
6283 }
6284 run_test 56s "check lfs find -stripe-count works"
6285
6286 test_56t() { # LU-611 #LU-9369
6287         local dir=$DIR/$tdir
6288
6289         setup_56 $dir 0 $NUMDIRS
6290         for i in $(seq $NUMDIRS); do
6291                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6292         done
6293
6294         local expected=$NUMDIRS
6295         local cmd="$LFS find -S 8M $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         rm -rf $dir
6303
6304         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6305
6306         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6307
6308         expected=$(((NUMDIRS + 1) * NUMFILES))
6309         cmd="$LFS find -stripe-size 512k -type f $dir"
6310         nums=$($cmd | wc -l)
6311         [ $nums -eq $expected ] ||
6312                 error "'$cmd' wrong: found $nums, expected $expected"
6313
6314         cmd="$LFS find -stripe-size +320k -type f $dir"
6315         nums=$($cmd | wc -l)
6316         [ $nums -eq $expected ] ||
6317                 error "'$cmd' wrong: found $nums, expected $expected"
6318
6319         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6320         cmd="$LFS find -stripe-size +200k -type f $dir"
6321         nums=$($cmd | wc -l)
6322         [ $nums -eq $expected ] ||
6323                 error "'$cmd' wrong: found $nums, expected $expected"
6324
6325         cmd="$LFS find -stripe-size -640k -type f $dir"
6326         nums=$($cmd | wc -l)
6327         [ $nums -eq $expected ] ||
6328                 error "'$cmd' wrong: found $nums, expected $expected"
6329
6330         expected=4
6331         cmd="$LFS find -stripe-size 256k -type f $dir"
6332         nums=$($cmd | wc -l)
6333         [ $nums -eq $expected ] ||
6334                 error "'$cmd' wrong: found $nums, expected $expected"
6335
6336         cmd="$LFS find -stripe-size -320k -type f $dir"
6337         nums=$($cmd | wc -l)
6338         [ $nums -eq $expected ] ||
6339                 error "'$cmd' wrong: found $nums, expected $expected"
6340
6341         expected=0
6342         cmd="$LFS find -stripe-size 1024k -type f $dir"
6343         nums=$($cmd | wc -l)
6344         [ $nums -eq $expected ] ||
6345                 error "'$cmd' wrong: found $nums, expected $expected"
6346 }
6347 run_test 56t "check lfs find -stripe-size works"
6348
6349 test_56u() { # LU-611
6350         local dir=$DIR/$tdir
6351
6352         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6353
6354         if [[ $OSTCOUNT -gt 1 ]]; then
6355                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6356                 onestripe=4
6357         else
6358                 onestripe=0
6359         fi
6360
6361         local expected=$(((NUMDIRS + 1) * NUMFILES))
6362         local cmd="$LFS find -stripe-index 0 -type f $dir"
6363         local nums=$($cmd | wc -l)
6364
6365         [ $nums -eq $expected ] ||
6366                 error "'$cmd' wrong: found $nums, expected $expected"
6367
6368         expected=$onestripe
6369         cmd="$LFS find -stripe-index 1 -type f $dir"
6370         nums=$($cmd | wc -l)
6371         [ $nums -eq $expected ] ||
6372                 error "'$cmd' wrong: found $nums, expected $expected"
6373
6374         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6375         nums=$($cmd | wc -l)
6376         [ $nums -eq $expected ] ||
6377                 error "'$cmd' wrong: found $nums, expected $expected"
6378
6379         expected=0
6380         # This should produce an error and not return any files
6381         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
6382         nums=$($cmd 2>/dev/null | wc -l)
6383         [ $nums -eq $expected ] ||
6384                 error "'$cmd' wrong: found $nums, expected $expected"
6385
6386         if [[ $OSTCOUNT -gt 1 ]]; then
6387                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
6388                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
6389                 nums=$($cmd | wc -l)
6390                 [ $nums -eq $expected ] ||
6391                         error "'$cmd' wrong: found $nums, expected $expected"
6392         fi
6393 }
6394 run_test 56u "check lfs find -stripe-index works"
6395
6396 test_56v() {
6397         local mdt_idx=0
6398         local dir=$DIR/$tdir
6399
6400         setup_56 $dir $NUMFILES $NUMDIRS
6401
6402         UUID=$(mdtuuid_from_index $mdt_idx $dir)
6403         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
6404
6405         for file in $($LFS find -m $UUID $dir); do
6406                 file_midx=$($LFS getstripe -m $file)
6407                 [ $file_midx -eq $mdt_idx ] ||
6408                         error "lfs find -m $UUID != getstripe -m $file_midx"
6409         done
6410 }
6411 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
6412
6413 test_56w() {
6414         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6415         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6416
6417         local dir=$DIR/$tdir
6418
6419         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
6420
6421         local stripe_size=$($LFS getstripe -S -d $dir) ||
6422                 error "$LFS getstripe -S -d $dir failed"
6423         stripe_size=${stripe_size%% *}
6424
6425         local file_size=$((stripe_size * OSTCOUNT))
6426         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
6427         local required_space=$((file_num * file_size))
6428         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
6429                            head -n1)
6430         [[ $free_space -le $((required_space / 1024)) ]] &&
6431                 skip_env "need $required_space, have $free_space kbytes"
6432
6433         local dd_bs=65536
6434         local dd_count=$((file_size / dd_bs))
6435
6436         # write data into the files
6437         local i
6438         local j
6439         local file
6440
6441         for i in $(seq $NUMFILES); do
6442                 file=$dir/file$i
6443                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6444                         error "write data into $file failed"
6445         done
6446         for i in $(seq $NUMDIRS); do
6447                 for j in $(seq $NUMFILES); do
6448                         file=$dir/dir$i/file$j
6449                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6450                                 error "write data into $file failed"
6451                 done
6452         done
6453
6454         # $LFS_MIGRATE will fail if hard link migration is unsupported
6455         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
6456                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
6457                         error "creating links to $dir/dir1/file1 failed"
6458         fi
6459
6460         local expected=-1
6461
6462         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
6463
6464         # lfs_migrate file
6465         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
6466
6467         echo "$cmd"
6468         eval $cmd || error "$cmd failed"
6469
6470         check_stripe_count $dir/file1 $expected
6471
6472         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
6473         then
6474                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
6475                 # OST 1 if it is on OST 0. This file is small enough to
6476                 # be on only one stripe.
6477                 file=$dir/migr_1_ost
6478                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
6479                         error "write data into $file failed"
6480                 local obdidx=$($LFS getstripe -i $file)
6481                 local oldmd5=$(md5sum $file)
6482                 local newobdidx=0
6483
6484                 [[ $obdidx -eq 0 ]] && newobdidx=1
6485                 cmd="$LFS migrate -i $newobdidx $file"
6486                 echo $cmd
6487                 eval $cmd || error "$cmd failed"
6488
6489                 local realobdix=$($LFS getstripe -i $file)
6490                 local newmd5=$(md5sum $file)
6491
6492                 [[ $newobdidx -ne $realobdix ]] &&
6493                         error "new OST is different (was=$obdidx, "\
6494                               "wanted=$newobdidx, got=$realobdix)"
6495                 [[ "$oldmd5" != "$newmd5" ]] &&
6496                         error "md5sum differ: $oldmd5, $newmd5"
6497         fi
6498
6499         # lfs_migrate dir
6500         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
6501         echo "$cmd"
6502         eval $cmd || error "$cmd failed"
6503
6504         for j in $(seq $NUMFILES); do
6505                 check_stripe_count $dir/dir1/file$j $expected
6506         done
6507
6508         # lfs_migrate works with lfs find
6509         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
6510              $LFS_MIGRATE -y -c $expected"
6511         echo "$cmd"
6512         eval $cmd || error "$cmd failed"
6513
6514         for i in $(seq 2 $NUMFILES); do
6515                 check_stripe_count $dir/file$i $expected
6516         done
6517         for i in $(seq 2 $NUMDIRS); do
6518                 for j in $(seq $NUMFILES); do
6519                 check_stripe_count $dir/dir$i/file$j $expected
6520                 done
6521         done
6522 }
6523 run_test 56w "check lfs_migrate -c stripe_count works"
6524
6525 test_56wb() {
6526         local file1=$DIR/$tdir/file1
6527         local create_pool=false
6528         local initial_pool=$($LFS getstripe -p $DIR)
6529         local pool_list=()
6530         local pool=""
6531
6532         echo -n "Creating test dir..."
6533         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6534         echo "done."
6535
6536         echo -n "Creating test file..."
6537         touch $file1 || error "cannot create file"
6538         echo "done."
6539
6540         echo -n "Detecting existing pools..."
6541         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
6542
6543         if [ ${#pool_list[@]} -gt 0 ]; then
6544                 echo "${pool_list[@]}"
6545                 for thispool in "${pool_list[@]}"; do
6546                         if [[ -z "$initial_pool" ||
6547                               "$initial_pool" != "$thispool" ]]; then
6548                                 pool="$thispool"
6549                                 echo "Using existing pool '$pool'"
6550                                 break
6551                         fi
6552                 done
6553         else
6554                 echo "none detected."
6555         fi
6556         if [ -z "$pool" ]; then
6557                 pool=${POOL:-testpool}
6558                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
6559                 echo -n "Creating pool '$pool'..."
6560                 create_pool=true
6561                 pool_add $pool &> /dev/null ||
6562                         error "pool_add failed"
6563                 echo "done."
6564
6565                 echo -n "Adding target to pool..."
6566                 pool_add_targets $pool 0 0 1 &> /dev/null ||
6567                         error "pool_add_targets failed"
6568                 echo "done."
6569         fi
6570
6571         echo -n "Setting pool using -p option..."
6572         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
6573                 error "migrate failed rc = $?"
6574         echo "done."
6575
6576         echo -n "Verifying test file is in pool after migrating..."
6577         [ "$($LFS getstripe -p $file1)" = $pool ] ||
6578                 error "file was not migrated to pool $pool"
6579         echo "done."
6580
6581         echo -n "Removing test file from pool '$pool'..."
6582         # "lfs migrate $file" won't remove the file from the pool
6583         # until some striping information is changed.
6584         $LFS migrate -c 1 $file1 &> /dev/null ||
6585                 error "cannot remove from pool"
6586         [ "$($LFS getstripe -p $file1)" ] &&
6587                 error "pool still set"
6588         echo "done."
6589
6590         echo -n "Setting pool using --pool option..."
6591         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
6592                 error "migrate failed rc = $?"
6593         echo "done."
6594
6595         # Clean up
6596         rm -f $file1
6597         if $create_pool; then
6598                 destroy_test_pools 2> /dev/null ||
6599                         error "destroy test pools failed"
6600         fi
6601 }
6602 run_test 56wb "check lfs_migrate pool support"
6603
6604 test_56wc() {
6605         local file1="$DIR/$tdir/file1"
6606         local parent_ssize
6607         local parent_scount
6608         local cur_ssize
6609         local cur_scount
6610         local orig_ssize
6611
6612         echo -n "Creating test dir..."
6613         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6614         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
6615                 error "cannot set stripe by '-S 1M -c 1'"
6616         echo "done"
6617
6618         echo -n "Setting initial stripe for test file..."
6619         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
6620                 error "cannot set stripe"
6621         cur_ssize=$($LFS getstripe -S "$file1")
6622         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
6623         echo "done."
6624
6625         # File currently set to -S 512K -c 1
6626
6627         # Ensure -c and -S options are rejected when -R is set
6628         echo -n "Verifying incompatible options are detected..."
6629         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
6630                 error "incompatible -c and -R options not detected"
6631         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
6632                 error "incompatible -S and -R options not detected"
6633         echo "done."
6634
6635         # Ensure unrecognized options are passed through to 'lfs migrate'
6636         echo -n "Verifying -S option is passed through to lfs migrate..."
6637         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
6638                 error "migration failed"
6639         cur_ssize=$($LFS getstripe -S "$file1")
6640         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
6641         echo "done."
6642
6643         # File currently set to -S 1M -c 1
6644
6645         # Ensure long options are supported
6646         echo -n "Verifying long options supported..."
6647         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
6648                 error "long option without argument not supported"
6649         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
6650                 error "long option with argument not supported"
6651         cur_ssize=$($LFS getstripe -S "$file1")
6652         [ $cur_ssize -eq 524288 ] ||
6653                 error "migrate --stripe-size $cur_ssize != 524288"
6654         echo "done."
6655
6656         # File currently set to -S 512K -c 1
6657
6658         if [ "$OSTCOUNT" -gt 1 ]; then
6659                 echo -n "Verifying explicit stripe count can be set..."
6660                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
6661                         error "migrate failed"
6662                 cur_scount=$($LFS getstripe -c "$file1")
6663                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
6664                 echo "done."
6665         fi
6666
6667         # File currently set to -S 512K -c 1 or -S 512K -c 2
6668
6669         # Ensure parent striping is used if -R is set, and no stripe
6670         # count or size is specified
6671         echo -n "Setting stripe for parent directory..."
6672         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6673                 error "cannot set stripe '-S 2M -c 1'"
6674         echo "done."
6675
6676         echo -n "Verifying restripe option uses parent stripe settings..."
6677         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
6678         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
6679         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
6680                 error "migrate failed"
6681         cur_ssize=$($LFS getstripe -S "$file1")
6682         [ $cur_ssize -eq $parent_ssize ] ||
6683                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
6684         cur_scount=$($LFS getstripe -c "$file1")
6685         [ $cur_scount -eq $parent_scount ] ||
6686                 error "migrate -R stripe_count $cur_scount != $parent_scount"
6687         echo "done."
6688
6689         # File currently set to -S 1M -c 1
6690
6691         # Ensure striping is preserved if -R is not set, and no stripe
6692         # count or size is specified
6693         echo -n "Verifying striping size preserved when not specified..."
6694         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
6695         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6696                 error "cannot set stripe on parent directory"
6697         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6698                 error "migrate failed"
6699         cur_ssize=$($LFS getstripe -S "$file1")
6700         [ $cur_ssize -eq $orig_ssize ] ||
6701                 error "migrate by default $cur_ssize != $orig_ssize"
6702         echo "done."
6703
6704         # Ensure file name properly detected when final option has no argument
6705         echo -n "Verifying file name properly detected..."
6706         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6707                 error "file name interpreted as option argument"
6708         echo "done."
6709
6710         # Clean up
6711         rm -f "$file1"
6712 }
6713 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
6714
6715 test_56wd() {
6716         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6717
6718         local file1=$DIR/$tdir/file1
6719
6720         echo -n "Creating test dir..."
6721         test_mkdir $DIR/$tdir || error "cannot create dir"
6722         echo "done."
6723
6724         echo -n "Creating test file..."
6725         touch $file1
6726         echo "done."
6727
6728         # Ensure 'lfs migrate' will fail by using a non-existent option,
6729         # and make sure rsync is not called to recover
6730         echo -n "Make sure --no-rsync option works..."
6731         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
6732                 grep -q 'refusing to fall back to rsync' ||
6733                 error "rsync was called with --no-rsync set"
6734         echo "done."
6735
6736         # Ensure rsync is called without trying 'lfs migrate' first
6737         echo -n "Make sure --rsync option works..."
6738         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
6739                 grep -q 'falling back to rsync' &&
6740                 error "lfs migrate was called with --rsync set"
6741         echo "done."
6742
6743         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
6744         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
6745                 grep -q 'at the same time' ||
6746                 error "--rsync and --no-rsync accepted concurrently"
6747         echo "done."
6748
6749         # Clean up
6750         rm -f $file1
6751 }
6752 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
6753
6754 test_56x() {
6755         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6756         check_swap_layouts_support
6757
6758         local dir=$DIR/$tdir
6759         local ref1=/etc/passwd
6760         local file1=$dir/file1
6761
6762         test_mkdir $dir || error "creating dir $dir"
6763         $LFS setstripe -c 2 $file1
6764         cp $ref1 $file1
6765         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
6766         stripe=$($LFS getstripe -c $file1)
6767         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6768         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6769
6770         # clean up
6771         rm -f $file1
6772 }
6773 run_test 56x "lfs migration support"
6774
6775 test_56xa() {
6776         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6777         check_swap_layouts_support
6778
6779         local dir=$DIR/$tdir/$testnum
6780
6781         test_mkdir -p $dir
6782
6783         local ref1=/etc/passwd
6784         local file1=$dir/file1
6785
6786         $LFS setstripe -c 2 $file1
6787         cp $ref1 $file1
6788         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
6789
6790         local stripe=$($LFS getstripe -c $file1)
6791
6792         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6793         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6794
6795         # clean up
6796         rm -f $file1
6797 }
6798 run_test 56xa "lfs migration --block support"
6799
6800 check_migrate_links() {
6801         local dir="$1"
6802         local file1="$dir/file1"
6803         local begin="$2"
6804         local count="$3"
6805         local runas="$4"
6806         local total_count=$(($begin + $count - 1))
6807         local symlink_count=10
6808         local uniq_count=10
6809
6810         if [ ! -f "$file1" ]; then
6811                 echo -n "creating initial file..."
6812                 $LFS setstripe -c 1 -S "512k" "$file1" ||
6813                         error "cannot setstripe initial file"
6814                 echo "done"
6815
6816                 echo -n "creating symlinks..."
6817                 for s in $(seq 1 $symlink_count); do
6818                         ln -s "$file1" "$dir/slink$s" ||
6819                                 error "cannot create symlinks"
6820                 done
6821                 echo "done"
6822
6823                 echo -n "creating nonlinked files..."
6824                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
6825                         error "cannot create nonlinked files"
6826                 echo "done"
6827         fi
6828
6829         # create hard links
6830         if [ ! -f "$dir/file$total_count" ]; then
6831                 echo -n "creating hard links $begin:$total_count..."
6832                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
6833                         /dev/null || error "cannot create hard links"
6834                 echo "done"
6835         fi
6836
6837         echo -n "checking number of hard links listed in xattrs..."
6838         local fid=$($LFS getstripe -F "$file1")
6839         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
6840
6841         echo "${#paths[*]}"
6842         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
6843                         skip "hard link list has unexpected size, skipping test"
6844         fi
6845         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
6846                         error "link names should exceed xattrs size"
6847         fi
6848
6849         echo -n "migrating files..."
6850         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
6851         local rc=$?
6852         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
6853         echo "done"
6854
6855         # make sure all links have been properly migrated
6856         echo -n "verifying files..."
6857         fid=$($LFS getstripe -F "$file1") ||
6858                 error "cannot get fid for file $file1"
6859         for i in $(seq 2 $total_count); do
6860                 local fid2=$($LFS getstripe -F $dir/file$i)
6861
6862                 [ "$fid2" == "$fid" ] ||
6863                         error "migrated hard link has mismatched FID"
6864         done
6865
6866         # make sure hard links were properly detected, and migration was
6867         # performed only once for the entire link set; nonlinked files should
6868         # also be migrated
6869         local actual=$(grep -c 'done' <<< "$migrate_out")
6870         local expected=$(($uniq_count + 1))
6871
6872         [ "$actual" -eq  "$expected" ] ||
6873                 error "hard links individually migrated ($actual != $expected)"
6874
6875         # make sure the correct number of hard links are present
6876         local hardlinks=$(stat -c '%h' "$file1")
6877
6878         [ $hardlinks -eq $total_count ] ||
6879                 error "num hard links $hardlinks != $total_count"
6880         echo "done"
6881
6882         return 0
6883 }
6884
6885 test_56xb() {
6886         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
6887                 skip "Need MDS version at least 2.10.55"
6888
6889         local dir="$DIR/$tdir"
6890
6891         test_mkdir "$dir" || error "cannot create dir $dir"
6892
6893         echo "testing lfs migrate mode when all links fit within xattrs"
6894         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
6895
6896         echo "testing rsync mode when all links fit within xattrs"
6897         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
6898
6899         echo "testing lfs migrate mode when all links do not fit within xattrs"
6900         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
6901
6902         echo "testing rsync mode when all links do not fit within xattrs"
6903         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
6904
6905         chown -R $RUNAS_ID $dir
6906         echo "testing non-root lfs migrate mode when not all links are in xattr"
6907         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
6908
6909         # clean up
6910         rm -rf $dir
6911 }
6912 run_test 56xb "lfs migration hard link support"
6913
6914 test_56xc() {
6915         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6916
6917         local dir="$DIR/$tdir"
6918
6919         test_mkdir "$dir" || error "cannot create dir $dir"
6920
6921         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
6922         echo -n "Setting initial stripe for 20MB test file..."
6923         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
6924                 error "cannot setstripe 20MB file"
6925         echo "done"
6926         echo -n "Sizing 20MB test file..."
6927         truncate "$dir/20mb" 20971520 || error "cannot create 20MB test file"
6928         echo "done"
6929         echo -n "Verifying small file autostripe count is 1..."
6930         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
6931                 error "cannot migrate 20MB file"
6932         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
6933                 error "cannot get stripe for $dir/20mb"
6934         [ $stripe_count -eq 1 ] ||
6935                 error "unexpected stripe count $stripe_count for 20MB file"
6936         rm -f "$dir/20mb"
6937         echo "done"
6938
6939         # Test 2: File is small enough to fit within the available space on
6940         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
6941         # have at least an additional 1KB for each desired stripe for test 3
6942         echo -n "Setting stripe for 1GB test file..."
6943         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
6944         echo "done"
6945         echo -n "Sizing 1GB test file..."
6946         # File size is 1GB + 3KB
6947         truncate "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
6948         echo "done"
6949
6950         # need at least 512MB per OST for 1GB file to fit in 2 stripes
6951         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
6952         if (( avail > 524288 * OSTCOUNT )); then
6953                 echo -n "Migrating 1GB file..."
6954                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
6955                         error "cannot migrate 1GB file"
6956                 echo "done"
6957                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
6958                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
6959                         error "cannot getstripe for 1GB file"
6960                 [ $stripe_count -eq 2 ] ||
6961                         error "unexpected stripe count $stripe_count != 2"
6962                 echo "done"
6963         fi
6964
6965         # Test 3: File is too large to fit within the available space on
6966         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
6967         if [ $OSTCOUNT -ge 3 ]; then
6968                 # The required available space is calculated as
6969                 # file size (1GB + 3KB) / OST count (3).
6970                 local kb_per_ost=349526
6971
6972                 echo -n "Migrating 1GB file with limit..."
6973                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
6974                         error "cannot migrate 1GB file with limit"
6975                 echo "done"
6976
6977                 stripe_count=$($LFS getstripe -c "$dir/1gb")
6978                 echo -n "Verifying 1GB autostripe count with limited space..."
6979                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
6980                         error "unexpected stripe count $stripe_count (min 3)"
6981                 echo "done"
6982         fi
6983
6984         # clean up
6985         rm -rf $dir
6986 }
6987 run_test 56xc "lfs migration autostripe"
6988
6989 test_56xd() {
6990         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6991
6992         local dir=$DIR/$tdir
6993         local f_mgrt=$dir/$tfile.mgrt
6994         local f_yaml=$dir/$tfile.yaml
6995         local f_copy=$dir/$tfile.copy
6996         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
6997         local layout_copy="-c 2 -S 2M -i 1"
6998         local yamlfile=$dir/yamlfile
6999         local layout_before;
7000         local layout_after;
7001
7002         test_mkdir "$dir" || error "cannot create dir $dir"
7003         $LFS setstripe $layout_yaml $f_yaml ||
7004                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7005         $LFS getstripe --yaml $f_yaml > $yamlfile
7006         $LFS setstripe $layout_copy $f_copy ||
7007                 error "cannot setstripe $f_copy with layout $layout_copy"
7008         touch $f_mgrt
7009         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7010
7011         # 1. test option --yaml
7012         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7013                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7014         layout_before=$(get_layout_param $f_yaml)
7015         layout_after=$(get_layout_param $f_mgrt)
7016         [ "$layout_after" == "$layout_before" ] ||
7017                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7018
7019         # 2. test option --copy
7020         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7021                 error "cannot migrate $f_mgrt with --copy $f_copy"
7022         layout_before=$(get_layout_param $f_copy)
7023         layout_after=$(get_layout_param $f_mgrt)
7024         [ "$layout_after" == "$layout_before" ] ||
7025                 error "lfs_migrate --copy: $layout_after != $layout_before"
7026 }
7027 run_test 56xd "check lfs_migrate --yaml and --copy support"
7028
7029 test_56xe() {
7030         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7031
7032         local dir=$DIR/$tdir
7033         local f_comp=$dir/$tfile
7034         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7035         local layout_before=""
7036         local layout_after=""
7037
7038         test_mkdir "$dir" || error "cannot create dir $dir"
7039         $LFS setstripe $layout $f_comp ||
7040                 error "cannot setstripe $f_comp with layout $layout"
7041         layout_before=$(get_layout_param $f_comp)
7042         dd if=/dev/zero of=$f_comp bs=1M count=4
7043
7044         # 1. migrate a comp layout file by lfs_migrate
7045         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7046         layout_after=$(get_layout_param $f_comp)
7047         [ "$layout_before" == "$layout_after" ] ||
7048                 error "lfs_migrate: $layout_before != $layout_after"
7049
7050         # 2. migrate a comp layout file by lfs migrate
7051         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7052         layout_after=$(get_layout_param $f_comp)
7053         [ "$layout_before" == "$layout_after" ] ||
7054                 error "lfs migrate: $layout_before != $layout_after"
7055 }
7056 run_test 56xe "migrate a composite layout file"
7057
7058 test_56y() {
7059         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7060                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7061
7062         local res=""
7063         local dir=$DIR/$tdir
7064         local f1=$dir/file1
7065         local f2=$dir/file2
7066
7067         test_mkdir -p $dir || error "creating dir $dir"
7068         touch $f1 || error "creating std file $f1"
7069         $MULTIOP $f2 H2c || error "creating released file $f2"
7070
7071         # a directory can be raid0, so ask only for files
7072         res=$($LFS find $dir -L raid0 -type f | wc -l)
7073         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7074
7075         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7076         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7077
7078         # only files can be released, so no need to force file search
7079         res=$($LFS find $dir -L released)
7080         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7081
7082         res=$($LFS find $dir -type f \! -L released)
7083         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7084 }
7085 run_test 56y "lfs find -L raid0|released"
7086
7087 test_56z() { # LU-4824
7088         # This checks to make sure 'lfs find' continues after errors
7089         # There are two classes of errors that should be caught:
7090         # - If multiple paths are provided, all should be searched even if one
7091         #   errors out
7092         # - If errors are encountered during the search, it should not terminate
7093         #   early
7094         local dir=$DIR/$tdir
7095         local i
7096
7097         test_mkdir $dir
7098         for i in d{0..9}; do
7099                 test_mkdir $dir/$i
7100                 touch $dir/$i/$tfile
7101         done
7102         $LFS find $DIR/non_existent_dir $dir &&
7103                 error "$LFS find did not return an error"
7104         # Make a directory unsearchable. This should NOT be the last entry in
7105         # directory order.  Arbitrarily pick the 6th entry
7106         chmod 700 $($LFS find $dir -type d | sed '6!d')
7107
7108         $RUNAS $LFS find $DIR/non_existent $dir
7109         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7110
7111         # The user should be able to see 10 directories and 9 files
7112         (( count == 19 )) ||
7113                 error "$LFS find found $count != 19 entries after error"
7114 }
7115 run_test 56z "lfs find should continue after an error"
7116
7117 test_56aa() { # LU-5937
7118         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7119
7120         local dir=$DIR/$tdir
7121
7122         mkdir $dir
7123         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7124
7125         createmany -o $dir/striped_dir/${tfile}- 1024
7126         local dirs=$($LFS find --size +8k $dir/)
7127
7128         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7129 }
7130 run_test 56aa "lfs find --size under striped dir"
7131
7132 test_56ab() { # LU-10705
7133         test_mkdir $DIR/$tdir
7134         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7135         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7136         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7137         # Flush writes to ensure valid blocks.  Need to be more thorough for
7138         # ZFS, since blocks are not allocated/returned to client immediately.
7139         sync_all_data
7140         wait_zfs_commit ost1 2
7141         cancel_lru_locks osc
7142         ls -ls $DIR/$tdir
7143
7144         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7145
7146         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7147
7148         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7149         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7150
7151         rm -f $DIR/$tdir/$tfile.[123]
7152 }
7153 run_test 56ab "lfs find --blocks"
7154
7155 test_56ba() {
7156         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
7157                 skip "Need MDS version at least 2.10.50"
7158
7159         # Create composite files with one component
7160         local dir=$DIR/$tdir
7161
7162         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
7163         # Create composite files with three components
7164         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
7165         # Create non-composite files
7166         createmany -o $dir/${tfile}- 10
7167
7168         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
7169
7170         [[ $nfiles == 10 ]] ||
7171                 error "lfs find -E 1M found $nfiles != 10 files"
7172
7173         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
7174         [[ $nfiles == 25 ]] ||
7175                 error "lfs find ! -E 1M found $nfiles != 25 files"
7176
7177         # All files have a component that starts at 0
7178         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
7179         [[ $nfiles == 35 ]] ||
7180                 error "lfs find --component-start 0 - $nfiles != 35 files"
7181
7182         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
7183         [[ $nfiles == 15 ]] ||
7184                 error "lfs find --component-start 2M - $nfiles != 15 files"
7185
7186         # All files created here have a componenet that does not starts at 2M
7187         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
7188         [[ $nfiles == 35 ]] ||
7189                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
7190
7191         # Find files with a specified number of components
7192         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
7193         [[ $nfiles == 15 ]] ||
7194                 error "lfs find --component-count 3 - $nfiles != 15 files"
7195
7196         # Remember non-composite files have a component count of zero
7197         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
7198         [[ $nfiles == 10 ]] ||
7199                 error "lfs find --component-count 0 - $nfiles != 10 files"
7200
7201         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
7202         [[ $nfiles == 20 ]] ||
7203                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
7204
7205         # All files have a flag called "init"
7206         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
7207         [[ $nfiles == 35 ]] ||
7208                 error "lfs find --component-flags init - $nfiles != 35 files"
7209
7210         # Multi-component files will have a component not initialized
7211         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
7212         [[ $nfiles == 15 ]] ||
7213                 error "lfs find !--component-flags init - $nfiles != 15 files"
7214
7215         rm -rf $dir
7216
7217 }
7218 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
7219
7220 test_56ca() {
7221         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
7222                 skip "Need MDS version at least 2.10.57"
7223
7224         local td=$DIR/$tdir
7225         local tf=$td/$tfile
7226         local dir
7227         local nfiles
7228         local cmd
7229         local i
7230         local j
7231
7232         # create mirrored directories and mirrored files
7233         mkdir $td || error "mkdir $td failed"
7234         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
7235         createmany -o $tf- 10 || error "create $tf- failed"
7236
7237         for i in $(seq 2); do
7238                 dir=$td/dir$i
7239                 mkdir $dir || error "mkdir $dir failed"
7240                 $LFS mirror create -N$((3 + i)) $dir ||
7241                         error "create mirrored dir $dir failed"
7242                 createmany -o $dir/$tfile- 10 ||
7243                         error "create $dir/$tfile- failed"
7244         done
7245
7246         # change the states of some mirrored files
7247         echo foo > $tf-6
7248         for i in $(seq 2); do
7249                 dir=$td/dir$i
7250                 for j in $(seq 4 9); do
7251                         echo foo > $dir/$tfile-$j
7252                 done
7253         done
7254
7255         # find mirrored files with specific mirror count
7256         cmd="$LFS find --mirror-count 3 --type f $td"
7257         nfiles=$($cmd | wc -l)
7258         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
7259
7260         cmd="$LFS find ! --mirror-count 3 --type f $td"
7261         nfiles=$($cmd | wc -l)
7262         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
7263
7264         cmd="$LFS find --mirror-count +2 --type f $td"
7265         nfiles=$($cmd | wc -l)
7266         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7267
7268         cmd="$LFS find --mirror-count -6 --type f $td"
7269         nfiles=$($cmd | wc -l)
7270         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7271
7272         # find mirrored files with specific file state
7273         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
7274         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
7275
7276         cmd="$LFS find --mirror-state=ro --type f $td"
7277         nfiles=$($cmd | wc -l)
7278         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
7279
7280         cmd="$LFS find ! --mirror-state=ro --type f $td"
7281         nfiles=$($cmd | wc -l)
7282         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7283
7284         cmd="$LFS find --mirror-state=wp --type f $td"
7285         nfiles=$($cmd | wc -l)
7286         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7287
7288         cmd="$LFS find ! --mirror-state=sp --type f $td"
7289         nfiles=$($cmd | wc -l)
7290         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7291 }
7292 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
7293
7294 test_57a() {
7295         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7296         # note test will not do anything if MDS is not local
7297         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7298                 skip_env "ldiskfs only test"
7299         fi
7300         remote_mds_nodsh && skip "remote MDS with nodsh"
7301
7302         local MNTDEV="osd*.*MDT*.mntdev"
7303         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
7304         [ -z "$DEV" ] && error "can't access $MNTDEV"
7305         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
7306                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
7307                         error "can't access $DEV"
7308                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
7309                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
7310                 rm $TMP/t57a.dump
7311         done
7312 }
7313 run_test 57a "verify MDS filesystem created with large inodes =="
7314
7315 test_57b() {
7316         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7317         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7318                 skip_env "ldiskfs only test"
7319         fi
7320         remote_mds_nodsh && skip "remote MDS with nodsh"
7321
7322         local dir=$DIR/$tdir
7323         local filecount=100
7324         local file1=$dir/f1
7325         local fileN=$dir/f$filecount
7326
7327         rm -rf $dir || error "removing $dir"
7328         test_mkdir -c1 $dir
7329         local mdtidx=$($LFS getstripe -m $dir)
7330         local mdtname=MDT$(printf %04x $mdtidx)
7331         local facet=mds$((mdtidx + 1))
7332
7333         echo "mcreating $filecount files"
7334         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
7335
7336         # verify that files do not have EAs yet
7337         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
7338                 error "$file1 has an EA"
7339         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
7340                 error "$fileN has an EA"
7341
7342         sync
7343         sleep 1
7344         df $dir  #make sure we get new statfs data
7345         local mdsfree=$(do_facet $facet \
7346                         lctl get_param -n osd*.*$mdtname.kbytesfree)
7347         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7348         local file
7349
7350         echo "opening files to create objects/EAs"
7351         for file in $(seq -f $dir/f%g 1 $filecount); do
7352                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
7353                         error "opening $file"
7354         done
7355
7356         # verify that files have EAs now
7357         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
7358         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
7359
7360         sleep 1  #make sure we get new statfs data
7361         df $dir
7362         local mdsfree2=$(do_facet $facet \
7363                          lctl get_param -n osd*.*$mdtname.kbytesfree)
7364         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7365
7366         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
7367                 if [ "$mdsfree" != "$mdsfree2" ]; then
7368                         error "MDC before $mdcfree != after $mdcfree2"
7369                 else
7370                         echo "MDC before $mdcfree != after $mdcfree2"
7371                         echo "unable to confirm if MDS has large inodes"
7372                 fi
7373         fi
7374         rm -rf $dir
7375 }
7376 run_test 57b "default LOV EAs are stored inside large inodes ==="
7377
7378 test_58() {
7379         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7380         [ -z "$(which wiretest 2>/dev/null)" ] &&
7381                         skip_env "could not find wiretest"
7382
7383         wiretest
7384 }
7385 run_test 58 "verify cross-platform wire constants =============="
7386
7387 test_59() {
7388         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7389
7390         echo "touch 130 files"
7391         createmany -o $DIR/f59- 130
7392         echo "rm 130 files"
7393         unlinkmany $DIR/f59- 130
7394         sync
7395         # wait for commitment of removal
7396         wait_delete_completed
7397 }
7398 run_test 59 "verify cancellation of llog records async ========="
7399
7400 TEST60_HEAD="test_60 run $RANDOM"
7401 test_60a() {
7402         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7403         remote_mgs_nodsh && skip "remote MGS with nodsh"
7404         do_facet mgs "! which run-llog.sh &> /dev/null" &&
7405                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
7406                         skip_env "missing subtest run-llog.sh"
7407
7408         log "$TEST60_HEAD - from kernel mode"
7409         do_facet mgs "$LCTL dk > /dev/null"
7410         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
7411         do_facet mgs $LCTL dk > $TMP/$tfile
7412
7413         # LU-6388: test llog_reader
7414         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
7415         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
7416         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
7417                         skip_env "missing llog_reader"
7418         local fstype=$(facet_fstype mgs)
7419         [ $fstype != ldiskfs -a $fstype != zfs ] &&
7420                 skip_env "Only for ldiskfs or zfs type mgs"
7421
7422         local mntpt=$(facet_mntpt mgs)
7423         local mgsdev=$(mgsdevname 1)
7424         local fid_list
7425         local fid
7426         local rec_list
7427         local rec
7428         local rec_type
7429         local obj_file
7430         local path
7431         local seq
7432         local oid
7433         local pass=true
7434
7435         #get fid and record list
7436         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
7437                 tail -n 4))
7438         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
7439                 tail -n 4))
7440         #remount mgs as ldiskfs or zfs type
7441         stop mgs || error "stop mgs failed"
7442         mount_fstype mgs || error "remount mgs failed"
7443         for ((i = 0; i < ${#fid_list[@]}; i++)); do
7444                 fid=${fid_list[i]}
7445                 rec=${rec_list[i]}
7446                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
7447                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
7448                 oid=$((16#$oid))
7449
7450                 case $fstype in
7451                         ldiskfs )
7452                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
7453                         zfs )
7454                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
7455                 esac
7456                 echo "obj_file is $obj_file"
7457                 do_facet mgs $llog_reader $obj_file
7458
7459                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
7460                         awk '{ print $3 }' | sed -e "s/^type=//g")
7461                 if [ $rec_type != $rec ]; then
7462                         echo "FAILED test_60a wrong record type $rec_type," \
7463                               "should be $rec"
7464                         pass=false
7465                         break
7466                 fi
7467
7468                 #check obj path if record type is LLOG_LOGID_MAGIC
7469                 if [ "$rec" == "1064553b" ]; then
7470                         path=$(do_facet mgs $llog_reader $obj_file |
7471                                 grep "path=" | awk '{ print $NF }' |
7472                                 sed -e "s/^path=//g")
7473                         if [ $obj_file != $mntpt/$path ]; then
7474                                 echo "FAILED test_60a wrong obj path" \
7475                                       "$montpt/$path, should be $obj_file"
7476                                 pass=false
7477                                 break
7478                         fi
7479                 fi
7480         done
7481         rm -f $TMP/$tfile
7482         #restart mgs before "error", otherwise it will block the next test
7483         stop mgs || error "stop mgs failed"
7484         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
7485         $pass || error "test failed, see FAILED test_60a messages for specifics"
7486 }
7487 run_test 60a "llog_test run from kernel module and test llog_reader"
7488
7489 test_60b() { # bug 6411
7490         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7491
7492         dmesg > $DIR/$tfile
7493         LLOG_COUNT=$(do_facet mgs dmesg |
7494                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
7495                           /llog_[a-z]*.c:[0-9]/ {
7496                                 if (marker)
7497                                         from_marker++
7498                                 from_begin++
7499                           }
7500                           END {
7501                                 if (marker)
7502                                         print from_marker
7503                                 else
7504                                         print from_begin
7505                           }")
7506
7507         [[ $LLOG_COUNT -gt 120 ]] &&
7508                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
7509 }
7510 run_test 60b "limit repeated messages from CERROR/CWARN"
7511
7512 test_60c() {
7513         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7514
7515         echo "create 5000 files"
7516         createmany -o $DIR/f60c- 5000
7517 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
7518         lctl set_param fail_loc=0x80000137
7519         unlinkmany $DIR/f60c- 5000
7520         lctl set_param fail_loc=0
7521 }
7522 run_test 60c "unlink file when mds full"
7523
7524 test_60d() {
7525         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7526
7527         SAVEPRINTK=$(lctl get_param -n printk)
7528         # verify "lctl mark" is even working"
7529         MESSAGE="test message ID $RANDOM $$"
7530         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7531         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
7532
7533         lctl set_param printk=0 || error "set lnet.printk failed"
7534         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
7535         MESSAGE="new test message ID $RANDOM $$"
7536         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
7537         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7538         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
7539
7540         lctl set_param -n printk="$SAVEPRINTK"
7541 }
7542 run_test 60d "test printk console message masking"
7543
7544 test_60e() {
7545         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7546         remote_mds_nodsh && skip "remote MDS with nodsh"
7547
7548         touch $DIR/$tfile
7549 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
7550         do_facet mds1 lctl set_param fail_loc=0x15b
7551         rm $DIR/$tfile
7552 }
7553 run_test 60e "no space while new llog is being created"
7554
7555 test_60g() {
7556         local pid
7557         local i
7558
7559         test_mkdir -c $MDSCOUNT $DIR/$tdir
7560
7561         (
7562                 local index=0
7563                 while true; do
7564                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
7565                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
7566                                 2>/dev/null
7567                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
7568                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
7569                         index=$((index + 1))
7570                 done
7571         ) &
7572
7573         pid=$!
7574
7575         for i in {0..100}; do
7576                 # define OBD_FAIL_OSD_TXN_START    0x19a
7577                 local index=$((i % MDSCOUNT + 1))
7578
7579                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
7580                         > /dev/null
7581                 usleep 100
7582         done
7583
7584         kill -9 $pid
7585
7586         for i in $(seq $MDSCOUNT); do
7587                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
7588         done
7589
7590         mkdir $DIR/$tdir/new || error "mkdir failed"
7591         rmdir $DIR/$tdir/new || error "rmdir failed"
7592
7593         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
7594                 -t namespace
7595         for i in $(seq $MDSCOUNT); do
7596                 wait_update_facet mds$i "$LCTL get_param -n \
7597                         mdd.$(facet_svc mds$i).lfsck_namespace |
7598                         awk '/^status/ { print \\\$2 }'" "completed"
7599         done
7600
7601         ls -R $DIR/$tdir || error "ls failed"
7602         rm -rf $DIR/$tdir || error "rmdir failed"
7603 }
7604 run_test 60g "transaction abort won't cause MDT hung"
7605
7606 test_60h() {
7607         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
7608                 skip "Need MDS version at least 2.12.52"
7609         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
7610
7611         local f
7612
7613         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
7614         #define OBD_FAIL_MDS_STRIPE_FID          0x189
7615         for fail_loc in 0x80000188 0x80000189; do
7616                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
7617                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
7618                         error "mkdir $dir-$fail_loc failed"
7619                 for i in {0..10}; do
7620                         # create may fail on missing stripe
7621                         echo $i > $DIR/$tdir-$fail_loc/$i
7622                 done
7623                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7624                         error "getdirstripe $tdir-$fail_loc failed"
7625                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
7626                         error "migrate $tdir-$fail_loc failed"
7627                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7628                         error "getdirstripe $tdir-$fail_loc failed"
7629                 pushd $DIR/$tdir-$fail_loc
7630                 for f in *; do
7631                         echo $f | cmp $f - || error "$f data mismatch"
7632                 done
7633                 popd
7634                 rm -rf $DIR/$tdir-$fail_loc
7635         done
7636 }
7637 run_test 60h "striped directory with missing stripes can be accessed"
7638
7639 test_61a() {
7640         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7641
7642         f="$DIR/f61"
7643         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
7644         cancel_lru_locks osc
7645         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
7646         sync
7647 }
7648 run_test 61a "mmap() writes don't make sync hang ================"
7649
7650 test_61b() {
7651         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
7652 }
7653 run_test 61b "mmap() of unstriped file is successful"
7654
7655 # bug 2330 - insufficient obd_match error checking causes LBUG
7656 test_62() {
7657         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7658
7659         f="$DIR/f62"
7660         echo foo > $f
7661         cancel_lru_locks osc
7662         lctl set_param fail_loc=0x405
7663         cat $f && error "cat succeeded, expect -EIO"
7664         lctl set_param fail_loc=0
7665 }
7666 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
7667 # match every page all of the time.
7668 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
7669
7670 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
7671 # Though this test is irrelevant anymore, it helped to reveal some
7672 # other grant bugs (LU-4482), let's keep it.
7673 test_63a() {   # was test_63
7674         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7675
7676         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
7677
7678         for i in `seq 10` ; do
7679                 dd if=/dev/zero of=$DIR/f63 bs=8k &
7680                 sleep 5
7681                 kill $!
7682                 sleep 1
7683         done
7684
7685         rm -f $DIR/f63 || true
7686 }
7687 run_test 63a "Verify oig_wait interruption does not crash ======="
7688
7689 # bug 2248 - async write errors didn't return to application on sync
7690 # bug 3677 - async write errors left page locked
7691 test_63b() {
7692         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7693
7694         debugsave
7695         lctl set_param debug=-1
7696
7697         # ensure we have a grant to do async writes
7698         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
7699         rm $DIR/$tfile
7700
7701         sync    # sync lest earlier test intercept the fail_loc
7702
7703         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
7704         lctl set_param fail_loc=0x80000406
7705         $MULTIOP $DIR/$tfile Owy && \
7706                 error "sync didn't return ENOMEM"
7707         sync; sleep 2; sync     # do a real sync this time to flush page
7708         lctl get_param -n llite.*.dump_page_cache | grep locked && \
7709                 error "locked page left in cache after async error" || true
7710         debugrestore
7711 }
7712 run_test 63b "async write errors should be returned to fsync ==="
7713
7714 test_64a () {
7715         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7716
7717         lfs df $DIR
7718         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
7719 }
7720 run_test 64a "verify filter grant calculations (in kernel) ====="
7721
7722 test_64b () {
7723         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7724
7725         sh oos.sh $MOUNT || error "oos.sh failed: $?"
7726 }
7727 run_test 64b "check out-of-space detection on client"
7728
7729 test_64c() {
7730         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
7731 }
7732 run_test 64c "verify grant shrink"
7733
7734 # this does exactly what osc_request.c:osc_announce_cached() does in
7735 # order to calculate max amount of grants to ask from server
7736 want_grant() {
7737         local tgt=$1
7738
7739         local nrpages=$($LCTL get_param -n osc.${tgt}.max_pages_per_rpc)
7740         local rpc_in_flight=$($LCTL get_param -n osc.${tgt}.max_rpcs_in_flight)
7741
7742         ((rpc_in_flight ++));
7743         nrpages=$((nrpages * rpc_in_flight))
7744
7745         local dirty_max_pages=$($LCTL get_param -n osc.${tgt}.max_dirty_mb)
7746
7747         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
7748
7749         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
7750         local undirty=$((nrpages * PAGE_SIZE))
7751
7752         local max_extent_pages
7753         max_extent_pages=$($LCTL get_param osc.${tgt}.import |
7754             grep grant_max_extent_size | awk '{print $2}')
7755         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
7756         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
7757         local grant_extent_tax
7758         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
7759             grep grant_extent_tax | awk '{print $2}')
7760
7761         undirty=$((undirty + nrextents * grant_extent_tax))
7762
7763         echo $undirty
7764 }
7765
7766 # this is size of unit for grant allocation. It should be equal to
7767 # what tgt_grant.c:tgt_grant_chunk() calculates
7768 grant_chunk() {
7769         local tgt=$1
7770         local max_brw_size
7771         local grant_extent_tax
7772
7773         max_brw_size=$($LCTL get_param osc.${tgt}.import |
7774             grep max_brw_size | awk '{print $2}')
7775
7776         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
7777             grep grant_extent_tax | awk '{print $2}')
7778
7779         echo $(((max_brw_size + grant_extent_tax) * 2))
7780 }
7781
7782 test_64d() {
7783         [ $OST1_VERSION -lt $(version_code 2.10.56) ] &&
7784                 skip "OST < 2.10.55 doesn't limit grants enough"
7785
7786         local tgt=$($LCTL dl | grep "0000-osc-[^mM]" | awk '{print $4}')
7787         local file=$DIR/$tfile
7788
7789         [[ $($LCTL get_param osc.${tgt}.import |
7790              grep "connect_flags:.*grant_param") ]] ||
7791                 skip "no grant_param connect flag"
7792
7793         local olddebug=$($LCTL get_param -n debug 2> /dev/null)
7794
7795         $LCTL set_param debug="$OLDDEBUG" 2> /dev/null || true
7796
7797         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
7798         stack_trap "rm -f $file" EXIT
7799
7800         $LFS setstripe $file -i 0 -c 1
7801         dd if=/dev/zero of=$file bs=1M count=1000 &
7802         ddpid=$!
7803
7804         while true
7805         do
7806                 local cur_grant=$($LCTL get_param -n osc.${tgt}.cur_grant_bytes)
7807                 if [[ $cur_grant -gt $max_cur_granted ]]
7808                 then
7809                         kill $ddpid
7810                         error "cur_grant $cur_grant > $max_cur_granted"
7811                 fi
7812                 kill -0 $ddpid
7813                 [[ $? -ne 0 ]] && break;
7814                 sleep 2
7815         done
7816
7817         rm -f $DIR/$tfile
7818         wait_delete_completed
7819         $LCTL set_param debug="$olddebug" 2> /dev/null || true
7820 }
7821 run_test 64d "check grant limit exceed"
7822
7823 # bug 1414 - set/get directories' stripe info
7824 test_65a() {
7825         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7826
7827         test_mkdir $DIR/$tdir
7828         touch $DIR/$tdir/f1
7829         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
7830 }
7831 run_test 65a "directory with no stripe info"
7832
7833 test_65b() {
7834         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7835
7836         test_mkdir $DIR/$tdir
7837         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7838
7839         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
7840                                                 error "setstripe"
7841         touch $DIR/$tdir/f2
7842         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
7843 }
7844 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
7845
7846 test_65c() {
7847         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7848         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
7849
7850         test_mkdir $DIR/$tdir
7851         local stripesize=$($LFS getstripe -S $DIR/$tdir)
7852
7853         $LFS setstripe -S $((stripesize * 4)) -i 1 \
7854                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
7855         touch $DIR/$tdir/f3
7856         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
7857 }
7858 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
7859
7860 test_65d() {
7861         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7862
7863         test_mkdir $DIR/$tdir
7864         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
7865         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7866
7867         if [[ $STRIPECOUNT -le 0 ]]; then
7868                 sc=1
7869         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
7870                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
7871                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
7872         else
7873                 sc=$(($STRIPECOUNT - 1))
7874         fi
7875         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
7876         touch $DIR/$tdir/f4 $DIR/$tdir/f5
7877         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
7878                 error "lverify failed"
7879 }
7880 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
7881
7882 test_65e() {
7883         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7884
7885         test_mkdir $DIR/$tdir
7886
7887         $LFS setstripe $DIR/$tdir || error "setstripe"
7888         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
7889                                         error "no stripe info failed"
7890         touch $DIR/$tdir/f6
7891         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
7892 }
7893 run_test 65e "directory setstripe defaults"
7894
7895 test_65f() {
7896         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7897
7898         test_mkdir $DIR/${tdir}f
7899         $RUNAS $LFS setstripe $DIR/${tdir}f &&
7900                 error "setstripe succeeded" || true
7901 }
7902 run_test 65f "dir setstripe permission (should return error) ==="
7903
7904 test_65g() {
7905         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7906
7907         test_mkdir $DIR/$tdir
7908         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7909
7910         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
7911                 error "setstripe -S failed"
7912         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
7913         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
7914                 error "delete default stripe failed"
7915 }
7916 run_test 65g "directory setstripe -d"
7917
7918 test_65h() {
7919         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7920
7921         test_mkdir $DIR/$tdir
7922         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7923
7924         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
7925                 error "setstripe -S failed"
7926         test_mkdir $DIR/$tdir/dd1
7927         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
7928                 error "stripe info inherit failed"
7929 }
7930 run_test 65h "directory stripe info inherit ===================="
7931
7932 test_65i() {
7933         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7934
7935         save_layout_restore_at_exit $MOUNT
7936
7937         # bug6367: set non-default striping on root directory
7938         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
7939
7940         # bug12836: getstripe on -1 default directory striping
7941         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
7942
7943         # bug12836: getstripe -v on -1 default directory striping
7944         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
7945
7946         # bug12836: new find on -1 default directory striping
7947         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
7948 }
7949 run_test 65i "various tests to set root directory striping"
7950
7951 test_65j() { # bug6367
7952         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7953
7954         sync; sleep 1
7955
7956         # if we aren't already remounting for each test, do so for this test
7957         if [ "$I_MOUNTED" = "yes" ]; then
7958                 cleanup || error "failed to unmount"
7959                 setup
7960         fi
7961
7962         save_layout_restore_at_exit $MOUNT
7963
7964         $LFS setstripe -d $MOUNT || error "setstripe failed"
7965 }
7966 run_test 65j "set default striping on root directory (bug 6367)="
7967
7968 cleanup_65k() {
7969         rm -rf $DIR/$tdir
7970         wait_delete_completed
7971         do_facet $SINGLEMDS "lctl set_param -n \
7972                 osp.$ost*MDT0000.max_create_count=$max_count"
7973         do_facet $SINGLEMDS "lctl set_param -n \
7974                 osp.$ost*MDT0000.create_count=$count"
7975         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
7976         echo $INACTIVE_OSC "is Activate"
7977
7978         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
7979 }
7980
7981 test_65k() { # bug11679
7982         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7983         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7984         remote_mds_nodsh && skip "remote MDS with nodsh"
7985
7986         local disable_precreate=true
7987         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
7988                 disable_precreate=false
7989
7990         echo "Check OST status: "
7991         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
7992                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
7993
7994         for OSC in $MDS_OSCS; do
7995                 echo $OSC "is active"
7996                 do_facet $SINGLEMDS lctl --device %$OSC activate
7997         done
7998
7999         for INACTIVE_OSC in $MDS_OSCS; do
8000                 local ost=$(osc_to_ost $INACTIVE_OSC)
8001                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
8002                                lov.*md*.target_obd |
8003                                awk -F: /$ost/'{ print $1 }' | head -n 1)
8004
8005                 mkdir -p $DIR/$tdir
8006                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
8007                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
8008
8009                 echo "Deactivate: " $INACTIVE_OSC
8010                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
8011
8012                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
8013                               osp.$ost*MDT0000.create_count")
8014                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
8015                                   osp.$ost*MDT0000.max_create_count")
8016                 $disable_precreate &&
8017                         do_facet $SINGLEMDS "lctl set_param -n \
8018                                 osp.$ost*MDT0000.max_create_count=0"
8019
8020                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
8021                         [ -f $DIR/$tdir/$idx ] && continue
8022                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
8023                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
8024                                 { cleanup_65k;
8025                                   error "setstripe $idx should succeed"; }
8026                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
8027                 done
8028                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
8029                 rmdir $DIR/$tdir
8030
8031                 do_facet $SINGLEMDS "lctl set_param -n \
8032                         osp.$ost*MDT0000.max_create_count=$max_count"
8033                 do_facet $SINGLEMDS "lctl set_param -n \
8034                         osp.$ost*MDT0000.create_count=$count"
8035                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8036                 echo $INACTIVE_OSC "is Activate"
8037
8038                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8039         done
8040 }
8041 run_test 65k "validate manual striping works properly with deactivated OSCs"
8042
8043 test_65l() { # bug 12836
8044         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8045
8046         test_mkdir -p $DIR/$tdir/test_dir
8047         $LFS setstripe -c -1 $DIR/$tdir/test_dir
8048         $LFS find -mtime -1 $DIR/$tdir >/dev/null
8049 }
8050 run_test 65l "lfs find on -1 stripe dir ========================"
8051
8052 test_65m() {
8053         local layout=$(save_layout $MOUNT)
8054         $RUNAS $LFS setstripe -c 2 $MOUNT && {
8055                 restore_layout $MOUNT $layout
8056                 error "setstripe should fail by non-root users"
8057         }
8058         true
8059 }
8060 run_test 65m "normal user can't set filesystem default stripe"
8061
8062 test_65n() {
8063         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
8064         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
8065                 skip "Need MDS version at least 2.12.50"
8066         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8067
8068         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8069         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
8070         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
8071
8072         local root_layout=$(save_layout $MOUNT)
8073         stack_trap "restore_layout $MOUNT $root_layout" EXIT
8074
8075         # new subdirectory under root directory should not inherit
8076         # the default layout from root
8077         local dir1=$MOUNT/$tdir-1
8078         mkdir $dir1 || error "mkdir $dir1 failed"
8079         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
8080                 error "$dir1 shouldn't have LOV EA"
8081
8082         # delete the default layout on root directory
8083         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
8084
8085         local dir2=$MOUNT/$tdir-2
8086         mkdir $dir2 || error "mkdir $dir2 failed"
8087         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
8088                 error "$dir2 shouldn't have LOV EA"
8089
8090         # set a new striping pattern on root directory
8091         local def_stripe_size=$($LFS getstripe -S $MOUNT)
8092         local new_def_stripe_size=$((def_stripe_size * 2))
8093         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
8094                 error "set stripe size on $MOUNT failed"
8095
8096         # new file created in $dir2 should inherit the new stripe size from
8097         # the filesystem default
8098         local file2=$dir2/$tfile-2
8099         touch $file2 || error "touch $file2 failed"
8100
8101         local file2_stripe_size=$($LFS getstripe -S $file2)
8102         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
8103                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
8104
8105         local dir3=$MOUNT/$tdir-3
8106         mkdir $dir3 || error "mkdir $dir3 failed"
8107         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
8108         # the root layout, which is the actual default layout that will be used
8109         # when new files are created in $dir3.
8110         local dir3_layout=$(get_layout_param $dir3)
8111         local root_dir_layout=$(get_layout_param $MOUNT)
8112         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
8113                 error "$dir3 should show the default layout from $MOUNT"
8114
8115         # set OST pool on root directory
8116         local pool=$TESTNAME
8117         pool_add $pool || error "add $pool failed"
8118         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8119                 error "add targets to $pool failed"
8120
8121         $LFS setstripe -p $pool $MOUNT ||
8122                 error "set OST pool on $MOUNT failed"
8123
8124         # new file created in $dir3 should inherit the pool from
8125         # the filesystem default
8126         local file3=$dir3/$tfile-3
8127         touch $file3 || error "touch $file3 failed"
8128
8129         local file3_pool=$($LFS getstripe -p $file3)
8130         [[ "$file3_pool" = "$pool" ]] ||
8131                 error "$file3 didn't inherit OST pool $pool"
8132
8133         local dir4=$MOUNT/$tdir-4
8134         mkdir $dir4 || error "mkdir $dir4 failed"
8135         local dir4_layout=$(get_layout_param $dir4)
8136         root_dir_layout=$(get_layout_param $MOUNT)
8137         echo "$LFS getstripe -d $dir4"
8138         $LFS getstripe -d $dir4
8139         echo "$LFS getstripe -d $MOUNT"
8140         $LFS getstripe -d $MOUNT
8141         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
8142                 error "$dir4 should show the default layout from $MOUNT"
8143
8144         # new file created in $dir4 should inherit the pool from
8145         # the filesystem default
8146         local file4=$dir4/$tfile-4
8147         touch $file4 || error "touch $file4 failed"
8148
8149         local file4_pool=$($LFS getstripe -p $file4)
8150         [[ "$file4_pool" = "$pool" ]] ||
8151                 error "$file4 didn't inherit OST pool $pool"
8152
8153         # new subdirectory under non-root directory should inherit
8154         # the default layout from its parent directory
8155         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
8156                 error "set directory layout on $dir4 failed"
8157
8158         local dir5=$dir4/$tdir-5
8159         mkdir $dir5 || error "mkdir $dir5 failed"
8160
8161         dir4_layout=$(get_layout_param $dir4)
8162         local dir5_layout=$(get_layout_param $dir5)
8163         [[ "$dir4_layout" = "$dir5_layout" ]] ||
8164                 error "$dir5 should inherit the default layout from $dir4"
8165
8166         # though subdir under ROOT doesn't inherit default layout, but
8167         # its sub dir/file should be created with default layout.
8168         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
8169         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
8170                 skip "Need MDS version at least 2.12.59"
8171
8172         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
8173         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
8174         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
8175
8176         if [ $default_lmv_hash == "none" ]; then
8177                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
8178         else
8179                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
8180                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
8181         fi
8182
8183         $LFS setdirstripe -D -c 2 $MOUNT ||
8184                 error "setdirstripe -D -c 2 failed"
8185         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
8186         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
8187         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
8188 }
8189 run_test 65n "don't inherit default layout from root for new subdirectories"
8190
8191 # bug 2543 - update blocks count on client
8192 test_66() {
8193         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8194
8195         COUNT=${COUNT:-8}
8196         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
8197         sync; sync_all_data; sync; sync_all_data
8198         cancel_lru_locks osc
8199         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
8200         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
8201 }
8202 run_test 66 "update inode blocks count on client ==============="
8203
8204 meminfo() {
8205         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
8206 }
8207
8208 swap_used() {
8209         swapon -s | awk '($1 == "'$1'") { print $4 }'
8210 }
8211
8212 # bug5265, obdfilter oa2dentry return -ENOENT
8213 # #define OBD_FAIL_SRV_ENOENT 0x217
8214 test_69() {
8215         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8216         remote_ost_nodsh && skip "remote OST with nodsh"
8217
8218         f="$DIR/$tfile"
8219         $LFS setstripe -c 1 -i 0 $f
8220
8221         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
8222
8223         do_facet ost1 lctl set_param fail_loc=0x217
8224         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
8225         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
8226
8227         do_facet ost1 lctl set_param fail_loc=0
8228         $DIRECTIO write $f 0 2 || error "write error"
8229
8230         cancel_lru_locks osc
8231         $DIRECTIO read $f 0 1 || error "read error"
8232
8233         do_facet ost1 lctl set_param fail_loc=0x217
8234         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
8235
8236         do_facet ost1 lctl set_param fail_loc=0
8237         rm -f $f
8238 }
8239 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
8240
8241 test_71() {
8242         test_mkdir $DIR/$tdir
8243         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
8244         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
8245 }
8246 run_test 71 "Running dbench on lustre (don't segment fault) ===="
8247
8248 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
8249         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8250         [ "$RUNAS_ID" = "$UID" ] &&
8251                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8252         # Check that testing environment is properly set up. Skip if not
8253         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
8254                 skip_env "User $RUNAS_ID does not exist - skipping"
8255
8256         touch $DIR/$tfile
8257         chmod 777 $DIR/$tfile
8258         chmod ug+s $DIR/$tfile
8259         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
8260                 error "$RUNAS dd $DIR/$tfile failed"
8261         # See if we are still setuid/sgid
8262         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8263                 error "S/gid is not dropped on write"
8264         # Now test that MDS is updated too
8265         cancel_lru_locks mdc
8266         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8267                 error "S/gid is not dropped on MDS"
8268         rm -f $DIR/$tfile
8269 }
8270 run_test 72a "Test that remove suid works properly (bug5695) ===="
8271
8272 test_72b() { # bug 24226 -- keep mode setting when size is not changing
8273         local perm
8274
8275         [ "$RUNAS_ID" = "$UID" ] &&
8276                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8277         [ "$RUNAS_ID" -eq 0 ] &&
8278                 skip_env "RUNAS_ID = 0 -- skipping"
8279         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8280         # Check that testing environment is properly set up. Skip if not
8281         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
8282                 skip_env "User $RUNAS_ID does not exist - skipping"
8283
8284         touch $DIR/${tfile}-f{g,u}
8285         test_mkdir $DIR/${tfile}-dg
8286         test_mkdir $DIR/${tfile}-du
8287         chmod 770 $DIR/${tfile}-{f,d}{g,u}
8288         chmod g+s $DIR/${tfile}-{f,d}g
8289         chmod u+s $DIR/${tfile}-{f,d}u
8290         for perm in 777 2777 4777; do
8291                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
8292                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
8293                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
8294                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
8295         done
8296         true
8297 }
8298 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
8299
8300 # bug 3462 - multiple simultaneous MDC requests
8301 test_73() {
8302         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8303
8304         test_mkdir $DIR/d73-1
8305         test_mkdir $DIR/d73-2
8306         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
8307         pid1=$!
8308
8309         lctl set_param fail_loc=0x80000129
8310         $MULTIOP $DIR/d73-1/f73-2 Oc &
8311         sleep 1
8312         lctl set_param fail_loc=0
8313
8314         $MULTIOP $DIR/d73-2/f73-3 Oc &
8315         pid3=$!
8316
8317         kill -USR1 $pid1
8318         wait $pid1 || return 1
8319
8320         sleep 25
8321
8322         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
8323         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
8324         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
8325
8326         rm -rf $DIR/d73-*
8327 }
8328 run_test 73 "multiple MDC requests (should not deadlock)"
8329
8330 test_74a() { # bug 6149, 6184
8331         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8332
8333         touch $DIR/f74a
8334         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8335         #
8336         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8337         # will spin in a tight reconnection loop
8338         $LCTL set_param fail_loc=0x8000030e
8339         # get any lock that won't be difficult - lookup works.
8340         ls $DIR/f74a
8341         $LCTL set_param fail_loc=0
8342         rm -f $DIR/f74a
8343         true
8344 }
8345 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
8346
8347 test_74b() { # bug 13310
8348         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8349
8350         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8351         #
8352         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8353         # will spin in a tight reconnection loop
8354         $LCTL set_param fail_loc=0x8000030e
8355         # get a "difficult" lock
8356         touch $DIR/f74b
8357         $LCTL set_param fail_loc=0
8358         rm -f $DIR/f74b
8359         true
8360 }
8361 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
8362
8363 test_74c() {
8364         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8365
8366         #define OBD_FAIL_LDLM_NEW_LOCK
8367         $LCTL set_param fail_loc=0x319
8368         touch $DIR/$tfile && error "touch successful"
8369         $LCTL set_param fail_loc=0
8370         true
8371 }
8372 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
8373
8374 num_inodes() {
8375         awk '/lustre_inode_cache/ {print $2; exit}' /proc/slabinfo
8376 }
8377
8378 test_76() { # Now for bug 20433, added originally in bug 1443
8379         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8380
8381         cancel_lru_locks osc
8382         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
8383         local before=$(num_inodes)
8384         local count=$((512 * cpus))
8385         [ "$SLOW" = "no" ] && count=$((64 * cpus))
8386
8387         echo "before inodes: $before"
8388         for i in $(seq $count); do
8389                 touch $DIR/$tfile
8390                 rm -f $DIR/$tfile
8391         done
8392         cancel_lru_locks osc
8393         local after=$(num_inodes)
8394         echo "after inodes: $after"
8395         while (( after > before + 8 * ${cpus:-1} )); do
8396                 sleep 1
8397                 after=$(num_inodes)
8398                 wait=$((wait + 1))
8399                 (( wait % 5 == 0 )) && echo "wait $wait seconds inodes: $after"
8400                 if (( wait > 30 )); then
8401                         error "inode slab grew from $before to $after"
8402                 fi
8403         done
8404 }
8405 run_test 76 "confirm clients recycle inodes properly ===="
8406
8407
8408 export ORIG_CSUM=""
8409 set_checksums()
8410 {
8411         # Note: in sptlrpc modes which enable its own bulk checksum, the
8412         # original crc32_le bulk checksum will be automatically disabled,
8413         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
8414         # will be checked by sptlrpc code against sptlrpc bulk checksum.
8415         # In this case set_checksums() will not be no-op, because sptlrpc
8416         # bulk checksum will be enabled all through the test.
8417
8418         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
8419         lctl set_param -n osc.*.checksums $1
8420         return 0
8421 }
8422
8423 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8424                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
8425 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8426                              tr -d [] | head -n1)}
8427 set_checksum_type()
8428 {
8429         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
8430         rc=$?
8431         log "set checksum type to $1, rc = $rc"
8432         return $rc
8433 }
8434
8435 get_osc_checksum_type()
8436 {
8437         # arugment 1: OST name, like OST0000
8438         ost=$1
8439         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
8440                         sed 's/.*\[\(.*\)\].*/\1/g')
8441         rc=$?
8442         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
8443         echo $checksum_type
8444 }
8445
8446 F77_TMP=$TMP/f77-temp
8447 F77SZ=8
8448 setup_f77() {
8449         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
8450                 error "error writing to $F77_TMP"
8451 }
8452
8453 test_77a() { # bug 10889
8454         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8455         $GSS && skip_env "could not run with gss"
8456
8457         [ ! -f $F77_TMP ] && setup_f77
8458         set_checksums 1
8459         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
8460         set_checksums 0
8461         rm -f $DIR/$tfile
8462 }
8463 run_test 77a "normal checksum read/write operation"
8464
8465 test_77b() { # bug 10889
8466         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8467         $GSS && skip_env "could not run with gss"
8468
8469         [ ! -f $F77_TMP ] && setup_f77
8470         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8471         $LCTL set_param fail_loc=0x80000409
8472         set_checksums 1
8473
8474         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8475                 error "dd error: $?"
8476         $LCTL set_param fail_loc=0
8477
8478         for algo in $CKSUM_TYPES; do
8479                 cancel_lru_locks osc
8480                 set_checksum_type $algo
8481                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8482                 $LCTL set_param fail_loc=0x80000408
8483                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
8484                 $LCTL set_param fail_loc=0
8485         done
8486         set_checksums 0
8487         set_checksum_type $ORIG_CSUM_TYPE
8488         rm -f $DIR/$tfile
8489 }
8490 run_test 77b "checksum error on client write, read"
8491
8492 cleanup_77c() {
8493         trap 0
8494         set_checksums 0
8495         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
8496         $check_ost &&
8497                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
8498         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
8499         $check_ost && [ -n "$ost_file_prefix" ] &&
8500                 do_facet ost1 rm -f ${ost_file_prefix}\*
8501 }
8502
8503 test_77c() {
8504         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8505         $GSS && skip_env "could not run with gss"
8506         remote_ost_nodsh && skip "remote OST with nodsh"
8507
8508         local bad1
8509         local osc_file_prefix
8510         local osc_file
8511         local check_ost=false
8512         local ost_file_prefix
8513         local ost_file
8514         local orig_cksum
8515         local dump_cksum
8516         local fid
8517
8518         # ensure corruption will occur on first OSS/OST
8519         $LFS setstripe -i 0 $DIR/$tfile
8520
8521         [ ! -f $F77_TMP ] && setup_f77
8522         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8523                 error "dd write error: $?"
8524         fid=$($LFS path2fid $DIR/$tfile)
8525
8526         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
8527         then
8528                 check_ost=true
8529                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
8530                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
8531         else
8532                 echo "OSS do not support bulk pages dump upon error"
8533         fi
8534
8535         osc_file_prefix=$($LCTL get_param -n debug_path)
8536         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
8537
8538         trap cleanup_77c EXIT
8539
8540         set_checksums 1
8541         # enable bulk pages dump upon error on Client
8542         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
8543         # enable bulk pages dump upon error on OSS
8544         $check_ost &&
8545                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
8546
8547         # flush Client cache to allow next read to reach OSS
8548         cancel_lru_locks osc
8549
8550         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
8551         $LCTL set_param fail_loc=0x80000408
8552         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
8553         $LCTL set_param fail_loc=0
8554
8555         rm -f $DIR/$tfile
8556
8557         # check cksum dump on Client
8558         osc_file=$(ls ${osc_file_prefix}*)
8559         [ -n "$osc_file" ] || error "no checksum dump file on Client"
8560         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
8561         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
8562         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
8563         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
8564                      cksum)
8565         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
8566         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8567                 error "dump content does not match on Client"
8568
8569         $check_ost || skip "No need to check cksum dump on OSS"
8570
8571         # check cksum dump on OSS
8572         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
8573         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
8574         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
8575         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
8576         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8577                 error "dump content does not match on OSS"
8578
8579         cleanup_77c
8580 }
8581 run_test 77c "checksum error on client read with debug"
8582
8583 test_77d() { # bug 10889
8584         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8585         $GSS && skip_env "could not run with gss"
8586
8587         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8588         $LCTL set_param fail_loc=0x80000409
8589         set_checksums 1
8590         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8591                 error "direct write: rc=$?"
8592         $LCTL set_param fail_loc=0
8593         set_checksums 0
8594
8595         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8596         $LCTL set_param fail_loc=0x80000408
8597         set_checksums 1
8598         cancel_lru_locks osc
8599         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8600                 error "direct read: rc=$?"
8601         $LCTL set_param fail_loc=0
8602         set_checksums 0
8603 }
8604 run_test 77d "checksum error on OST direct write, read"
8605
8606 test_77f() { # bug 10889
8607         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8608         $GSS && skip_env "could not run with gss"
8609
8610         set_checksums 1
8611         for algo in $CKSUM_TYPES; do
8612                 cancel_lru_locks osc
8613                 set_checksum_type $algo
8614                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8615                 $LCTL set_param fail_loc=0x409
8616                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
8617                         error "direct write succeeded"
8618                 $LCTL set_param fail_loc=0
8619         done
8620         set_checksum_type $ORIG_CSUM_TYPE
8621         set_checksums 0
8622 }
8623 run_test 77f "repeat checksum error on write (expect error)"
8624
8625 test_77g() { # bug 10889
8626         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8627         $GSS && skip_env "could not run with gss"
8628         remote_ost_nodsh && skip "remote OST with nodsh"
8629
8630         [ ! -f $F77_TMP ] && setup_f77
8631
8632         local file=$DIR/$tfile
8633         stack_trap "rm -f $file" EXIT
8634
8635         $LFS setstripe -c 1 -i 0 $file
8636         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
8637         do_facet ost1 lctl set_param fail_loc=0x8000021a
8638         set_checksums 1
8639         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
8640                 error "write error: rc=$?"
8641         do_facet ost1 lctl set_param fail_loc=0
8642         set_checksums 0
8643
8644         cancel_lru_locks osc
8645         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
8646         do_facet ost1 lctl set_param fail_loc=0x8000021b
8647         set_checksums 1
8648         cmp $F77_TMP $file || error "file compare failed"
8649         do_facet ost1 lctl set_param fail_loc=0
8650         set_checksums 0
8651 }
8652 run_test 77g "checksum error on OST write, read"
8653
8654 test_77k() { # LU-10906
8655         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8656         $GSS && skip_env "could not run with gss"
8657
8658         local cksum_param="osc.$FSNAME*.checksums"
8659         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
8660         local checksum
8661         local i
8662
8663         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
8664         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM" EXIT
8665         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM" \
8666                 EXIT
8667
8668         for i in 0 1; do
8669                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
8670                         error "failed to set checksum=$i on MGS"
8671                 wait_update $HOSTNAME "$get_checksum" $i
8672                 #remount
8673                 echo "remount client, checksum should be $i"
8674                 remount_client $MOUNT || error "failed to remount client"
8675                 checksum=$(eval $get_checksum)
8676                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
8677         done
8678         # remove persistent param to avoid races with checksum mountopt below
8679         do_facet mgs $LCTL set_param -P -d $cksum_param ||
8680                 error "failed to delete checksum on MGS"
8681
8682         for opt in "checksum" "nochecksum"; do
8683                 #remount with mount option
8684                 echo "remount client with option $opt, checksum should be $i"
8685                 umount_client $MOUNT || error "failed to umount client"
8686                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
8687                         error "failed to mount client with option '$opt'"
8688                 checksum=$(eval $get_checksum)
8689                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
8690                 i=$((i - 1))
8691         done
8692
8693         remount_client $MOUNT || error "failed to remount client"
8694 }
8695 run_test 77k "enable/disable checksum correctly"
8696
8697 test_77l() {
8698         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8699         $GSS && skip_env "could not run with gss"
8700
8701         set_checksums 1
8702         stack_trap "set_checksums $ORIG_CSUM" EXIT
8703         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
8704
8705         set_checksum_type invalid && error "unexpected success of invalid checksum type"
8706
8707         $LFS setstripe -c 1 -i 0 $DIR/$tfile
8708         for algo in $CKSUM_TYPES; do
8709                 set_checksum_type $algo || error "fail to set checksum type $algo"
8710                 osc_algo=$(get_osc_checksum_type OST0000)
8711                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
8712
8713                 # no locks, no reqs to let the connection idle
8714                 cancel_lru_locks osc
8715                 lru_resize_disable osc
8716                 wait_osc_import_state client ost1 IDLE
8717
8718                 # ensure ost1 is connected
8719                 stat $DIR/$tfile >/dev/null || error "can't stat"
8720                 wait_osc_import_state client ost1 FULL
8721
8722                 osc_algo=$(get_osc_checksum_type OST0000)
8723                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
8724         done
8725         return 0
8726 }
8727 run_test 77l "preferred checksum type is remembered after reconnected"
8728
8729 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
8730 rm -f $F77_TMP
8731 unset F77_TMP
8732
8733 cleanup_test_78() {
8734         trap 0
8735         rm -f $DIR/$tfile
8736 }
8737
8738 test_78() { # bug 10901
8739         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8740         remote_ost || skip_env "local OST"
8741
8742         NSEQ=5
8743         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
8744         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
8745         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
8746         echo "MemTotal: $MEMTOTAL"
8747
8748         # reserve 256MB of memory for the kernel and other running processes,
8749         # and then take 1/2 of the remaining memory for the read/write buffers.
8750         if [ $MEMTOTAL -gt 512 ] ;then
8751                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
8752         else
8753                 # for those poor memory-starved high-end clusters...
8754                 MEMTOTAL=$((MEMTOTAL / 2))
8755         fi
8756         echo "Mem to use for directio: $MEMTOTAL"
8757
8758         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
8759         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
8760         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
8761         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
8762                 head -n1)
8763         echo "Smallest OST: $SMALLESTOST"
8764         [[ $SMALLESTOST -lt 10240 ]] &&
8765                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
8766
8767         trap cleanup_test_78 EXIT
8768
8769         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
8770                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
8771
8772         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
8773         echo "File size: $F78SIZE"
8774         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
8775         for i in $(seq 1 $NSEQ); do
8776                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
8777                 echo directIO rdwr round $i of $NSEQ
8778                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
8779         done
8780
8781         cleanup_test_78
8782 }
8783 run_test 78 "handle large O_DIRECT writes correctly ============"
8784
8785 test_79() { # bug 12743
8786         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8787
8788         wait_delete_completed
8789
8790         BKTOTAL=$(calc_osc_kbytes kbytestotal)
8791         BKFREE=$(calc_osc_kbytes kbytesfree)
8792         BKAVAIL=$(calc_osc_kbytes kbytesavail)
8793
8794         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
8795         DFTOTAL=`echo $STRING | cut -d, -f1`
8796         DFUSED=`echo $STRING  | cut -d, -f2`
8797         DFAVAIL=`echo $STRING | cut -d, -f3`
8798         DFFREE=$(($DFTOTAL - $DFUSED))
8799
8800         ALLOWANCE=$((64 * $OSTCOUNT))
8801
8802         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
8803            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
8804                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
8805         fi
8806         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
8807            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
8808                 error "df free($DFFREE) mismatch OST free($BKFREE)"
8809         fi
8810         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
8811            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
8812                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
8813         fi
8814 }
8815 run_test 79 "df report consistency check ======================="
8816
8817 test_80() { # bug 10718
8818         remote_ost_nodsh && skip "remote OST with nodsh"
8819         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8820
8821         # relax strong synchronous semantics for slow backends like ZFS
8822         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
8823                 local soc="obdfilter.*.sync_lock_cancel"
8824                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
8825
8826                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
8827                 if [ -z "$save" ]; then
8828                         soc="obdfilter.*.sync_on_lock_cancel"
8829                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
8830                 fi
8831
8832                 if [ "$save" != "never" ]; then
8833                         local hosts=$(comma_list $(osts_nodes))
8834
8835                         do_nodes $hosts $LCTL set_param $soc=never
8836                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
8837                 fi
8838         fi
8839
8840         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
8841         sync; sleep 1; sync
8842         local before=$(date +%s)
8843         cancel_lru_locks osc
8844         local after=$(date +%s)
8845         local diff=$((after - before))
8846         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
8847
8848         rm -f $DIR/$tfile
8849 }
8850 run_test 80 "Page eviction is equally fast at high offsets too"
8851
8852 test_81a() { # LU-456
8853         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8854         remote_ost_nodsh && skip "remote OST with nodsh"
8855
8856         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
8857         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
8858         do_facet ost1 lctl set_param fail_loc=0x80000228
8859
8860         # write should trigger a retry and success
8861         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8862         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
8863         RC=$?
8864         if [ $RC -ne 0 ] ; then
8865                 error "write should success, but failed for $RC"
8866         fi
8867 }
8868 run_test 81a "OST should retry write when get -ENOSPC ==============="
8869
8870 test_81b() { # LU-456
8871         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8872         remote_ost_nodsh && skip "remote OST with nodsh"
8873
8874         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
8875         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
8876         do_facet ost1 lctl set_param fail_loc=0x228
8877
8878         # write should retry several times and return -ENOSPC finally
8879         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8880         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
8881         RC=$?
8882         ENOSPC=28
8883         if [ $RC -ne $ENOSPC ] ; then
8884                 error "dd should fail for -ENOSPC, but succeed."
8885         fi
8886 }
8887 run_test 81b "OST should return -ENOSPC when retry still fails ======="
8888
8889 test_82() { # LU-1031
8890         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10
8891         local gid1=14091995
8892         local gid2=16022000
8893
8894         multiop_bg_pause $DIR/$tfile OG${gid1}_g${gid1}c || return 1
8895         local MULTIPID1=$!
8896         multiop_bg_pause $DIR/$tfile O_G${gid2}r10g${gid2}c || return 2
8897         local MULTIPID2=$!
8898         kill -USR1 $MULTIPID2
8899         sleep 2
8900         if [[ `ps h -o comm -p $MULTIPID2` == "" ]]; then
8901                 error "First grouplock does not block second one"
8902         else
8903                 echo "Second grouplock blocks first one"
8904         fi
8905         kill -USR1 $MULTIPID1
8906         wait $MULTIPID1
8907         wait $MULTIPID2
8908 }
8909 run_test 82 "Basic grouplock test"
8910
8911 test_99() {
8912         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
8913
8914         test_mkdir $DIR/$tdir.cvsroot
8915         chown $RUNAS_ID $DIR/$tdir.cvsroot
8916
8917         cd $TMP
8918         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
8919
8920         cd /etc/init.d
8921         # some versions of cvs import exit(1) when asked to import links or
8922         # files they can't read.  ignore those files.
8923         local toignore=$(find . -type l -printf '-I %f\n' -o \
8924                          ! -perm /4 -printf '-I %f\n')
8925         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
8926                 $tdir.reposname vtag rtag
8927
8928         cd $DIR
8929         test_mkdir $DIR/$tdir.reposname
8930         chown $RUNAS_ID $DIR/$tdir.reposname
8931         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
8932
8933         cd $DIR/$tdir.reposname
8934         $RUNAS touch foo99
8935         $RUNAS cvs add -m 'addmsg' foo99
8936         $RUNAS cvs update
8937         $RUNAS cvs commit -m 'nomsg' foo99
8938         rm -fr $DIR/$tdir.cvsroot
8939 }
8940 run_test 99 "cvs strange file/directory operations"
8941
8942 test_100() {
8943         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8944         [[ "$NETTYPE" =~ tcp ]] ||
8945                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
8946         remote_ost_nodsh && skip "remote OST with nodsh"
8947         remote_mds_nodsh && skip "remote MDS with nodsh"
8948         remote_servers ||
8949                 skip "useless for local single node setup"
8950
8951         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
8952                 [ "$PROT" != "tcp" ] && continue
8953                 RPORT=$(echo $REMOTE | cut -d: -f2)
8954                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
8955
8956                 rc=0
8957                 LPORT=`echo $LOCAL | cut -d: -f2`
8958                 if [ $LPORT -ge 1024 ]; then
8959                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
8960                         netstat -tna
8961                         error_exit "local: $LPORT > 1024, remote: $RPORT"
8962                 fi
8963         done
8964         [ "$rc" = 0 ] || error_exit "privileged port not found" )
8965 }
8966 run_test 100 "check local port using privileged port ==========="
8967
8968 function get_named_value()
8969 {
8970     local tag
8971
8972     tag=$1
8973     while read ;do
8974         line=$REPLY
8975         case $line in
8976         $tag*)
8977             echo $line | sed "s/^$tag[ ]*//"
8978             break
8979             ;;
8980         esac
8981     done
8982 }
8983
8984 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
8985                    awk '/^max_cached_mb/ { print $2 }')
8986
8987 cleanup_101a() {
8988         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
8989         trap 0
8990 }
8991
8992 test_101a() {
8993         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8994
8995         local s
8996         local discard
8997         local nreads=10000
8998         local cache_limit=32
8999
9000         $LCTL set_param -n osc.*-osc*.rpc_stats 0
9001         trap cleanup_101a EXIT
9002         $LCTL set_param -n llite.*.read_ahead_stats 0
9003         $LCTL set_param -n llite.*.max_cached_mb $cache_limit
9004
9005         #
9006         # randomly read 10000 of 64K chunks from file 3x 32MB in size
9007         #
9008         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
9009         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
9010
9011         discard=0
9012         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
9013                 get_named_value 'read but discarded' | cut -d" " -f1); do
9014                         discard=$(($discard + $s))
9015         done
9016         cleanup_101a
9017
9018         $LCTL get_param osc.*-osc*.rpc_stats
9019         $LCTL get_param llite.*.read_ahead_stats
9020
9021         # Discard is generally zero, but sometimes a few random reads line up
9022         # and trigger larger readahead, which is wasted & leads to discards.
9023         if [[ $(($discard)) -gt $nreads ]]; then
9024                 error "too many ($discard) discarded pages"
9025         fi
9026         rm -f $DIR/$tfile || true
9027 }
9028 run_test 101a "check read-ahead for random reads"
9029
9030 setup_test101bc() {
9031         test_mkdir $DIR/$tdir
9032         local ssize=$1
9033         local FILE_LENGTH=$2
9034         STRIPE_OFFSET=0
9035
9036         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
9037
9038         local list=$(comma_list $(osts_nodes))
9039         set_osd_param $list '' read_cache_enable 0
9040         set_osd_param $list '' writethrough_cache_enable 0
9041
9042         trap cleanup_test101bc EXIT
9043         # prepare the read-ahead file
9044         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
9045
9046         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
9047                                 count=$FILE_SIZE_MB 2> /dev/null
9048
9049 }
9050
9051 cleanup_test101bc() {
9052         trap 0
9053         rm -rf $DIR/$tdir
9054         rm -f $DIR/$tfile
9055
9056         local list=$(comma_list $(osts_nodes))
9057         set_osd_param $list '' read_cache_enable 1
9058         set_osd_param $list '' writethrough_cache_enable 1
9059 }
9060
9061 calc_total() {
9062         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
9063 }
9064
9065 ra_check_101() {
9066         local READ_SIZE=$1
9067         local STRIPE_SIZE=$2
9068         local FILE_LENGTH=$3
9069         local RA_INC=1048576
9070         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
9071         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
9072                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
9073         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
9074                         get_named_value 'read but discarded' |
9075                         cut -d" " -f1 | calc_total)
9076         if [[ $DISCARD -gt $discard_limit ]]; then
9077                 $LCTL get_param llite.*.read_ahead_stats
9078                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
9079         else
9080                 echo "Read-ahead success for size ${READ_SIZE}"
9081         fi
9082 }
9083
9084 test_101b() {
9085         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9086         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9087
9088         local STRIPE_SIZE=1048576
9089         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
9090
9091         if [ $SLOW == "yes" ]; then
9092                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
9093         else
9094                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
9095         fi
9096
9097         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
9098
9099         # prepare the read-ahead file
9100         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9101         cancel_lru_locks osc
9102         for BIDX in 2 4 8 16 32 64 128 256
9103         do
9104                 local BSIZE=$((BIDX*4096))
9105                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
9106                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
9107                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
9108                 $LCTL set_param -n llite.*.read_ahead_stats 0
9109                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
9110                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
9111                 cancel_lru_locks osc
9112                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
9113         done
9114         cleanup_test101bc
9115         true
9116 }
9117 run_test 101b "check stride-io mode read-ahead ================="
9118
9119 test_101c() {
9120         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9121
9122         local STRIPE_SIZE=1048576
9123         local FILE_LENGTH=$((STRIPE_SIZE*100))
9124         local nreads=10000
9125         local rsize=65536
9126         local osc_rpc_stats
9127
9128         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9129
9130         cancel_lru_locks osc
9131         $LCTL set_param osc.*.rpc_stats 0
9132         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
9133         $LCTL get_param osc.*.rpc_stats
9134         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
9135                 local stats=$($LCTL get_param -n $osc_rpc_stats)
9136                 local lines=$(echo "$stats" | awk 'END {print NR;}')
9137                 local size
9138
9139                 if [ $lines -le 20 ]; then
9140                         echo "continue debug"
9141                         continue
9142                 fi
9143                 for size in 1 2 4 8; do
9144                         local rpc=$(echo "$stats" |
9145                                     awk '($1 == "'$size':") {print $2; exit; }')
9146                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
9147                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
9148                 done
9149                 echo "$osc_rpc_stats check passed!"
9150         done
9151         cleanup_test101bc
9152         true
9153 }
9154 run_test 101c "check stripe_size aligned read-ahead ================="
9155
9156 test_101d() {
9157         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9158
9159         local file=$DIR/$tfile
9160         local sz_MB=${FILESIZE_101d:-80}
9161         local ra_MB=${READAHEAD_MB:-40}
9162
9163         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
9164         [ $free_MB -lt $sz_MB ] &&
9165                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
9166
9167         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
9168         $LFS setstripe -c -1 $file || error "setstripe failed"
9169
9170         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
9171         echo Cancel LRU locks on lustre client to flush the client cache
9172         cancel_lru_locks osc
9173
9174         echo Disable read-ahead
9175         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9176         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9177         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_RA" EXIT
9178         $LCTL get_param -n llite.*.max_read_ahead_mb
9179
9180         echo "Reading the test file $file with read-ahead disabled"
9181         local sz_KB=$((sz_MB * 1024 / 4))
9182         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
9183         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
9184         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9185                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9186
9187         echo "Cancel LRU locks on lustre client to flush the client cache"
9188         cancel_lru_locks osc
9189         echo Enable read-ahead with ${ra_MB}MB
9190         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
9191
9192         echo "Reading the test file $file with read-ahead enabled"
9193         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9194                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9195
9196         echo "read-ahead disabled time read $raOFF"
9197         echo "read-ahead enabled time read $raON"
9198
9199         rm -f $file
9200         wait_delete_completed
9201
9202         # use awk for this check instead of bash because it handles decimals
9203         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
9204                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
9205 }
9206 run_test 101d "file read with and without read-ahead enabled"
9207
9208 test_101e() {
9209         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9210
9211         local file=$DIR/$tfile
9212         local size_KB=500  #KB
9213         local count=100
9214         local bsize=1024
9215
9216         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
9217         local need_KB=$((count * size_KB))
9218         [[ $free_KB -le $need_KB ]] &&
9219                 skip_env "Need free space $need_KB, have $free_KB"
9220
9221         echo "Creating $count ${size_KB}K test files"
9222         for ((i = 0; i < $count; i++)); do
9223                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
9224         done
9225
9226         echo "Cancel LRU locks on lustre client to flush the client cache"
9227         cancel_lru_locks $OSC
9228
9229         echo "Reset readahead stats"
9230         $LCTL set_param -n llite.*.read_ahead_stats 0
9231
9232         for ((i = 0; i < $count; i++)); do
9233                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
9234         done
9235
9236         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9237                      get_named_value 'misses' | cut -d" " -f1 | calc_total)
9238
9239         for ((i = 0; i < $count; i++)); do
9240                 rm -rf $file.$i 2>/dev/null
9241         done
9242
9243         #10000 means 20% reads are missing in readahead
9244         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
9245 }
9246 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
9247
9248 test_101f() {
9249         which iozone || skip_env "no iozone installed"
9250
9251         local old_debug=$($LCTL get_param debug)
9252         old_debug=${old_debug#*=}
9253         $LCTL set_param debug="reada mmap"
9254
9255         # create a test file
9256         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
9257
9258         echo Cancel LRU locks on lustre client to flush the client cache
9259         cancel_lru_locks osc
9260
9261         echo Reset readahead stats
9262         $LCTL set_param -n llite.*.read_ahead_stats 0
9263
9264         echo mmap read the file with small block size
9265         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
9266                 > /dev/null 2>&1
9267
9268         echo checking missing pages
9269         $LCTL get_param llite.*.read_ahead_stats
9270         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9271                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9272
9273         $LCTL set_param debug="$old_debug"
9274         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
9275         rm -f $DIR/$tfile
9276 }
9277 run_test 101f "check mmap read performance"
9278
9279 test_101g_brw_size_test() {
9280         local mb=$1
9281         local pages=$((mb * 1048576 / PAGE_SIZE))
9282         local file=$DIR/$tfile
9283
9284         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
9285                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
9286         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
9287                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
9288                         return 2
9289         done
9290
9291         stack_trap "rm -f $file" EXIT
9292         $LCTL set_param -n osc.*.rpc_stats=0
9293
9294         # 10 RPCs should be enough for the test
9295         local count=10
9296         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
9297                 { error "dd write ${mb} MB blocks failed"; return 3; }
9298         cancel_lru_locks osc
9299         dd of=/dev/null if=$file bs=${mb}M count=$count ||
9300                 { error "dd write ${mb} MB blocks failed"; return 4; }
9301
9302         # calculate number of full-sized read and write RPCs
9303         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
9304                 sed -n '/pages per rpc/,/^$/p' |
9305                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
9306                 END { print reads,writes }'))
9307         [ ${rpcs[0]} -ne $count ] && error "${rpcs[0]} != $count read RPCs" &&
9308                 return 5
9309         [ ${rpcs[1]} -ne $count ] && error "${rpcs[1]} != $count write RPCs" &&
9310                 return 6
9311
9312         return 0
9313 }
9314
9315 test_101g() {
9316         remote_ost_nodsh && skip "remote OST with nodsh"
9317
9318         local rpcs
9319         local osts=$(get_facets OST)
9320         local list=$(comma_list $(osts_nodes))
9321         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9322         local brw_size="obdfilter.*.brw_size"
9323
9324         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9325
9326         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
9327
9328         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
9329                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
9330                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
9331            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
9332                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
9333                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
9334
9335                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
9336                         suffix="M"
9337
9338                 if [[ $orig_mb -lt 16 ]]; then
9339                         save_lustre_params $osts "$brw_size" > $p
9340                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
9341                                 error "set 16MB RPC size failed"
9342
9343                         echo "remount client to enable new RPC size"
9344                         remount_client $MOUNT || error "remount_client failed"
9345                 fi
9346
9347                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
9348                 # should be able to set brw_size=12, but no rpc_stats for that
9349                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
9350         fi
9351
9352         test_101g_brw_size_test 4 || error "4MB RPC test failed"
9353
9354         if [[ $orig_mb -lt 16 ]]; then
9355                 restore_lustre_params < $p
9356                 remount_client $MOUNT || error "remount_client restore failed"
9357         fi
9358
9359         rm -f $p $DIR/$tfile
9360 }
9361 run_test 101g "Big bulk(4/16 MiB) readahead"
9362
9363 test_101h() {
9364         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9365
9366         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
9367                 error "dd 70M file failed"
9368         echo Cancel LRU locks on lustre client to flush the client cache
9369         cancel_lru_locks osc
9370
9371         echo "Reset readahead stats"
9372         $LCTL set_param -n llite.*.read_ahead_stats 0
9373
9374         echo "Read 10M of data but cross 64M bundary"
9375         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
9376         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9377                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9378         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
9379         rm -f $p $DIR/$tfile
9380 }
9381 run_test 101h "Readahead should cover current read window"
9382
9383 test_101i() {
9384         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
9385                 error "dd 10M file failed"
9386
9387         local max_per_file_mb=$($LCTL get_param -n \
9388                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
9389         cancel_lru_locks osc
9390         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
9391         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
9392                 error "set max_read_ahead_per_file_mb to 1 failed"
9393
9394         echo "Reset readahead stats"
9395         $LCTL set_param llite.*.read_ahead_stats=0
9396
9397         dd if=$DIR/$tfile of=/dev/null bs=2M
9398
9399         $LCTL get_param llite.*.read_ahead_stats
9400         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9401                      awk '/misses/ { print $2 }')
9402         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
9403         rm -f $DIR/$tfile
9404 }
9405 run_test 101i "allow current readahead to exceed reservation"
9406
9407 test_101j() {
9408         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
9409                 error "setstripe $DIR/$tfile failed"
9410         local file_size=$((1048576 * 16))
9411         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9412         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
9413
9414         echo Disable read-ahead
9415         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9416
9417         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
9418         for blk in $PAGE_SIZE 1048576 $file_size; do
9419                 cancel_lru_locks osc
9420                 echo "Reset readahead stats"
9421                 $LCTL set_param -n llite.*.read_ahead_stats=0
9422                 local count=$(($file_size / $blk))
9423                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
9424                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9425                              get_named_value 'failed to fast read' |
9426                              cut -d" " -f1 | calc_total)
9427                 $LCTL get_param -n llite.*.read_ahead_stats
9428                 [ $miss -eq $count ] || error "expected $count got $miss"
9429         done
9430
9431         rm -f $p $DIR/$tfile
9432 }
9433 run_test 101j "A complete read block should be submitted when no RA"
9434
9435 setup_test102() {
9436         test_mkdir $DIR/$tdir
9437         chown $RUNAS_ID $DIR/$tdir
9438         STRIPE_SIZE=65536
9439         STRIPE_OFFSET=1
9440         STRIPE_COUNT=$OSTCOUNT
9441         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
9442
9443         trap cleanup_test102 EXIT
9444         cd $DIR
9445         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
9446         cd $DIR/$tdir
9447         for num in 1 2 3 4; do
9448                 for count in $(seq 1 $STRIPE_COUNT); do
9449                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
9450                                 local size=`expr $STRIPE_SIZE \* $num`
9451                                 local file=file"$num-$idx-$count"
9452                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
9453                         done
9454                 done
9455         done
9456
9457         cd $DIR
9458         $1 tar cf $TMP/f102.tar $tdir --xattrs
9459 }
9460
9461 cleanup_test102() {
9462         trap 0
9463         rm -f $TMP/f102.tar
9464         rm -rf $DIR/d0.sanity/d102
9465 }
9466
9467 test_102a() {
9468         [ "$UID" != 0 ] && skip "must run as root"
9469         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
9470                 skip_env "must have user_xattr"
9471
9472         [ -z "$(which setfattr 2>/dev/null)" ] &&
9473                 skip_env "could not find setfattr"
9474
9475         local testfile=$DIR/$tfile
9476
9477         touch $testfile
9478         echo "set/get xattr..."
9479         setfattr -n trusted.name1 -v value1 $testfile ||
9480                 error "setfattr -n trusted.name1=value1 $testfile failed"
9481         getfattr -n trusted.name1 $testfile 2> /dev/null |
9482           grep "trusted.name1=.value1" ||
9483                 error "$testfile missing trusted.name1=value1"
9484
9485         setfattr -n user.author1 -v author1 $testfile ||
9486                 error "setfattr -n user.author1=author1 $testfile failed"
9487         getfattr -n user.author1 $testfile 2> /dev/null |
9488           grep "user.author1=.author1" ||
9489                 error "$testfile missing trusted.author1=author1"
9490
9491         echo "listxattr..."
9492         setfattr -n trusted.name2 -v value2 $testfile ||
9493                 error "$testfile unable to set trusted.name2"
9494         setfattr -n trusted.name3 -v value3 $testfile ||
9495                 error "$testfile unable to set trusted.name3"
9496         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
9497             grep "trusted.name" | wc -l) -eq 3 ] ||
9498                 error "$testfile missing 3 trusted.name xattrs"
9499
9500         setfattr -n user.author2 -v author2 $testfile ||
9501                 error "$testfile unable to set user.author2"
9502         setfattr -n user.author3 -v author3 $testfile ||
9503                 error "$testfile unable to set user.author3"
9504         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
9505             grep "user.author" | wc -l) -eq 3 ] ||
9506                 error "$testfile missing 3 user.author xattrs"
9507
9508         echo "remove xattr..."
9509         setfattr -x trusted.name1 $testfile ||
9510                 error "$testfile error deleting trusted.name1"
9511         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
9512                 error "$testfile did not delete trusted.name1 xattr"
9513
9514         setfattr -x user.author1 $testfile ||
9515                 error "$testfile error deleting user.author1"
9516         echo "set lustre special xattr ..."
9517         $LFS setstripe -c1 $testfile
9518         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
9519                 awk -F "=" '/trusted.lov/ { print $2 }' )
9520         setfattr -n "trusted.lov" -v $lovea $testfile ||
9521                 error "$testfile doesn't ignore setting trusted.lov again"
9522         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
9523                 error "$testfile allow setting invalid trusted.lov"
9524         rm -f $testfile
9525 }
9526 run_test 102a "user xattr test =================================="
9527
9528 test_102b() {
9529         [ -z "$(which setfattr 2>/dev/null)" ] &&
9530                 skip_env "could not find setfattr"
9531         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9532
9533         # b10930: get/set/list trusted.lov xattr
9534         echo "get/set/list trusted.lov xattr ..."
9535         local testfile=$DIR/$tfile
9536         $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
9537                 error "setstripe failed"
9538         local STRIPECOUNT=$($LFS getstripe -c $testfile) ||
9539                 error "getstripe failed"
9540         getfattr -d -m "^trusted" $testfile 2>/dev/null | grep "trusted.lov" ||
9541                 error "can't get trusted.lov from $testfile"
9542
9543         local testfile2=${testfile}2
9544         local value=$(getfattr -n trusted.lov $testfile 2>/dev/null |
9545                         grep "trusted.lov" | sed -e 's/[^=]\+=//')
9546
9547         $MCREATE $testfile2
9548         setfattr -n trusted.lov -v $value $testfile2
9549         local stripe_size=$($LFS getstripe -S $testfile2)
9550         local stripe_count=$($LFS getstripe -c $testfile2)
9551         [[ $stripe_size -eq 65536 ]] ||
9552                 error "stripe size $stripe_size != 65536"
9553         [[ $stripe_count -eq $STRIPECOUNT ]] ||
9554                 error "stripe count $stripe_count != $STRIPECOUNT"
9555         rm -f $DIR/$tfile
9556 }
9557 run_test 102b "getfattr/setfattr for trusted.lov EAs ============"
9558
9559 test_102c() {
9560         [ -z "$(which setfattr 2>/dev/null)" ] &&
9561                 skip_env "could not find setfattr"
9562         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9563
9564         # b10930: get/set/list lustre.lov xattr
9565         echo "get/set/list lustre.lov xattr ..."
9566         test_mkdir $DIR/$tdir
9567         chown $RUNAS_ID $DIR/$tdir
9568         local testfile=$DIR/$tdir/$tfile
9569         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
9570                 error "setstripe failed"
9571         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
9572                 error "getstripe failed"
9573         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
9574         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
9575
9576         local testfile2=${testfile}2
9577         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
9578                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
9579
9580         $RUNAS $MCREATE $testfile2
9581         $RUNAS setfattr -n lustre.lov -v $value $testfile2
9582         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
9583         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
9584         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
9585         [ $stripe_count -eq $STRIPECOUNT ] ||
9586                 error "stripe count $stripe_count != $STRIPECOUNT"
9587 }
9588 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
9589
9590 compare_stripe_info1() {
9591         local stripe_index_all_zero=true
9592
9593         for num in 1 2 3 4; do
9594                 for count in $(seq 1 $STRIPE_COUNT); do
9595                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
9596                                 local size=$((STRIPE_SIZE * num))
9597                                 local file=file"$num-$offset-$count"
9598                                 stripe_size=$($LFS getstripe -S $PWD/$file)
9599                                 [[ $stripe_size -ne $size ]] &&
9600                                     error "$file: size $stripe_size != $size"
9601                                 stripe_count=$($LFS getstripe -c $PWD/$file)
9602                                 # allow fewer stripes to be created, ORI-601
9603                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
9604                                     error "$file: count $stripe_count != $count"
9605                                 stripe_index=$($LFS getstripe -i $PWD/$file)
9606                                 [[ $stripe_index -ne 0 ]] &&
9607                                         stripe_index_all_zero=false
9608                         done
9609                 done
9610         done
9611         $stripe_index_all_zero &&
9612                 error "all files are being extracted starting from OST index 0"
9613         return 0
9614 }
9615
9616 have_xattrs_include() {
9617         tar --help | grep -q xattrs-include &&
9618                 echo --xattrs-include="lustre.*"
9619 }
9620
9621 test_102d() {
9622         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9623         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9624
9625         XINC=$(have_xattrs_include)
9626         setup_test102
9627         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
9628         cd $DIR/$tdir/$tdir
9629         compare_stripe_info1
9630 }
9631 run_test 102d "tar restore stripe info from tarfile,not keep osts"
9632
9633 test_102f() {
9634         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9635         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9636
9637         XINC=$(have_xattrs_include)
9638         setup_test102
9639         test_mkdir $DIR/$tdir.restore
9640         cd $DIR
9641         tar cf - --xattrs $tdir | tar xf - \
9642                 -C $DIR/$tdir.restore --xattrs $XINC
9643         cd $DIR/$tdir.restore/$tdir
9644         compare_stripe_info1
9645 }
9646 run_test 102f "tar copy files, not keep osts"
9647
9648 grow_xattr() {
9649         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
9650                 skip "must have user_xattr"
9651         [ -z "$(which setfattr 2>/dev/null)" ] &&
9652                 skip_env "could not find setfattr"
9653         [ -z "$(which getfattr 2>/dev/null)" ] &&
9654                 skip_env "could not find getfattr"
9655
9656         local xsize=${1:-1024}  # in bytes
9657         local file=$DIR/$tfile
9658         local value="$(generate_string $xsize)"
9659         local xbig=trusted.big
9660         local toobig=$2
9661
9662         touch $file
9663         log "save $xbig on $file"
9664         if [ -z "$toobig" ]
9665         then
9666                 setfattr -n $xbig -v $value $file ||
9667                         error "saving $xbig on $file failed"
9668         else
9669                 setfattr -n $xbig -v $value $file &&
9670                         error "saving $xbig on $file succeeded"
9671                 return 0
9672         fi
9673
9674         local orig=$(get_xattr_value $xbig $file)
9675         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
9676
9677         local xsml=trusted.sml
9678         log "save $xsml on $file"
9679         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
9680
9681         local new=$(get_xattr_value $xbig $file)
9682         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
9683
9684         log "grow $xsml on $file"
9685         setfattr -n $xsml -v "$value" $file ||
9686                 error "growing $xsml on $file failed"
9687
9688         new=$(get_xattr_value $xbig $file)
9689         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
9690         log "$xbig still valid after growing $xsml"
9691
9692         rm -f $file
9693 }
9694
9695 test_102h() { # bug 15777
9696         grow_xattr 1024
9697 }
9698 run_test 102h "grow xattr from inside inode to external block"
9699
9700 test_102ha() {
9701         large_xattr_enabled || skip_env "ea_inode feature disabled"
9702
9703         echo "setting xattr of max xattr size: $(max_xattr_size)"
9704         grow_xattr $(max_xattr_size)
9705
9706         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
9707         echo "This should fail:"
9708         grow_xattr $(($(max_xattr_size) + 10)) 1
9709 }
9710 run_test 102ha "grow xattr from inside inode to external inode"
9711
9712 test_102i() { # bug 17038
9713         [ -z "$(which getfattr 2>/dev/null)" ] &&
9714                 skip "could not find getfattr"
9715
9716         touch $DIR/$tfile
9717         ln -s $DIR/$tfile $DIR/${tfile}link
9718         getfattr -n trusted.lov $DIR/$tfile ||
9719                 error "lgetxattr on $DIR/$tfile failed"
9720         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
9721                 grep -i "no such attr" ||
9722                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
9723         rm -f $DIR/$tfile $DIR/${tfile}link
9724 }
9725 run_test 102i "lgetxattr test on symbolic link ============"
9726
9727 test_102j() {
9728         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9729         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9730
9731         XINC=$(have_xattrs_include)
9732         setup_test102 "$RUNAS"
9733         chown $RUNAS_ID $DIR/$tdir
9734         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
9735         cd $DIR/$tdir/$tdir
9736         compare_stripe_info1 "$RUNAS"
9737 }
9738 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
9739
9740 test_102k() {
9741         [ -z "$(which setfattr 2>/dev/null)" ] &&
9742                 skip "could not find setfattr"
9743
9744         touch $DIR/$tfile
9745         # b22187 just check that does not crash for regular file.
9746         setfattr -n trusted.lov $DIR/$tfile
9747         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
9748         local test_kdir=$DIR/$tdir
9749         test_mkdir $test_kdir
9750         local default_size=$($LFS getstripe -S $test_kdir)
9751         local default_count=$($LFS getstripe -c $test_kdir)
9752         local default_offset=$($LFS getstripe -i $test_kdir)
9753         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
9754                 error 'dir setstripe failed'
9755         setfattr -n trusted.lov $test_kdir
9756         local stripe_size=$($LFS getstripe -S $test_kdir)
9757         local stripe_count=$($LFS getstripe -c $test_kdir)
9758         local stripe_offset=$($LFS getstripe -i $test_kdir)
9759         [ $stripe_size -eq $default_size ] ||
9760                 error "stripe size $stripe_size != $default_size"
9761         [ $stripe_count -eq $default_count ] ||
9762                 error "stripe count $stripe_count != $default_count"
9763         [ $stripe_offset -eq $default_offset ] ||
9764                 error "stripe offset $stripe_offset != $default_offset"
9765         rm -rf $DIR/$tfile $test_kdir
9766 }
9767 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
9768
9769 test_102l() {
9770         [ -z "$(which getfattr 2>/dev/null)" ] &&
9771                 skip "could not find getfattr"
9772
9773         # LU-532 trusted. xattr is invisible to non-root
9774         local testfile=$DIR/$tfile
9775
9776         touch $testfile
9777
9778         echo "listxattr as user..."
9779         chown $RUNAS_ID $testfile
9780         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
9781             grep -q "trusted" &&
9782                 error "$testfile trusted xattrs are user visible"
9783
9784         return 0;
9785 }
9786 run_test 102l "listxattr size test =================================="
9787
9788 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
9789         local path=$DIR/$tfile
9790         touch $path
9791
9792         listxattr_size_check $path || error "listattr_size_check $path failed"
9793 }
9794 run_test 102m "Ensure listxattr fails on small bufffer ========"
9795
9796 cleanup_test102
9797
9798 getxattr() { # getxattr path name
9799         # Return the base64 encoding of the value of xattr name on path.
9800         local path=$1
9801         local name=$2
9802
9803         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
9804         # file: $path
9805         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
9806         #
9807         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
9808
9809         getfattr --absolute-names --encoding=base64 --name=$name $path |
9810                 awk -F= -v name=$name '$1 == name {
9811                         print substr($0, index($0, "=") + 1);
9812         }'
9813 }
9814
9815 test_102n() { # LU-4101 mdt: protect internal xattrs
9816         [ -z "$(which setfattr 2>/dev/null)" ] &&
9817                 skip "could not find setfattr"
9818         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
9819         then
9820                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
9821         fi
9822
9823         local file0=$DIR/$tfile.0
9824         local file1=$DIR/$tfile.1
9825         local xattr0=$TMP/$tfile.0
9826         local xattr1=$TMP/$tfile.1
9827         local namelist="lov lma lmv link fid version som hsm"
9828         local name
9829         local value
9830
9831         rm -rf $file0 $file1 $xattr0 $xattr1
9832         touch $file0 $file1
9833
9834         # Get 'before' xattrs of $file1.
9835         getfattr --absolute-names --dump --match=- $file1 > $xattr0
9836
9837         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
9838                 namelist+=" lfsck_namespace"
9839         for name in $namelist; do
9840                 # Try to copy xattr from $file0 to $file1.
9841                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
9842
9843                 setfattr --name=trusted.$name --value="$value" $file1 ||
9844                         error "setxattr 'trusted.$name' failed"
9845
9846                 # Try to set a garbage xattr.
9847                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
9848
9849                 if [[ x$name == "xlov" ]]; then
9850                         setfattr --name=trusted.lov --value="$value" $file1 &&
9851                         error "setxattr invalid 'trusted.lov' success"
9852                 else
9853                         setfattr --name=trusted.$name --value="$value" $file1 ||
9854                                 error "setxattr invalid 'trusted.$name' failed"
9855                 fi
9856
9857                 # Try to remove the xattr from $file1. We don't care if this
9858                 # appears to succeed or fail, we just don't want there to be
9859                 # any changes or crashes.
9860                 setfattr --remove=$trusted.$name $file1 2> /dev/null
9861         done
9862
9863         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
9864         then
9865                 name="lfsck_ns"
9866                 # Try to copy xattr from $file0 to $file1.
9867                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
9868
9869                 setfattr --name=trusted.$name --value="$value" $file1 ||
9870                         error "setxattr 'trusted.$name' failed"
9871
9872                 # Try to set a garbage xattr.
9873                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
9874
9875                 setfattr --name=trusted.$name --value="$value" $file1 ||
9876                         error "setxattr 'trusted.$name' failed"
9877
9878                 # Try to remove the xattr from $file1. We don't care if this
9879                 # appears to succeed or fail, we just don't want there to be
9880                 # any changes or crashes.
9881                 setfattr --remove=$trusted.$name $file1 2> /dev/null
9882         fi
9883
9884         # Get 'after' xattrs of file1.
9885         getfattr --absolute-names --dump --match=- $file1 > $xattr1
9886
9887         if ! diff $xattr0 $xattr1; then
9888                 error "before and after xattrs of '$file1' differ"
9889         fi
9890
9891         rm -rf $file0 $file1 $xattr0 $xattr1
9892
9893         return 0
9894 }
9895 run_test 102n "silently ignore setxattr on internal trusted xattrs"
9896
9897 test_102p() { # LU-4703 setxattr did not check ownership
9898         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
9899                 skip "MDS needs to be at least 2.5.56"
9900
9901         local testfile=$DIR/$tfile
9902
9903         touch $testfile
9904
9905         echo "setfacl as user..."
9906         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
9907         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
9908
9909         echo "setfattr as user..."
9910         setfacl -m "u:$RUNAS_ID:---" $testfile
9911         $RUNAS setfattr -x system.posix_acl_access $testfile
9912         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
9913 }
9914 run_test 102p "check setxattr(2) correctly fails without permission"
9915
9916 test_102q() {
9917         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
9918                 skip "MDS needs to be at least 2.6.92"
9919
9920         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
9921 }
9922 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
9923
9924 test_102r() {
9925         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
9926                 skip "MDS needs to be at least 2.6.93"
9927
9928         touch $DIR/$tfile || error "touch"
9929         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
9930         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
9931         rm $DIR/$tfile || error "rm"
9932
9933         #normal directory
9934         mkdir -p $DIR/$tdir || error "mkdir"
9935         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
9936         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
9937         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
9938                 error "$testfile error deleting user.author1"
9939         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
9940                 grep "user.$(basename $tdir)" &&
9941                 error "$tdir did not delete user.$(basename $tdir)"
9942         rmdir $DIR/$tdir || error "rmdir"
9943
9944         #striped directory
9945         test_mkdir $DIR/$tdir
9946         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
9947         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
9948         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
9949                 error "$testfile error deleting user.author1"
9950         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
9951                 grep "user.$(basename $tdir)" &&
9952                 error "$tdir did not delete user.$(basename $tdir)"
9953         rmdir $DIR/$tdir || error "rm striped dir"
9954 }
9955 run_test 102r "set EAs with empty values"
9956
9957 test_102s() {
9958         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
9959                 skip "MDS needs to be at least 2.11.52"
9960
9961         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
9962
9963         save_lustre_params client "llite.*.xattr_cache" > $save
9964
9965         for cache in 0 1; do
9966                 lctl set_param llite.*.xattr_cache=$cache
9967
9968                 rm -f $DIR/$tfile
9969                 touch $DIR/$tfile || error "touch"
9970                 for prefix in lustre security system trusted user; do
9971                         # Note getxattr() may fail with 'Operation not
9972                         # supported' or 'No such attribute' depending
9973                         # on prefix and cache.
9974                         getfattr -n $prefix.n102s $DIR/$tfile &&
9975                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
9976                 done
9977         done
9978
9979         restore_lustre_params < $save
9980 }
9981 run_test 102s "getting nonexistent xattrs should fail"
9982
9983 test_102t() {
9984         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
9985                 skip "MDS needs to be at least 2.11.52"
9986
9987         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
9988
9989         save_lustre_params client "llite.*.xattr_cache" > $save
9990
9991         for cache in 0 1; do
9992                 lctl set_param llite.*.xattr_cache=$cache
9993
9994                 for buf_size in 0 256; do
9995                         rm -f $DIR/$tfile
9996                         touch $DIR/$tfile || error "touch"
9997                         setfattr -n user.multiop $DIR/$tfile
9998                         $MULTIOP $DIR/$tfile oa$buf_size ||
9999                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
10000                 done
10001         done
10002
10003         restore_lustre_params < $save
10004 }
10005 run_test 102t "zero length xattr values handled correctly"
10006
10007 run_acl_subtest()
10008 {
10009     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
10010     return $?
10011 }
10012
10013 test_103a() {
10014         [ "$UID" != 0 ] && skip "must run as root"
10015         $GSS && skip_env "could not run under gss"
10016         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
10017                 skip_env "must have acl enabled"
10018         [ -z "$(which setfacl 2>/dev/null)" ] &&
10019                 skip_env "could not find setfacl"
10020         remote_mds_nodsh && skip "remote MDS with nodsh"
10021
10022         gpasswd -a daemon bin                           # LU-5641
10023         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
10024
10025         declare -a identity_old
10026
10027         for num in $(seq $MDSCOUNT); do
10028                 switch_identity $num true || identity_old[$num]=$?
10029         done
10030
10031         SAVE_UMASK=$(umask)
10032         umask 0022
10033         mkdir -p $DIR/$tdir
10034         cd $DIR/$tdir
10035
10036         echo "performing cp ..."
10037         run_acl_subtest cp || error "run_acl_subtest cp failed"
10038         echo "performing getfacl-noacl..."
10039         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
10040         echo "performing misc..."
10041         run_acl_subtest misc || error  "misc test failed"
10042         echo "performing permissions..."
10043         run_acl_subtest permissions || error "permissions failed"
10044         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
10045         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
10046                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
10047                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
10048         then
10049                 echo "performing permissions xattr..."
10050                 run_acl_subtest permissions_xattr ||
10051                         error "permissions_xattr failed"
10052         fi
10053         echo "performing setfacl..."
10054         run_acl_subtest setfacl || error  "setfacl test failed"
10055
10056         # inheritance test got from HP
10057         echo "performing inheritance..."
10058         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
10059         chmod +x make-tree || error "chmod +x failed"
10060         run_acl_subtest inheritance || error "inheritance test failed"
10061         rm -f make-tree
10062
10063         echo "LU-974 ignore umask when acl is enabled..."
10064         run_acl_subtest 974 || error "LU-974 umask test failed"
10065         if [ $MDSCOUNT -ge 2 ]; then
10066                 run_acl_subtest 974_remote ||
10067                         error "LU-974 umask test failed under remote dir"
10068         fi
10069
10070         echo "LU-2561 newly created file is same size as directory..."
10071         if [ "$mds1_FSTYPE" != "zfs" ]; then
10072                 run_acl_subtest 2561 || error "LU-2561 test failed"
10073         else
10074                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
10075         fi
10076
10077         run_acl_subtest 4924 || error "LU-4924 test failed"
10078
10079         cd $SAVE_PWD
10080         umask $SAVE_UMASK
10081
10082         for num in $(seq $MDSCOUNT); do
10083                 if [ "${identity_old[$num]}" = 1 ]; then
10084                         switch_identity $num false || identity_old[$num]=$?
10085                 fi
10086         done
10087 }
10088 run_test 103a "acl test"
10089
10090 test_103b() {
10091         declare -a pids
10092         local U
10093
10094         for U in {0..511}; do
10095                 {
10096                 local O=$(printf "%04o" $U)
10097
10098                 umask $(printf "%04o" $((511 ^ $O)))
10099                 $LFS setstripe -c 1 $DIR/$tfile.s$O
10100                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
10101
10102                 (( $S == ($O & 0666) )) ||
10103                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
10104
10105                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
10106                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
10107                 (( $S == ($O & 0666) )) ||
10108                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
10109
10110                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
10111                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
10112                 (( $S == ($O & 0666) )) ||
10113                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
10114                 rm -f $DIR/$tfile.[smp]$0
10115                 } &
10116                 local pid=$!
10117
10118                 # limit the concurrently running threads to 64. LU-11878
10119                 local idx=$((U % 64))
10120                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
10121                 pids[idx]=$pid
10122         done
10123         wait
10124 }
10125 run_test 103b "umask lfs setstripe"
10126
10127 test_103c() {
10128         mkdir -p $DIR/$tdir
10129         cp -rp $DIR/$tdir $DIR/$tdir.bak
10130
10131         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
10132                 error "$DIR/$tdir shouldn't contain default ACL"
10133         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
10134                 error "$DIR/$tdir.bak shouldn't contain default ACL"
10135         true
10136 }
10137 run_test 103c "'cp -rp' won't set empty acl"
10138
10139 test_104a() {
10140         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10141
10142         touch $DIR/$tfile
10143         lfs df || error "lfs df failed"
10144         lfs df -ih || error "lfs df -ih failed"
10145         lfs df -h $DIR || error "lfs df -h $DIR failed"
10146         lfs df -i $DIR || error "lfs df -i $DIR failed"
10147         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
10148         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
10149
10150         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
10151         lctl --device %$OSC deactivate
10152         lfs df || error "lfs df with deactivated OSC failed"
10153         lctl --device %$OSC activate
10154         # wait the osc back to normal
10155         wait_osc_import_ready client ost
10156
10157         lfs df || error "lfs df with reactivated OSC failed"
10158         rm -f $DIR/$tfile
10159 }
10160 run_test 104a "lfs df [-ih] [path] test ========================="
10161
10162 test_104b() {
10163         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10164         [ $RUNAS_ID -eq $UID ] &&
10165                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10166
10167         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
10168                         grep "Permission denied" | wc -l)))
10169         if [ $denied_cnt -ne 0 ]; then
10170                 error "lfs check servers test failed"
10171         fi
10172 }
10173 run_test 104b "$RUNAS lfs check servers test ===================="
10174
10175 test_105a() {
10176         # doesn't work on 2.4 kernels
10177         touch $DIR/$tfile
10178         if $(flock_is_enabled); then
10179                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
10180         else
10181                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
10182         fi
10183         rm -f $DIR/$tfile
10184 }
10185 run_test 105a "flock when mounted without -o flock test ========"
10186
10187 test_105b() {
10188         touch $DIR/$tfile
10189         if $(flock_is_enabled); then
10190                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
10191         else
10192                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
10193         fi
10194         rm -f $DIR/$tfile
10195 }
10196 run_test 105b "fcntl when mounted without -o flock test ========"
10197
10198 test_105c() {
10199         touch $DIR/$tfile
10200         if $(flock_is_enabled); then
10201                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
10202         else
10203                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
10204         fi
10205         rm -f $DIR/$tfile
10206 }
10207 run_test 105c "lockf when mounted without -o flock test"
10208
10209 test_105d() { # bug 15924
10210         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10211
10212         test_mkdir $DIR/$tdir
10213         flock_is_enabled || skip_env "mount w/o flock enabled"
10214         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
10215         $LCTL set_param fail_loc=0x80000315
10216         flocks_test 2 $DIR/$tdir
10217 }
10218 run_test 105d "flock race (should not freeze) ========"
10219
10220 test_105e() { # bug 22660 && 22040
10221         flock_is_enabled || skip_env "mount w/o flock enabled"
10222
10223         touch $DIR/$tfile
10224         flocks_test 3 $DIR/$tfile
10225 }
10226 run_test 105e "Two conflicting flocks from same process"
10227
10228 test_106() { #bug 10921
10229         test_mkdir $DIR/$tdir
10230         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
10231         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
10232 }
10233 run_test 106 "attempt exec of dir followed by chown of that dir"
10234
10235 test_107() {
10236         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10237
10238         CDIR=`pwd`
10239         local file=core
10240
10241         cd $DIR
10242         rm -f $file
10243
10244         local save_pattern=$(sysctl -n kernel.core_pattern)
10245         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
10246         sysctl -w kernel.core_pattern=$file
10247         sysctl -w kernel.core_uses_pid=0
10248
10249         ulimit -c unlimited
10250         sleep 60 &
10251         SLEEPPID=$!
10252
10253         sleep 1
10254
10255         kill -s 11 $SLEEPPID
10256         wait $SLEEPPID
10257         if [ -e $file ]; then
10258                 size=`stat -c%s $file`
10259                 [ $size -eq 0 ] && error "Fail to create core file $file"
10260         else
10261                 error "Fail to create core file $file"
10262         fi
10263         rm -f $file
10264         sysctl -w kernel.core_pattern=$save_pattern
10265         sysctl -w kernel.core_uses_pid=$save_uses_pid
10266         cd $CDIR
10267 }
10268 run_test 107 "Coredump on SIG"
10269
10270 test_110() {
10271         test_mkdir $DIR/$tdir
10272         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
10273         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
10274                 error "mkdir with 256 char should fail, but did not"
10275         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
10276                 error "create with 255 char failed"
10277         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
10278                 error "create with 256 char should fail, but did not"
10279
10280         ls -l $DIR/$tdir
10281         rm -rf $DIR/$tdir
10282 }
10283 run_test 110 "filename length checking"
10284
10285 #
10286 # Purpose: To verify dynamic thread (OSS) creation.
10287 #
10288 test_115() {
10289         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10290         remote_ost_nodsh && skip "remote OST with nodsh"
10291
10292         # Lustre does not stop service threads once they are started.
10293         # Reset number of running threads to default.
10294         stopall
10295         setupall
10296
10297         local OSTIO_pre
10298         local save_params="$TMP/sanity-$TESTNAME.parameters"
10299
10300         # Get ll_ost_io count before I/O
10301         OSTIO_pre=$(do_facet ost1 \
10302                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
10303         # Exit if lustre is not running (ll_ost_io not running).
10304         [ -z "$OSTIO_pre" ] && error "no OSS threads"
10305
10306         echo "Starting with $OSTIO_pre threads"
10307         local thread_max=$((OSTIO_pre * 2))
10308         local rpc_in_flight=$((thread_max * 2))
10309         # Number of I/O Process proposed to be started.
10310         local nfiles
10311         local facets=$(get_facets OST)
10312
10313         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
10314         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
10315
10316         # Set in_flight to $rpc_in_flight
10317         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
10318                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
10319         nfiles=${rpc_in_flight}
10320         # Set ost thread_max to $thread_max
10321         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
10322
10323         # 5 Minutes should be sufficient for max number of OSS
10324         # threads(thread_max) to be created.
10325         local timeout=300
10326
10327         # Start I/O.
10328         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
10329         test_mkdir $DIR/$tdir
10330         for i in $(seq $nfiles); do
10331                 local file=$DIR/$tdir/${tfile}-$i
10332                 $LFS setstripe -c -1 -i 0 $file
10333                 ($WTL $file $timeout)&
10334         done
10335
10336         # I/O Started - Wait for thread_started to reach thread_max or report
10337         # error if thread_started is more than thread_max.
10338         echo "Waiting for thread_started to reach thread_max"
10339         local thread_started=0
10340         local end_time=$((SECONDS + timeout))
10341
10342         while [ $SECONDS -le $end_time ] ; do
10343                 echo -n "."
10344                 # Get ost i/o thread_started count.
10345                 thread_started=$(do_facet ost1 \
10346                         "$LCTL get_param \
10347                         ost.OSS.ost_io.threads_started | cut -d= -f2")
10348                 # Break out if thread_started is equal/greater than thread_max
10349                 if [[ $thread_started -ge $thread_max ]]; then
10350                         echo ll_ost_io thread_started $thread_started, \
10351                                 equal/greater than thread_max $thread_max
10352                         break
10353                 fi
10354                 sleep 1
10355         done
10356
10357         # Cleanup - We have the numbers, Kill i/o jobs if running.
10358         jobcount=($(jobs -p))
10359         for i in $(seq 0 $((${#jobcount[@]}-1)))
10360         do
10361                 kill -9 ${jobcount[$i]}
10362                 if [ $? -ne 0 ] ; then
10363                         echo Warning: \
10364                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
10365                 fi
10366         done
10367
10368         # Cleanup files left by WTL binary.
10369         for i in $(seq $nfiles); do
10370                 local file=$DIR/$tdir/${tfile}-$i
10371                 rm -rf $file
10372                 if [ $? -ne 0 ] ; then
10373                         echo "Warning: Failed to delete file $file"
10374                 fi
10375         done
10376
10377         restore_lustre_params <$save_params
10378         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
10379
10380         # Error out if no new thread has started or Thread started is greater
10381         # than thread max.
10382         if [[ $thread_started -le $OSTIO_pre ||
10383                         $thread_started -gt $thread_max ]]; then
10384                 error "ll_ost_io: thread_started $thread_started" \
10385                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
10386                       "No new thread started or thread started greater " \
10387                       "than thread_max."
10388         fi
10389 }
10390 run_test 115 "verify dynamic thread creation===================="
10391
10392 free_min_max () {
10393         wait_delete_completed
10394         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
10395         echo "OST kbytes available: ${AVAIL[@]}"
10396         MAXV=${AVAIL[0]}
10397         MAXI=0
10398         MINV=${AVAIL[0]}
10399         MINI=0
10400         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
10401                 #echo OST $i: ${AVAIL[i]}kb
10402                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
10403                         MAXV=${AVAIL[i]}
10404                         MAXI=$i
10405                 fi
10406                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
10407                         MINV=${AVAIL[i]}
10408                         MINI=$i
10409                 fi
10410         done
10411         echo "Min free space: OST $MINI: $MINV"
10412         echo "Max free space: OST $MAXI: $MAXV"
10413 }
10414
10415 test_116a() { # was previously test_116()
10416         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10417         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10418         remote_mds_nodsh && skip "remote MDS with nodsh"
10419
10420         echo -n "Free space priority "
10421         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
10422                 head -n1
10423         declare -a AVAIL
10424         free_min_max
10425
10426         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
10427         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
10428         trap simple_cleanup_common EXIT
10429
10430         # Check if we need to generate uneven OSTs
10431         test_mkdir -p $DIR/$tdir/OST${MINI}
10432         local FILL=$((MINV / 4))
10433         local DIFF=$((MAXV - MINV))
10434         local DIFF2=$((DIFF * 100 / MINV))
10435
10436         local threshold=$(do_facet $SINGLEMDS \
10437                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
10438         threshold=${threshold%%%}
10439         echo -n "Check for uneven OSTs: "
10440         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
10441
10442         if [[ $DIFF2 -gt $threshold ]]; then
10443                 echo "ok"
10444                 echo "Don't need to fill OST$MINI"
10445         else
10446                 # generate uneven OSTs. Write 2% over the QOS threshold value
10447                 echo "no"
10448                 DIFF=$((threshold - DIFF2 + 2))
10449                 DIFF2=$((MINV * DIFF / 100))
10450                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
10451                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
10452                         error "setstripe failed"
10453                 DIFF=$((DIFF2 / 2048))
10454                 i=0
10455                 while [ $i -lt $DIFF ]; do
10456                         i=$((i + 1))
10457                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
10458                                 bs=2M count=1 2>/dev/null
10459                         echo -n .
10460                 done
10461                 echo .
10462                 sync
10463                 sleep_maxage
10464                 free_min_max
10465         fi
10466
10467         DIFF=$((MAXV - MINV))
10468         DIFF2=$((DIFF * 100 / MINV))
10469         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
10470         if [ $DIFF2 -gt $threshold ]; then
10471                 echo "ok"
10472         else
10473                 echo "failed - QOS mode won't be used"
10474                 simple_cleanup_common
10475                 skip "QOS imbalance criteria not met"
10476         fi
10477
10478         MINI1=$MINI
10479         MINV1=$MINV
10480         MAXI1=$MAXI
10481         MAXV1=$MAXV
10482
10483         # now fill using QOS
10484         $LFS setstripe -c 1 $DIR/$tdir
10485         FILL=$((FILL / 200))
10486         if [ $FILL -gt 600 ]; then
10487                 FILL=600
10488         fi
10489         echo "writing $FILL files to QOS-assigned OSTs"
10490         i=0
10491         while [ $i -lt $FILL ]; do
10492                 i=$((i + 1))
10493                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
10494                         count=1 2>/dev/null
10495                 echo -n .
10496         done
10497         echo "wrote $i 200k files"
10498         sync
10499         sleep_maxage
10500
10501         echo "Note: free space may not be updated, so measurements might be off"
10502         free_min_max
10503         DIFF2=$((MAXV - MINV))
10504         echo "free space delta: orig $DIFF final $DIFF2"
10505         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
10506         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
10507         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
10508         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
10509         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
10510         if [[ $DIFF -gt 0 ]]; then
10511                 FILL=$((DIFF2 * 100 / DIFF - 100))
10512                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
10513         fi
10514
10515         # Figure out which files were written where
10516         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10517                awk '/'$MINI1': / {print $2; exit}')
10518         echo $UUID
10519         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10520         echo "$MINC files created on smaller OST $MINI1"
10521         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10522                awk '/'$MAXI1': / {print $2; exit}')
10523         echo $UUID
10524         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10525         echo "$MAXC files created on larger OST $MAXI1"
10526         if [[ $MINC -gt 0 ]]; then
10527                 FILL=$((MAXC * 100 / MINC - 100))
10528                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
10529         fi
10530         [[ $MAXC -gt $MINC ]] ||
10531                 error_ignore LU-9 "stripe QOS didn't balance free space"
10532         simple_cleanup_common
10533 }
10534 run_test 116a "stripe QOS: free space balance ==================="
10535
10536 test_116b() { # LU-2093
10537         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10538         remote_mds_nodsh && skip "remote MDS with nodsh"
10539
10540 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
10541         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
10542                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
10543         [ -z "$old_rr" ] && skip "no QOS"
10544         do_facet $SINGLEMDS lctl set_param \
10545                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
10546         mkdir -p $DIR/$tdir
10547         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
10548         createmany -o $DIR/$tdir/f- 20 || error "can't create"
10549         do_facet $SINGLEMDS lctl set_param fail_loc=0
10550         rm -rf $DIR/$tdir
10551         do_facet $SINGLEMDS lctl set_param \
10552                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
10553 }
10554 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
10555
10556 test_117() # bug 10891
10557 {
10558         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10559
10560         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
10561         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
10562         lctl set_param fail_loc=0x21e
10563         > $DIR/$tfile || error "truncate failed"
10564         lctl set_param fail_loc=0
10565         echo "Truncate succeeded."
10566         rm -f $DIR/$tfile
10567 }
10568 run_test 117 "verify osd extend =========="
10569
10570 NO_SLOW_RESENDCOUNT=4
10571 export OLD_RESENDCOUNT=""
10572 set_resend_count () {
10573         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
10574         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
10575         lctl set_param -n $PROC_RESENDCOUNT $1
10576         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
10577 }
10578
10579 # for reduce test_118* time (b=14842)
10580 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
10581
10582 # Reset async IO behavior after error case
10583 reset_async() {
10584         FILE=$DIR/reset_async
10585
10586         # Ensure all OSCs are cleared
10587         $LFS setstripe -c -1 $FILE
10588         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
10589         sync
10590         rm $FILE
10591 }
10592
10593 test_118a() #bug 11710
10594 {
10595         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10596
10597         reset_async
10598
10599         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10600         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10601         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10602
10603         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10604                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10605                 return 1;
10606         fi
10607         rm -f $DIR/$tfile
10608 }
10609 run_test 118a "verify O_SYNC works =========="
10610
10611 test_118b()
10612 {
10613         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10614         remote_ost_nodsh && skip "remote OST with nodsh"
10615
10616         reset_async
10617
10618         #define OBD_FAIL_SRV_ENOENT 0x217
10619         set_nodes_failloc "$(osts_nodes)" 0x217
10620         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10621         RC=$?
10622         set_nodes_failloc "$(osts_nodes)" 0
10623         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10624         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10625                     grep -c writeback)
10626
10627         if [[ $RC -eq 0 ]]; then
10628                 error "Must return error due to dropped pages, rc=$RC"
10629                 return 1;
10630         fi
10631
10632         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10633                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10634                 return 1;
10635         fi
10636
10637         echo "Dirty pages not leaked on ENOENT"
10638
10639         # Due to the above error the OSC will issue all RPCs syncronously
10640         # until a subsequent RPC completes successfully without error.
10641         $MULTIOP $DIR/$tfile Ow4096yc
10642         rm -f $DIR/$tfile
10643
10644         return 0
10645 }
10646 run_test 118b "Reclaim dirty pages on fatal error =========="
10647
10648 test_118c()
10649 {
10650         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10651
10652         # for 118c, restore the original resend count, LU-1940
10653         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
10654                                 set_resend_count $OLD_RESENDCOUNT
10655         remote_ost_nodsh && skip "remote OST with nodsh"
10656
10657         reset_async
10658
10659         #define OBD_FAIL_OST_EROFS               0x216
10660         set_nodes_failloc "$(osts_nodes)" 0x216
10661
10662         # multiop should block due to fsync until pages are written
10663         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10664         MULTIPID=$!
10665         sleep 1
10666
10667         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
10668                 error "Multiop failed to block on fsync, pid=$MULTIPID"
10669         fi
10670
10671         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10672                     grep -c writeback)
10673         if [[ $WRITEBACK -eq 0 ]]; then
10674                 error "No page in writeback, writeback=$WRITEBACK"
10675         fi
10676
10677         set_nodes_failloc "$(osts_nodes)" 0
10678         wait $MULTIPID
10679         RC=$?
10680         if [[ $RC -ne 0 ]]; then
10681                 error "Multiop fsync failed, rc=$RC"
10682         fi
10683
10684         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10685         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10686                     grep -c writeback)
10687         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10688                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10689         fi
10690
10691         rm -f $DIR/$tfile
10692         echo "Dirty pages flushed via fsync on EROFS"
10693         return 0
10694 }
10695 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
10696
10697 # continue to use small resend count to reduce test_118* time (b=14842)
10698 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
10699
10700 test_118d()
10701 {
10702         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10703         remote_ost_nodsh && skip "remote OST with nodsh"
10704
10705         reset_async
10706
10707         #define OBD_FAIL_OST_BRW_PAUSE_BULK
10708         set_nodes_failloc "$(osts_nodes)" 0x214
10709         # multiop should block due to fsync until pages are written
10710         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10711         MULTIPID=$!
10712         sleep 1
10713
10714         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
10715                 error "Multiop failed to block on fsync, pid=$MULTIPID"
10716         fi
10717
10718         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10719                     grep -c writeback)
10720         if [[ $WRITEBACK -eq 0 ]]; then
10721                 error "No page in writeback, writeback=$WRITEBACK"
10722         fi
10723
10724         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
10725         set_nodes_failloc "$(osts_nodes)" 0
10726
10727         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10728         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10729                     grep -c writeback)
10730         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10731                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10732         fi
10733
10734         rm -f $DIR/$tfile
10735         echo "Dirty pages gaurenteed flushed via fsync"
10736         return 0
10737 }
10738 run_test 118d "Fsync validation inject a delay of the bulk =========="
10739
10740 test_118f() {
10741         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10742
10743         reset_async
10744
10745         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
10746         lctl set_param fail_loc=0x8000040a
10747
10748         # Should simulate EINVAL error which is fatal
10749         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10750         RC=$?
10751         if [[ $RC -eq 0 ]]; then
10752                 error "Must return error due to dropped pages, rc=$RC"
10753         fi
10754
10755         lctl set_param fail_loc=0x0
10756
10757         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10758         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10759         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10760                     grep -c writeback)
10761         if [[ $LOCKED -ne 0 ]]; then
10762                 error "Locked pages remain in cache, locked=$LOCKED"
10763         fi
10764
10765         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10766                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10767         fi
10768
10769         rm -f $DIR/$tfile
10770         echo "No pages locked after fsync"
10771
10772         reset_async
10773         return 0
10774 }
10775 run_test 118f "Simulate unrecoverable OSC side error =========="
10776
10777 test_118g() {
10778         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10779
10780         reset_async
10781
10782         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
10783         lctl set_param fail_loc=0x406
10784
10785         # simulate local -ENOMEM
10786         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10787         RC=$?
10788
10789         lctl set_param fail_loc=0
10790         if [[ $RC -eq 0 ]]; then
10791                 error "Must return error due to dropped pages, rc=$RC"
10792         fi
10793
10794         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10795         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10796         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10797                         grep -c writeback)
10798         if [[ $LOCKED -ne 0 ]]; then
10799                 error "Locked pages remain in cache, locked=$LOCKED"
10800         fi
10801
10802         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10803                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10804         fi
10805
10806         rm -f $DIR/$tfile
10807         echo "No pages locked after fsync"
10808
10809         reset_async
10810         return 0
10811 }
10812 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
10813
10814 test_118h() {
10815         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10816         remote_ost_nodsh && skip "remote OST with nodsh"
10817
10818         reset_async
10819
10820         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
10821         set_nodes_failloc "$(osts_nodes)" 0x20e
10822         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
10823         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10824         RC=$?
10825
10826         set_nodes_failloc "$(osts_nodes)" 0
10827         if [[ $RC -eq 0 ]]; then
10828                 error "Must return error due to dropped pages, rc=$RC"
10829         fi
10830
10831         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10832         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10833         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10834                     grep -c writeback)
10835         if [[ $LOCKED -ne 0 ]]; then
10836                 error "Locked pages remain in cache, locked=$LOCKED"
10837         fi
10838
10839         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10840                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10841         fi
10842
10843         rm -f $DIR/$tfile
10844         echo "No pages locked after fsync"
10845
10846         return 0
10847 }
10848 run_test 118h "Verify timeout in handling recoverables errors  =========="
10849
10850 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
10851
10852 test_118i() {
10853         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10854         remote_ost_nodsh && skip "remote OST with nodsh"
10855
10856         reset_async
10857
10858         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
10859         set_nodes_failloc "$(osts_nodes)" 0x20e
10860
10861         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
10862         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10863         PID=$!
10864         sleep 5
10865         set_nodes_failloc "$(osts_nodes)" 0
10866
10867         wait $PID
10868         RC=$?
10869         if [[ $RC -ne 0 ]]; then
10870                 error "got error, but should be not, rc=$RC"
10871         fi
10872
10873         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10874         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10875         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10876         if [[ $LOCKED -ne 0 ]]; then
10877                 error "Locked pages remain in cache, locked=$LOCKED"
10878         fi
10879
10880         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10881                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10882         fi
10883
10884         rm -f $DIR/$tfile
10885         echo "No pages locked after fsync"
10886
10887         return 0
10888 }
10889 run_test 118i "Fix error before timeout in recoverable error  =========="
10890
10891 [ "$SLOW" = "no" ] && set_resend_count 4
10892
10893 test_118j() {
10894         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10895         remote_ost_nodsh && skip "remote OST with nodsh"
10896
10897         reset_async
10898
10899         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
10900         set_nodes_failloc "$(osts_nodes)" 0x220
10901
10902         # return -EIO from OST
10903         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10904         RC=$?
10905         set_nodes_failloc "$(osts_nodes)" 0x0
10906         if [[ $RC -eq 0 ]]; then
10907                 error "Must return error due to dropped pages, rc=$RC"
10908         fi
10909
10910         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10911         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10912         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10913         if [[ $LOCKED -ne 0 ]]; then
10914                 error "Locked pages remain in cache, locked=$LOCKED"
10915         fi
10916
10917         # in recoverable error on OST we want resend and stay until it finished
10918         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10919                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10920         fi
10921
10922         rm -f $DIR/$tfile
10923         echo "No pages locked after fsync"
10924
10925         return 0
10926 }
10927 run_test 118j "Simulate unrecoverable OST side error =========="
10928
10929 test_118k()
10930 {
10931         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10932         remote_ost_nodsh && skip "remote OSTs with nodsh"
10933
10934         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
10935         set_nodes_failloc "$(osts_nodes)" 0x20e
10936         test_mkdir $DIR/$tdir
10937
10938         for ((i=0;i<10;i++)); do
10939                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
10940                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
10941                 SLEEPPID=$!
10942                 sleep 0.500s
10943                 kill $SLEEPPID
10944                 wait $SLEEPPID
10945         done
10946
10947         set_nodes_failloc "$(osts_nodes)" 0
10948         rm -rf $DIR/$tdir
10949 }
10950 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
10951
10952 test_118l() # LU-646
10953 {
10954         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10955
10956         test_mkdir $DIR/$tdir
10957         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
10958         rm -rf $DIR/$tdir
10959 }
10960 run_test 118l "fsync dir"
10961
10962 test_118m() # LU-3066
10963 {
10964         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10965
10966         test_mkdir $DIR/$tdir
10967         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
10968         rm -rf $DIR/$tdir
10969 }
10970 run_test 118m "fdatasync dir ========="
10971
10972 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
10973
10974 test_118n()
10975 {
10976         local begin
10977         local end
10978
10979         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10980         remote_ost_nodsh && skip "remote OSTs with nodsh"
10981
10982         # Sleep to avoid a cached response.
10983         #define OBD_STATFS_CACHE_SECONDS 1
10984         sleep 2
10985
10986         # Inject a 10 second delay in the OST_STATFS handler.
10987         #define OBD_FAIL_OST_STATFS_DELAY 0x242
10988         set_nodes_failloc "$(osts_nodes)" 0x242
10989
10990         begin=$SECONDS
10991         stat --file-system $MOUNT > /dev/null
10992         end=$SECONDS
10993
10994         set_nodes_failloc "$(osts_nodes)" 0
10995
10996         if ((end - begin > 20)); then
10997             error "statfs took $((end - begin)) seconds, expected 10"
10998         fi
10999 }
11000 run_test 118n "statfs() sends OST_STATFS requests in parallel"
11001
11002 test_119a() # bug 11737
11003 {
11004         BSIZE=$((512 * 1024))
11005         directio write $DIR/$tfile 0 1 $BSIZE
11006         # We ask to read two blocks, which is more than a file size.
11007         # directio will indicate an error when requested and actual
11008         # sizes aren't equeal (a normal situation in this case) and
11009         # print actual read amount.
11010         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
11011         if [ "$NOB" != "$BSIZE" ]; then
11012                 error "read $NOB bytes instead of $BSIZE"
11013         fi
11014         rm -f $DIR/$tfile
11015 }
11016 run_test 119a "Short directIO read must return actual read amount"
11017
11018 test_119b() # bug 11737
11019 {
11020         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11021
11022         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
11023         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
11024         sync
11025         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
11026                 error "direct read failed"
11027         rm -f $DIR/$tfile
11028 }
11029 run_test 119b "Sparse directIO read must return actual read amount"
11030
11031 test_119c() # bug 13099
11032 {
11033         BSIZE=1048576
11034         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
11035         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
11036         rm -f $DIR/$tfile
11037 }
11038 run_test 119c "Testing for direct read hitting hole"
11039
11040 test_119d() # bug 15950
11041 {
11042         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11043
11044         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
11045         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
11046         BSIZE=1048576
11047         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
11048         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
11049         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
11050         lctl set_param fail_loc=0x40d
11051         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
11052         pid_dio=$!
11053         sleep 1
11054         cat $DIR/$tfile > /dev/null &
11055         lctl set_param fail_loc=0
11056         pid_reads=$!
11057         wait $pid_dio
11058         log "the DIO writes have completed, now wait for the reads (should not block very long)"
11059         sleep 2
11060         [ -n "`ps h -p $pid_reads -o comm`" ] && \
11061         error "the read rpcs have not completed in 2s"
11062         rm -f $DIR/$tfile
11063         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
11064 }
11065 run_test 119d "The DIO path should try to send a new rpc once one is completed"
11066
11067 test_120a() {
11068         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11069         remote_mds_nodsh && skip "remote MDS with nodsh"
11070         test_mkdir -i0 -c1 $DIR/$tdir
11071         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11072                 skip_env "no early lock cancel on server"
11073
11074         lru_resize_disable mdc
11075         lru_resize_disable osc
11076         cancel_lru_locks mdc
11077         # asynchronous object destroy at MDT could cause bl ast to client
11078         cancel_lru_locks osc
11079
11080         stat $DIR/$tdir > /dev/null
11081         can1=$(do_facet mds1 \
11082                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11083                awk '/ldlm_cancel/ {print $2}')
11084         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11085                awk '/ldlm_bl_callback/ {print $2}')
11086         test_mkdir -i0 -c1 $DIR/$tdir/d1
11087         can2=$(do_facet mds1 \
11088                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11089                awk '/ldlm_cancel/ {print $2}')
11090         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11091                awk '/ldlm_bl_callback/ {print $2}')
11092         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11093         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11094         lru_resize_enable mdc
11095         lru_resize_enable osc
11096 }
11097 run_test 120a "Early Lock Cancel: mkdir test"
11098
11099 test_120b() {
11100         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11101         remote_mds_nodsh && skip "remote MDS with nodsh"
11102         test_mkdir $DIR/$tdir
11103         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11104                 skip_env "no early lock cancel on server"
11105
11106         lru_resize_disable mdc
11107         lru_resize_disable osc
11108         cancel_lru_locks mdc
11109         stat $DIR/$tdir > /dev/null
11110         can1=$(do_facet $SINGLEMDS \
11111                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11112                awk '/ldlm_cancel/ {print $2}')
11113         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11114                awk '/ldlm_bl_callback/ {print $2}')
11115         touch $DIR/$tdir/f1
11116         can2=$(do_facet $SINGLEMDS \
11117                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11118                awk '/ldlm_cancel/ {print $2}')
11119         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11120                awk '/ldlm_bl_callback/ {print $2}')
11121         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11122         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11123         lru_resize_enable mdc
11124         lru_resize_enable osc
11125 }
11126 run_test 120b "Early Lock Cancel: create test"
11127
11128 test_120c() {
11129         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11130         remote_mds_nodsh && skip "remote MDS with nodsh"
11131         test_mkdir -i0 -c1 $DIR/$tdir
11132         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11133                 skip "no early lock cancel on server"
11134
11135         lru_resize_disable mdc
11136         lru_resize_disable osc
11137         test_mkdir -i0 -c1 $DIR/$tdir/d1
11138         test_mkdir -i0 -c1 $DIR/$tdir/d2
11139         touch $DIR/$tdir/d1/f1
11140         cancel_lru_locks mdc
11141         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
11142         can1=$(do_facet mds1 \
11143                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11144                awk '/ldlm_cancel/ {print $2}')
11145         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11146                awk '/ldlm_bl_callback/ {print $2}')
11147         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11148         can2=$(do_facet mds1 \
11149                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11150                awk '/ldlm_cancel/ {print $2}')
11151         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11152                awk '/ldlm_bl_callback/ {print $2}')
11153         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11154         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11155         lru_resize_enable mdc
11156         lru_resize_enable osc
11157 }
11158 run_test 120c "Early Lock Cancel: link test"
11159
11160 test_120d() {
11161         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11162         remote_mds_nodsh && skip "remote MDS with nodsh"
11163         test_mkdir -i0 -c1 $DIR/$tdir
11164         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11165                 skip_env "no early lock cancel on server"
11166
11167         lru_resize_disable mdc
11168         lru_resize_disable osc
11169         touch $DIR/$tdir
11170         cancel_lru_locks mdc
11171         stat $DIR/$tdir > /dev/null
11172         can1=$(do_facet mds1 \
11173                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11174                awk '/ldlm_cancel/ {print $2}')
11175         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11176                awk '/ldlm_bl_callback/ {print $2}')
11177         chmod a+x $DIR/$tdir
11178         can2=$(do_facet mds1 \
11179                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11180                awk '/ldlm_cancel/ {print $2}')
11181         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11182                awk '/ldlm_bl_callback/ {print $2}')
11183         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11184         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11185         lru_resize_enable mdc
11186         lru_resize_enable osc
11187 }
11188 run_test 120d "Early Lock Cancel: setattr test"
11189
11190 test_120e() {
11191         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11192         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11193                 skip_env "no early lock cancel on server"
11194         remote_mds_nodsh && skip "remote MDS with nodsh"
11195
11196         local dlmtrace_set=false
11197
11198         test_mkdir -i0 -c1 $DIR/$tdir
11199         lru_resize_disable mdc
11200         lru_resize_disable osc
11201         ! $LCTL get_param debug | grep -q dlmtrace &&
11202                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
11203         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
11204         cancel_lru_locks mdc
11205         cancel_lru_locks osc
11206         dd if=$DIR/$tdir/f1 of=/dev/null
11207         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
11208         # XXX client can not do early lock cancel of OST lock
11209         # during unlink (LU-4206), so cancel osc lock now.
11210         sleep 2
11211         cancel_lru_locks osc
11212         can1=$(do_facet mds1 \
11213                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11214                awk '/ldlm_cancel/ {print $2}')
11215         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11216                awk '/ldlm_bl_callback/ {print $2}')
11217         unlink $DIR/$tdir/f1
11218         sleep 5
11219         can2=$(do_facet mds1 \
11220                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11221                awk '/ldlm_cancel/ {print $2}')
11222         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11223                awk '/ldlm_bl_callback/ {print $2}')
11224         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
11225                 $LCTL dk $TMP/cancel.debug.txt
11226         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
11227                 $LCTL dk $TMP/blocking.debug.txt
11228         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
11229         lru_resize_enable mdc
11230         lru_resize_enable osc
11231 }
11232 run_test 120e "Early Lock Cancel: unlink test"
11233
11234 test_120f() {
11235         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11236         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11237                 skip_env "no early lock cancel on server"
11238         remote_mds_nodsh && skip "remote MDS with nodsh"
11239
11240         test_mkdir -i0 -c1 $DIR/$tdir
11241         lru_resize_disable mdc
11242         lru_resize_disable osc
11243         test_mkdir -i0 -c1 $DIR/$tdir/d1
11244         test_mkdir -i0 -c1 $DIR/$tdir/d2
11245         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
11246         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
11247         cancel_lru_locks mdc
11248         cancel_lru_locks osc
11249         dd if=$DIR/$tdir/d1/f1 of=/dev/null
11250         dd if=$DIR/$tdir/d2/f2 of=/dev/null
11251         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
11252         # XXX client can not do early lock cancel of OST lock
11253         # during rename (LU-4206), so cancel osc lock now.
11254         sleep 2
11255         cancel_lru_locks osc
11256         can1=$(do_facet mds1 \
11257                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11258                awk '/ldlm_cancel/ {print $2}')
11259         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11260                awk '/ldlm_bl_callback/ {print $2}')
11261         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11262         sleep 5
11263         can2=$(do_facet mds1 \
11264                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11265                awk '/ldlm_cancel/ {print $2}')
11266         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11267                awk '/ldlm_bl_callback/ {print $2}')
11268         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11269         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11270         lru_resize_enable mdc
11271         lru_resize_enable osc
11272 }
11273 run_test 120f "Early Lock Cancel: rename test"
11274
11275 test_120g() {
11276         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11277         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11278                 skip_env "no early lock cancel on server"
11279         remote_mds_nodsh && skip "remote MDS with nodsh"
11280
11281         lru_resize_disable mdc
11282         lru_resize_disable osc
11283         count=10000
11284         echo create $count files
11285         test_mkdir $DIR/$tdir
11286         cancel_lru_locks mdc
11287         cancel_lru_locks osc
11288         t0=$(date +%s)
11289
11290         can0=$(do_facet $SINGLEMDS \
11291                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11292                awk '/ldlm_cancel/ {print $2}')
11293         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11294                awk '/ldlm_bl_callback/ {print $2}')
11295         createmany -o $DIR/$tdir/f $count
11296         sync
11297         can1=$(do_facet $SINGLEMDS \
11298                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11299                awk '/ldlm_cancel/ {print $2}')
11300         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11301                awk '/ldlm_bl_callback/ {print $2}')
11302         t1=$(date +%s)
11303         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
11304         echo rm $count files
11305         rm -r $DIR/$tdir
11306         sync
11307         can2=$(do_facet $SINGLEMDS \
11308                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11309                awk '/ldlm_cancel/ {print $2}')
11310         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11311                awk '/ldlm_bl_callback/ {print $2}')
11312         t2=$(date +%s)
11313         echo total: $count removes in $((t2-t1))
11314         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
11315         sleep 2
11316         # wait for commitment of removal
11317         lru_resize_enable mdc
11318         lru_resize_enable osc
11319 }
11320 run_test 120g "Early Lock Cancel: performance test"
11321
11322 test_121() { #bug #10589
11323         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11324
11325         rm -rf $DIR/$tfile
11326         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
11327 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
11328         lctl set_param fail_loc=0x310
11329         cancel_lru_locks osc > /dev/null
11330         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
11331         lctl set_param fail_loc=0
11332         [[ $reads -eq $writes ]] ||
11333                 error "read $reads blocks, must be $writes blocks"
11334 }
11335 run_test 121 "read cancel race ========="
11336
11337 test_123a() { # was test 123, statahead(bug 11401)
11338         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11339
11340         SLOWOK=0
11341         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
11342                 log "testing UP system. Performance may be lower than expected."
11343                 SLOWOK=1
11344         fi
11345
11346         rm -rf $DIR/$tdir
11347         test_mkdir $DIR/$tdir
11348         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
11349         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
11350         MULT=10
11351         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
11352                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
11353
11354                 max=`lctl get_param -n llite.*.statahead_max | head -n 1`
11355                 lctl set_param -n llite.*.statahead_max 0
11356                 lctl get_param llite.*.statahead_max
11357                 cancel_lru_locks mdc
11358                 cancel_lru_locks osc
11359                 stime=`date +%s`
11360                 time ls -l $DIR/$tdir | wc -l
11361                 etime=`date +%s`
11362                 delta=$((etime - stime))
11363                 log "ls $i files without statahead: $delta sec"
11364                 lctl set_param llite.*.statahead_max=$max
11365
11366                 swrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
11367                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
11368                 cancel_lru_locks mdc
11369                 cancel_lru_locks osc
11370                 stime=`date +%s`
11371                 time ls -l $DIR/$tdir | wc -l
11372                 etime=`date +%s`
11373                 delta_sa=$((etime - stime))
11374                 log "ls $i files with statahead: $delta_sa sec"
11375                 lctl get_param -n llite.*.statahead_stats
11376                 ewrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
11377
11378                 [[ $swrong -lt $ewrong ]] &&
11379                         log "statahead was stopped, maybe too many locks held!"
11380                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
11381
11382                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
11383                     max=`lctl get_param -n llite.*.statahead_max | head -n 1`
11384                     lctl set_param -n llite.*.statahead_max 0
11385                     lctl get_param llite.*.statahead_max
11386                     cancel_lru_locks mdc
11387                     cancel_lru_locks osc
11388                     stime=`date +%s`
11389                     time ls -l $DIR/$tdir | wc -l
11390                     etime=`date +%s`
11391                     delta=$((etime - stime))
11392                     log "ls $i files again without statahead: $delta sec"
11393                     lctl set_param llite.*.statahead_max=$max
11394                     if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
11395                         if [  $SLOWOK -eq 0 ]; then
11396                                 error "ls $i files is slower with statahead!"
11397                         else
11398                                 log "ls $i files is slower with statahead!"
11399                         fi
11400                         break
11401                     fi
11402                 fi
11403
11404                 [ $delta -gt 20 ] && break
11405                 [ $delta -gt 8 ] && MULT=$((50 / delta))
11406                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
11407         done
11408         log "ls done"
11409
11410         stime=`date +%s`
11411         rm -r $DIR/$tdir
11412         sync
11413         etime=`date +%s`
11414         delta=$((etime - stime))
11415         log "rm -r $DIR/$tdir/: $delta seconds"
11416         log "rm done"
11417         lctl get_param -n llite.*.statahead_stats
11418 }
11419 run_test 123a "verify statahead work"
11420
11421 test_123b () { # statahead(bug 15027)
11422         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11423
11424         test_mkdir $DIR/$tdir
11425         createmany -o $DIR/$tdir/$tfile-%d 1000
11426
11427         cancel_lru_locks mdc
11428         cancel_lru_locks osc
11429
11430 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
11431         lctl set_param fail_loc=0x80000803
11432         ls -lR $DIR/$tdir > /dev/null
11433         log "ls done"
11434         lctl set_param fail_loc=0x0
11435         lctl get_param -n llite.*.statahead_stats
11436         rm -r $DIR/$tdir
11437         sync
11438
11439 }
11440 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
11441
11442 test_123c() {
11443         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
11444
11445         test_mkdir -i 0 -c 1 $DIR/$tdir.0
11446         test_mkdir -i 1 -c 1 $DIR/$tdir.1
11447         touch $DIR/$tdir.1/{1..3}
11448         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
11449
11450         remount_client $MOUNT
11451
11452         $MULTIOP $DIR/$tdir.0 Q
11453
11454         # let statahead to complete
11455         ls -l $DIR/$tdir.0 > /dev/null
11456
11457         testid=$(echo $TESTNAME | tr '_' ' ')
11458         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
11459                 error "statahead warning" || true
11460 }
11461 run_test 123c "Can not initialize inode warning on DNE statahead"
11462
11463 test_124a() {
11464         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11465         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11466                 skip_env "no lru resize on server"
11467
11468         local NR=2000
11469
11470         test_mkdir $DIR/$tdir
11471
11472         log "create $NR files at $DIR/$tdir"
11473         createmany -o $DIR/$tdir/f $NR ||
11474                 error "failed to create $NR files in $DIR/$tdir"
11475
11476         cancel_lru_locks mdc
11477         ls -l $DIR/$tdir > /dev/null
11478
11479         local NSDIR=""
11480         local LRU_SIZE=0
11481         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
11482                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
11483                 LRU_SIZE=$($LCTL get_param -n $PARAM)
11484                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
11485                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
11486                         log "NSDIR=$NSDIR"
11487                         log "NS=$(basename $NSDIR)"
11488                         break
11489                 fi
11490         done
11491
11492         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
11493                 skip "Not enough cached locks created!"
11494         fi
11495         log "LRU=$LRU_SIZE"
11496
11497         local SLEEP=30
11498
11499         # We know that lru resize allows one client to hold $LIMIT locks
11500         # for 10h. After that locks begin to be killed by client.
11501         local MAX_HRS=10
11502         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
11503         log "LIMIT=$LIMIT"
11504         if [ $LIMIT -lt $LRU_SIZE ]; then
11505                 skip "Limit is too small $LIMIT"
11506         fi
11507
11508         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
11509         # killing locks. Some time was spent for creating locks. This means
11510         # that up to the moment of sleep finish we must have killed some of
11511         # them (10-100 locks). This depends on how fast ther were created.
11512         # Many of them were touched in almost the same moment and thus will
11513         # be killed in groups.
11514         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE))
11515
11516         # Use $LRU_SIZE_B here to take into account real number of locks
11517         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
11518         local LRU_SIZE_B=$LRU_SIZE
11519         log "LVF=$LVF"
11520         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
11521         log "OLD_LVF=$OLD_LVF"
11522         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
11523
11524         # Let's make sure that we really have some margin. Client checks
11525         # cached locks every 10 sec.
11526         SLEEP=$((SLEEP+20))
11527         log "Sleep ${SLEEP} sec"
11528         local SEC=0
11529         while ((SEC<$SLEEP)); do
11530                 echo -n "..."
11531                 sleep 5
11532                 SEC=$((SEC+5))
11533                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
11534                 echo -n "$LRU_SIZE"
11535         done
11536         echo ""
11537         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
11538         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
11539
11540         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
11541                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
11542                 unlinkmany $DIR/$tdir/f $NR
11543                 return
11544         }
11545
11546         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
11547         log "unlink $NR files at $DIR/$tdir"
11548         unlinkmany $DIR/$tdir/f $NR
11549 }
11550 run_test 124a "lru resize ======================================="
11551
11552 get_max_pool_limit()
11553 {
11554         local limit=$($LCTL get_param \
11555                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
11556         local max=0
11557         for l in $limit; do
11558                 if [[ $l -gt $max ]]; then
11559                         max=$l
11560                 fi
11561         done
11562         echo $max
11563 }
11564
11565 test_124b() {
11566         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11567         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11568                 skip_env "no lru resize on server"
11569
11570         LIMIT=$(get_max_pool_limit)
11571
11572         NR=$(($(default_lru_size)*20))
11573         if [[ $NR -gt $LIMIT ]]; then
11574                 log "Limit lock number by $LIMIT locks"
11575                 NR=$LIMIT
11576         fi
11577
11578         IFree=$(mdsrate_inodes_available)
11579         if [ $IFree -lt $NR ]; then
11580                 log "Limit lock number by $IFree inodes"
11581                 NR=$IFree
11582         fi
11583
11584         lru_resize_disable mdc
11585         test_mkdir -p $DIR/$tdir/disable_lru_resize
11586
11587         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
11588         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
11589         cancel_lru_locks mdc
11590         stime=`date +%s`
11591         PID=""
11592         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11593         PID="$PID $!"
11594         sleep 2
11595         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11596         PID="$PID $!"
11597         sleep 2
11598         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11599         PID="$PID $!"
11600         wait $PID
11601         etime=`date +%s`
11602         nolruresize_delta=$((etime-stime))
11603         log "ls -la time: $nolruresize_delta seconds"
11604         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
11605         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
11606
11607         lru_resize_enable mdc
11608         test_mkdir -p $DIR/$tdir/enable_lru_resize
11609
11610         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
11611         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
11612         cancel_lru_locks mdc
11613         stime=`date +%s`
11614         PID=""
11615         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11616         PID="$PID $!"
11617         sleep 2
11618         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11619         PID="$PID $!"
11620         sleep 2
11621         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11622         PID="$PID $!"
11623         wait $PID
11624         etime=`date +%s`
11625         lruresize_delta=$((etime-stime))
11626         log "ls -la time: $lruresize_delta seconds"
11627         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
11628
11629         if [ $lruresize_delta -gt $nolruresize_delta ]; then
11630                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
11631         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
11632                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
11633         else
11634                 log "lru resize performs the same with no lru resize"
11635         fi
11636         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
11637 }
11638 run_test 124b "lru resize (performance test) ======================="
11639
11640 test_124c() {
11641         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11642         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11643                 skip_env "no lru resize on server"
11644
11645         # cache ununsed locks on client
11646         local nr=100
11647         cancel_lru_locks mdc
11648         test_mkdir $DIR/$tdir
11649         createmany -o $DIR/$tdir/f $nr ||
11650                 error "failed to create $nr files in $DIR/$tdir"
11651         ls -l $DIR/$tdir > /dev/null
11652
11653         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
11654         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11655         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
11656         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
11657         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
11658
11659         # set lru_max_age to 1 sec
11660         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
11661         echo "sleep $((recalc_p * 2)) seconds..."
11662         sleep $((recalc_p * 2))
11663
11664         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
11665         # restore lru_max_age
11666         $LCTL set_param -n $nsdir.lru_max_age $max_age
11667         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
11668         unlinkmany $DIR/$tdir/f $nr
11669 }
11670 run_test 124c "LRUR cancel very aged locks"
11671
11672 test_124d() {
11673         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11674         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11675                 skip_env "no lru resize on server"
11676
11677         # cache ununsed locks on client
11678         local nr=100
11679
11680         lru_resize_disable mdc
11681         stack_trap "lru_resize_enable mdc" EXIT
11682
11683         cancel_lru_locks mdc
11684
11685         # asynchronous object destroy at MDT could cause bl ast to client
11686         test_mkdir $DIR/$tdir
11687         createmany -o $DIR/$tdir/f $nr ||
11688                 error "failed to create $nr files in $DIR/$tdir"
11689         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
11690
11691         ls -l $DIR/$tdir > /dev/null
11692
11693         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
11694         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11695         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
11696         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
11697
11698         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
11699
11700         # set lru_max_age to 1 sec
11701         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
11702         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
11703
11704         echo "sleep $((recalc_p * 2)) seconds..."
11705         sleep $((recalc_p * 2))
11706
11707         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
11708
11709         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
11710 }
11711 run_test 124d "cancel very aged locks if lru-resize diasbaled"
11712
11713 test_125() { # 13358
11714         $LCTL get_param -n llite.*.client_type | grep -q local ||
11715                 skip "must run as local client"
11716         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
11717                 skip_env "must have acl enabled"
11718         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
11719
11720         test_mkdir $DIR/$tdir
11721         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
11722         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
11723         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
11724 }
11725 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
11726
11727 test_126() { # bug 12829/13455
11728         $GSS && skip_env "must run as gss disabled"
11729         $LCTL get_param -n llite.*.client_type | grep -q local ||
11730                 skip "must run as local client"
11731         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
11732
11733         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
11734         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
11735         rm -f $DIR/$tfile
11736         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
11737 }
11738 run_test 126 "check that the fsgid provided by the client is taken into account"
11739
11740 test_127a() { # bug 15521
11741         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11742         local name count samp unit min max sum sumsq
11743
11744         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
11745         echo "stats before reset"
11746         $LCTL get_param osc.*.stats
11747         $LCTL set_param osc.*.stats=0
11748         local fsize=$((2048 * 1024))
11749
11750         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
11751         cancel_lru_locks osc
11752         dd if=$DIR/$tfile of=/dev/null bs=$fsize
11753
11754         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
11755         stack_trap "rm -f $TMP/$tfile.tmp"
11756         while read name count samp unit min max sum sumsq; do
11757                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
11758                 [ ! $min ] && error "Missing min value for $name proc entry"
11759                 eval $name=$count || error "Wrong proc format"
11760
11761                 case $name in
11762                 read_bytes|write_bytes)
11763                         [[ "$unit" =~ "bytes" ]] ||
11764                                 error "unit is not 'bytes': $unit"
11765                         (( $min >= 4096 )) || error "min is too small: $min"
11766                         (( $min <= $fsize )) || error "min is too big: $min"
11767                         (( $max >= 4096 )) || error "max is too small: $max"
11768                         (( $max <= $fsize )) || error "max is too big: $max"
11769                         (( $sum == $fsize )) || error "sum is wrong: $sum"
11770                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
11771                                 error "sumsquare is too small: $sumsq"
11772                         (( $sumsq <= $fsize * $fsize )) ||
11773                                 error "sumsquare is too big: $sumsq"
11774                         ;;
11775                 ost_read|ost_write)
11776                         [[ "$unit" =~ "usec" ]] ||
11777                                 error "unit is not 'usec': $unit"
11778                         ;;
11779                 *)      ;;
11780                 esac
11781         done < $DIR/$tfile.tmp
11782
11783         #check that we actually got some stats
11784         [ "$read_bytes" ] || error "Missing read_bytes stats"
11785         [ "$write_bytes" ] || error "Missing write_bytes stats"
11786         [ "$read_bytes" != 0 ] || error "no read done"
11787         [ "$write_bytes" != 0 ] || error "no write done"
11788 }
11789 run_test 127a "verify the client stats are sane"
11790
11791 test_127b() { # bug LU-333
11792         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11793         local name count samp unit min max sum sumsq
11794
11795         echo "stats before reset"
11796         $LCTL get_param llite.*.stats
11797         $LCTL set_param llite.*.stats=0
11798
11799         # perform 2 reads and writes so MAX is different from SUM.
11800         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
11801         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
11802         cancel_lru_locks osc
11803         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
11804         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
11805
11806         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
11807         stack_trap "rm -f $TMP/$tfile.tmp"
11808         while read name count samp unit min max sum sumsq; do
11809                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
11810                 eval $name=$count || error "Wrong proc format"
11811
11812                 case $name in
11813                 read_bytes|write_bytes)
11814                         [[ "$unit" =~ "bytes" ]] ||
11815                                 error "unit is not 'bytes': $unit"
11816                         (( $count == 2 )) || error "count is not 2: $count"
11817                         (( $min == $PAGE_SIZE )) ||
11818                                 error "min is not $PAGE_SIZE: $min"
11819                         (( $max == $PAGE_SIZE )) ||
11820                                 error "max is not $PAGE_SIZE: $max"
11821                         (( $sum == $PAGE_SIZE * 2 )) ||
11822                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
11823                         ;;
11824                 read|write)
11825                         [[ "$unit" =~ "usec" ]] ||
11826                                 error "unit is not 'usec': $unit"
11827                         ;;
11828                 *)      ;;
11829                 esac
11830         done < $TMP/$tfile.tmp
11831
11832         #check that we actually got some stats
11833         [ "$read_bytes" ] || error "Missing read_bytes stats"
11834         [ "$write_bytes" ] || error "Missing write_bytes stats"
11835         [ "$read_bytes" != 0 ] || error "no read done"
11836         [ "$write_bytes" != 0 ] || error "no write done"
11837 }
11838 run_test 127b "verify the llite client stats are sane"
11839
11840 test_127c() { # LU-12394
11841         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
11842         local size
11843         local bsize
11844         local reads
11845         local writes
11846         local count
11847
11848         $LCTL set_param llite.*.extents_stats=1
11849         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
11850
11851         # Use two stripes so there is enough space in default config
11852         $LFS setstripe -c 2 $DIR/$tfile
11853
11854         # Extent stats start at 0-4K and go in power of two buckets
11855         # LL_HIST_START = 12 --> 2^12 = 4K
11856         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
11857         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
11858         # small configs
11859         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
11860                 do
11861                 # Write and read, 2x each, second time at a non-zero offset
11862                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
11863                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
11864                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
11865                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
11866                 rm -f $DIR/$tfile
11867         done
11868
11869         $LCTL get_param llite.*.extents_stats
11870
11871         count=2
11872         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
11873                 do
11874                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
11875                                 grep -m 1 $bsize)
11876                 reads=$(echo $bucket | awk '{print $5}')
11877                 writes=$(echo $bucket | awk '{print $9}')
11878                 [ "$reads" -eq $count ] ||
11879                         error "$reads reads in < $bsize bucket, expect $count"
11880                 [ "$writes" -eq $count ] ||
11881                         error "$writes writes in < $bsize bucket, expect $count"
11882         done
11883
11884         # Test mmap write and read
11885         $LCTL set_param llite.*.extents_stats=c
11886         size=512
11887         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
11888         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
11889         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
11890
11891         $LCTL get_param llite.*.extents_stats
11892
11893         count=$(((size*1024) / PAGE_SIZE))
11894
11895         bsize=$((2 * PAGE_SIZE / 1024))K
11896
11897         bucket=$($LCTL get_param -n llite.*.extents_stats |
11898                         grep -m 1 $bsize)
11899         reads=$(echo $bucket | awk '{print $5}')
11900         writes=$(echo $bucket | awk '{print $9}')
11901         # mmap writes fault in the page first, creating an additonal read
11902         [ "$reads" -eq $((2 * count)) ] ||
11903                 error "$reads reads in < $bsize bucket, expect $count"
11904         [ "$writes" -eq $count ] ||
11905                 error "$writes writes in < $bsize bucket, expect $count"
11906 }
11907 run_test 127c "test llite extent stats with regular & mmap i/o"
11908
11909 test_128() { # bug 15212
11910         touch $DIR/$tfile
11911         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
11912                 find $DIR/$tfile
11913                 find $DIR/$tfile
11914         EOF
11915
11916         result=$(grep error $TMP/$tfile.log)
11917         rm -f $DIR/$tfile $TMP/$tfile.log
11918         [ -z "$result" ] ||
11919                 error "consecutive find's under interactive lfs failed"
11920 }
11921 run_test 128 "interactive lfs for 2 consecutive find's"
11922
11923 set_dir_limits () {
11924         local mntdev
11925         local canondev
11926         local node
11927
11928         local ldproc=/proc/fs/ldiskfs
11929         local facets=$(get_facets MDS)
11930
11931         for facet in ${facets//,/ }; do
11932                 canondev=$(ldiskfs_canon \
11933                            *.$(convert_facet2label $facet).mntdev $facet)
11934                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
11935                         ldproc=/sys/fs/ldiskfs
11936                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
11937                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
11938         done
11939 }
11940
11941 check_mds_dmesg() {
11942         local facets=$(get_facets MDS)
11943         for facet in ${facets//,/ }; do
11944                 do_facet $facet "dmesg | tail -3 | grep -q $1" && return 0
11945         done
11946         return 1
11947 }
11948
11949 test_129() {
11950         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11951         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
11952                 skip "Need MDS version with at least 2.5.56"
11953         if [ "$mds1_FSTYPE" != ldiskfs ]; then
11954                 skip_env "ldiskfs only test"
11955         fi
11956         remote_mds_nodsh && skip "remote MDS with nodsh"
11957
11958         local ENOSPC=28
11959         local EFBIG=27
11960         local has_warning=false
11961
11962         rm -rf $DIR/$tdir
11963         mkdir -p $DIR/$tdir
11964
11965         # block size of mds1
11966         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 5))
11967         set_dir_limits $maxsize $maxsize
11968         local dirsize=$(stat -c%s "$DIR/$tdir")
11969         local nfiles=0
11970         while [[ $dirsize -le $maxsize ]]; do
11971                 $MULTIOP $DIR/$tdir/file_base_$nfiles Oc
11972                 rc=$?
11973                 if ! $has_warning; then
11974                         check_mds_dmesg '"is approaching"' && has_warning=true
11975                 fi
11976                 # check two errors:
11977                 # ENOSPC for new ext4 max_dir_size (kernel commit df981d03ee)
11978                 # EFBIG for previous versions included in ldiskfs series
11979                 if [ $rc -eq $EFBIG ] || [ $rc -eq $ENOSPC ]; then
11980                         set_dir_limits 0 0
11981                         echo "return code $rc received as expected"
11982
11983                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
11984                                 error_exit "create failed w/o dir size limit"
11985
11986                         check_mds_dmesg '"has reached"' ||
11987                                 error_exit "reached message should be output"
11988
11989                         [ $has_warning = "false" ] &&
11990                                 error_exit "warning message should be output"
11991
11992                         dirsize=$(stat -c%s "$DIR/$tdir")
11993
11994                         [[ $dirsize -ge $maxsize ]] && return 0
11995                         error_exit "current dir size $dirsize, " \
11996                                    "previous limit $maxsize"
11997                 elif [ $rc -ne 0 ]; then
11998                         set_dir_limits 0 0
11999                         error_exit "return $rc received instead of expected " \
12000                                    "$EFBIG or $ENOSPC, files in dir $dirsize"
12001                 fi
12002                 nfiles=$((nfiles + 1))
12003                 dirsize=$(stat -c%s "$DIR/$tdir")
12004         done
12005
12006         set_dir_limits 0 0
12007         error "exceeded dir size limit $maxsize($MDSCOUNT) : $dirsize bytes"
12008 }
12009 run_test 129 "test directory size limit ========================"
12010
12011 OLDIFS="$IFS"
12012 cleanup_130() {
12013         trap 0
12014         IFS="$OLDIFS"
12015 }
12016
12017 test_130a() {
12018         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12019         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12020
12021         trap cleanup_130 EXIT RETURN
12022
12023         local fm_file=$DIR/$tfile
12024         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
12025         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
12026                 error "dd failed for $fm_file"
12027
12028         # LU-1795: test filefrag/FIEMAP once, even if unsupported
12029         filefrag -ves $fm_file
12030         RC=$?
12031         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12032                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12033         [ $RC != 0 ] && error "filefrag $fm_file failed"
12034
12035         filefrag_op=$(filefrag -ve -k $fm_file |
12036                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12037         lun=$($LFS getstripe -i $fm_file)
12038
12039         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
12040         IFS=$'\n'
12041         tot_len=0
12042         for line in $filefrag_op
12043         do
12044                 frag_lun=`echo $line | cut -d: -f5`
12045                 ext_len=`echo $line | cut -d: -f4`
12046                 if (( $frag_lun != $lun )); then
12047                         cleanup_130
12048                         error "FIEMAP on 1-stripe file($fm_file) failed"
12049                         return
12050                 fi
12051                 (( tot_len += ext_len ))
12052         done
12053
12054         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
12055                 cleanup_130
12056                 error "FIEMAP on 1-stripe file($fm_file) failed;"
12057                 return
12058         fi
12059
12060         cleanup_130
12061
12062         echo "FIEMAP on single striped file succeeded"
12063 }
12064 run_test 130a "FIEMAP (1-stripe file)"
12065
12066 test_130b() {
12067         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12068
12069         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12070         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12071
12072         trap cleanup_130 EXIT RETURN
12073
12074         local fm_file=$DIR/$tfile
12075         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12076                         error "setstripe on $fm_file"
12077         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12078                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12079
12080         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
12081                 error "dd failed on $fm_file"
12082
12083         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12084         filefrag_op=$(filefrag -ve -k $fm_file |
12085                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12086
12087         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12088                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12089
12090         IFS=$'\n'
12091         tot_len=0
12092         num_luns=1
12093         for line in $filefrag_op
12094         do
12095                 frag_lun=$(echo $line | cut -d: -f5 |
12096                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12097                 ext_len=$(echo $line | cut -d: -f4)
12098                 if (( $frag_lun != $last_lun )); then
12099                         if (( tot_len != 1024 )); then
12100                                 cleanup_130
12101                                 error "FIEMAP on $fm_file failed; returned " \
12102                                 "len $tot_len for OST $last_lun instead of 1024"
12103                                 return
12104                         else
12105                                 (( num_luns += 1 ))
12106                                 tot_len=0
12107                         fi
12108                 fi
12109                 (( tot_len += ext_len ))
12110                 last_lun=$frag_lun
12111         done
12112         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
12113                 cleanup_130
12114                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12115                         "luns or wrong len for OST $last_lun"
12116                 return
12117         fi
12118
12119         cleanup_130
12120
12121         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
12122 }
12123 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
12124
12125 test_130c() {
12126         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12127
12128         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12129         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12130
12131         trap cleanup_130 EXIT RETURN
12132
12133         local fm_file=$DIR/$tfile
12134         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
12135         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12136                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12137
12138         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
12139                         error "dd failed on $fm_file"
12140
12141         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12142         filefrag_op=$(filefrag -ve -k $fm_file |
12143                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12144
12145         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12146                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12147
12148         IFS=$'\n'
12149         tot_len=0
12150         num_luns=1
12151         for line in $filefrag_op
12152         do
12153                 frag_lun=$(echo $line | cut -d: -f5 |
12154                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12155                 ext_len=$(echo $line | cut -d: -f4)
12156                 if (( $frag_lun != $last_lun )); then
12157                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
12158                         if (( logical != 512 )); then
12159                                 cleanup_130
12160                                 error "FIEMAP on $fm_file failed; returned " \
12161                                 "logical start for lun $logical instead of 512"
12162                                 return
12163                         fi
12164                         if (( tot_len != 512 )); then
12165                                 cleanup_130
12166                                 error "FIEMAP on $fm_file failed; returned " \
12167                                 "len $tot_len for OST $last_lun instead of 1024"
12168                                 return
12169                         else
12170                                 (( num_luns += 1 ))
12171                                 tot_len=0
12172                         fi
12173                 fi
12174                 (( tot_len += ext_len ))
12175                 last_lun=$frag_lun
12176         done
12177         if (( num_luns != 2 || tot_len != 512 )); then
12178                 cleanup_130
12179                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12180                         "luns or wrong len for OST $last_lun"
12181                 return
12182         fi
12183
12184         cleanup_130
12185
12186         echo "FIEMAP on 2-stripe file with hole succeeded"
12187 }
12188 run_test 130c "FIEMAP (2-stripe file with hole)"
12189
12190 test_130d() {
12191         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
12192
12193         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12194         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12195
12196         trap cleanup_130 EXIT RETURN
12197
12198         local fm_file=$DIR/$tfile
12199         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12200                         error "setstripe on $fm_file"
12201         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12202                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12203
12204         local actual_stripe_count=$($LFS getstripe -c $fm_file)
12205         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
12206                 error "dd failed on $fm_file"
12207
12208         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12209         filefrag_op=$(filefrag -ve -k $fm_file |
12210                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12211
12212         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12213                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12214
12215         IFS=$'\n'
12216         tot_len=0
12217         num_luns=1
12218         for line in $filefrag_op
12219         do
12220                 frag_lun=$(echo $line | cut -d: -f5 |
12221                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12222                 ext_len=$(echo $line | cut -d: -f4)
12223                 if (( $frag_lun != $last_lun )); then
12224                         if (( tot_len != 1024 )); then
12225                                 cleanup_130
12226                                 error "FIEMAP on $fm_file failed; returned " \
12227                                 "len $tot_len for OST $last_lun instead of 1024"
12228                                 return
12229                         else
12230                                 (( num_luns += 1 ))
12231                                 tot_len=0
12232                         fi
12233                 fi
12234                 (( tot_len += ext_len ))
12235                 last_lun=$frag_lun
12236         done
12237         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
12238                 cleanup_130
12239                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12240                         "luns or wrong len for OST $last_lun"
12241                 return
12242         fi
12243
12244         cleanup_130
12245
12246         echo "FIEMAP on N-stripe file succeeded"
12247 }
12248 run_test 130d "FIEMAP (N-stripe file)"
12249
12250 test_130e() {
12251         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12252
12253         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12254         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12255
12256         trap cleanup_130 EXIT RETURN
12257
12258         local fm_file=$DIR/$tfile
12259         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
12260         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12261                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12262
12263         NUM_BLKS=512
12264         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
12265         for ((i = 0; i < $NUM_BLKS; i++))
12266         do
12267                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) conv=notrunc > /dev/null 2>&1
12268         done
12269
12270         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12271         filefrag_op=$(filefrag -ve -k $fm_file |
12272                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12273
12274         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12275                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12276
12277         IFS=$'\n'
12278         tot_len=0
12279         num_luns=1
12280         for line in $filefrag_op
12281         do
12282                 frag_lun=$(echo $line | cut -d: -f5 |
12283                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12284                 ext_len=$(echo $line | cut -d: -f4)
12285                 if (( $frag_lun != $last_lun )); then
12286                         if (( tot_len != $EXPECTED_LEN )); then
12287                                 cleanup_130
12288                                 error "FIEMAP on $fm_file failed; returned " \
12289                                 "len $tot_len for OST $last_lun instead " \
12290                                 "of $EXPECTED_LEN"
12291                                 return
12292                         else
12293                                 (( num_luns += 1 ))
12294                                 tot_len=0
12295                         fi
12296                 fi
12297                 (( tot_len += ext_len ))
12298                 last_lun=$frag_lun
12299         done
12300         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
12301                 cleanup_130
12302                 error "FIEMAP on $fm_file failed; returned wrong number " \
12303                         "of luns or wrong len for OST $last_lun"
12304                 return
12305         fi
12306
12307         cleanup_130
12308
12309         echo "FIEMAP with continuation calls succeeded"
12310 }
12311 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
12312
12313 test_130f() {
12314         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12315         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12316
12317         local fm_file=$DIR/$tfile
12318         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
12319                 error "multiop create with lov_delay_create on $fm_file"
12320
12321         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12322         filefrag_extents=$(filefrag -vek $fm_file |
12323                            awk '/extents? found/ { print $2 }')
12324         if [[ "$filefrag_extents" != "0" ]]; then
12325                 error "FIEMAP on $fm_file failed; " \
12326                       "returned $filefrag_extents expected 0"
12327         fi
12328
12329         rm -f $fm_file
12330 }
12331 run_test 130f "FIEMAP (unstriped file)"
12332
12333 # Test for writev/readv
12334 test_131a() {
12335         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
12336                 error "writev test failed"
12337         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
12338                 error "readv failed"
12339         rm -f $DIR/$tfile
12340 }
12341 run_test 131a "test iov's crossing stripe boundary for writev/readv"
12342
12343 test_131b() {
12344         local fsize=$((524288 + 1048576 + 1572864))
12345         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
12346                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12347                         error "append writev test failed"
12348
12349         ((fsize += 1572864 + 1048576))
12350         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
12351                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12352                         error "append writev test failed"
12353         rm -f $DIR/$tfile
12354 }
12355 run_test 131b "test append writev"
12356
12357 test_131c() {
12358         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
12359         error "NOT PASS"
12360 }
12361 run_test 131c "test read/write on file w/o objects"
12362
12363 test_131d() {
12364         rwv -f $DIR/$tfile -w -n 1 1572864
12365         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
12366         if [ "$NOB" != 1572864 ]; then
12367                 error "Short read filed: read $NOB bytes instead of 1572864"
12368         fi
12369         rm -f $DIR/$tfile
12370 }
12371 run_test 131d "test short read"
12372
12373 test_131e() {
12374         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
12375         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
12376         error "read hitting hole failed"
12377         rm -f $DIR/$tfile
12378 }
12379 run_test 131e "test read hitting hole"
12380
12381 check_stats() {
12382         local facet=$1
12383         local op=$2
12384         local want=${3:-0}
12385         local res
12386
12387         case $facet in
12388         mds*) res=$(do_facet $facet \
12389                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
12390                  ;;
12391         ost*) res=$(do_facet $facet \
12392                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
12393                  ;;
12394         *) error "Wrong facet '$facet'" ;;
12395         esac
12396         [ "$res" ] || error "The counter for $op on $facet was not incremented"
12397         # if the argument $3 is zero, it means any stat increment is ok.
12398         if [[ $want -gt 0 ]]; then
12399                 local count=$(echo $res | awk '{ print $2 }')
12400                 [[ $count -ne $want ]] &&
12401                         error "The $op counter on $facet is $count, not $want"
12402         fi
12403 }
12404
12405 test_133a() {
12406         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12407         remote_ost_nodsh && skip "remote OST with nodsh"
12408         remote_mds_nodsh && skip "remote MDS with nodsh"
12409         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
12410                 skip_env "MDS doesn't support rename stats"
12411
12412         local testdir=$DIR/${tdir}/stats_testdir
12413
12414         mkdir -p $DIR/${tdir}
12415
12416         # clear stats.
12417         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12418         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12419
12420         # verify mdt stats first.
12421         mkdir ${testdir} || error "mkdir failed"
12422         check_stats $SINGLEMDS "mkdir" 1
12423         touch ${testdir}/${tfile} || error "touch failed"
12424         check_stats $SINGLEMDS "open" 1
12425         check_stats $SINGLEMDS "close" 1
12426         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
12427                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
12428                 check_stats $SINGLEMDS "mknod" 2
12429         }
12430         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
12431         check_stats $SINGLEMDS "unlink" 1
12432         rm -f ${testdir}/${tfile} || error "file remove failed"
12433         check_stats $SINGLEMDS "unlink" 2
12434
12435         # remove working dir and check mdt stats again.
12436         rmdir ${testdir} || error "rmdir failed"
12437         check_stats $SINGLEMDS "rmdir" 1
12438
12439         local testdir1=$DIR/${tdir}/stats_testdir1
12440         mkdir -p ${testdir}
12441         mkdir -p ${testdir1}
12442         touch ${testdir1}/test1
12443         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
12444         check_stats $SINGLEMDS "crossdir_rename" 1
12445
12446         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
12447         check_stats $SINGLEMDS "samedir_rename" 1
12448
12449         rm -rf $DIR/${tdir}
12450 }
12451 run_test 133a "Verifying MDT stats ========================================"
12452
12453 test_133b() {
12454         local res
12455
12456         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12457         remote_ost_nodsh && skip "remote OST with nodsh"
12458         remote_mds_nodsh && skip "remote MDS with nodsh"
12459
12460         local testdir=$DIR/${tdir}/stats_testdir
12461
12462         mkdir -p ${testdir} || error "mkdir failed"
12463         touch ${testdir}/${tfile} || error "touch failed"
12464         cancel_lru_locks mdc
12465
12466         # clear stats.
12467         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12468         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12469
12470         # extra mdt stats verification.
12471         chmod 444 ${testdir}/${tfile} || error "chmod failed"
12472         check_stats $SINGLEMDS "setattr" 1
12473         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12474         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
12475         then            # LU-1740
12476                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
12477                 check_stats $SINGLEMDS "getattr" 1
12478         fi
12479         rm -rf $DIR/${tdir}
12480
12481         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
12482         # so the check below is not reliable
12483         [ $MDSCOUNT -eq 1 ] || return 0
12484
12485         # Sleep to avoid a cached response.
12486         #define OBD_STATFS_CACHE_SECONDS 1
12487         sleep 2
12488         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12489         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12490         $LFS df || error "lfs failed"
12491         check_stats $SINGLEMDS "statfs" 1
12492
12493         # check aggregated statfs (LU-10018)
12494         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
12495                 return 0
12496         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
12497                 return 0
12498         sleep 2
12499         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12500         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12501         df $DIR
12502         check_stats $SINGLEMDS "statfs" 1
12503
12504         # We want to check that the client didn't send OST_STATFS to
12505         # ost1 but the MDT also uses OST_STATFS for precreate. So some
12506         # extra care is needed here.
12507         if remote_mds; then
12508                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
12509                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
12510
12511                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
12512                 [ "$res" ] && error "OST got STATFS"
12513         fi
12514
12515         return 0
12516 }
12517 run_test 133b "Verifying extra MDT stats =================================="
12518
12519 test_133c() {
12520         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12521         remote_ost_nodsh && skip "remote OST with nodsh"
12522         remote_mds_nodsh && skip "remote MDS with nodsh"
12523
12524         local testdir=$DIR/$tdir/stats_testdir
12525
12526         test_mkdir -p $testdir
12527
12528         # verify obdfilter stats.
12529         $LFS setstripe -c 1 -i 0 $testdir/$tfile
12530         sync
12531         cancel_lru_locks osc
12532         wait_delete_completed
12533
12534         # clear stats.
12535         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12536         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12537
12538         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
12539                 error "dd failed"
12540         sync
12541         cancel_lru_locks osc
12542         check_stats ost1 "write" 1
12543
12544         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
12545         check_stats ost1 "read" 1
12546
12547         > $testdir/$tfile || error "truncate failed"
12548         check_stats ost1 "punch" 1
12549
12550         rm -f $testdir/$tfile || error "file remove failed"
12551         wait_delete_completed
12552         check_stats ost1 "destroy" 1
12553
12554         rm -rf $DIR/$tdir
12555 }
12556 run_test 133c "Verifying OST stats ========================================"
12557
12558 order_2() {
12559         local value=$1
12560         local orig=$value
12561         local order=1
12562
12563         while [ $value -ge 2 ]; do
12564                 order=$((order*2))
12565                 value=$((value/2))
12566         done
12567
12568         if [ $orig -gt $order ]; then
12569                 order=$((order*2))
12570         fi
12571         echo $order
12572 }
12573
12574 size_in_KMGT() {
12575     local value=$1
12576     local size=('K' 'M' 'G' 'T');
12577     local i=0
12578     local size_string=$value
12579
12580     while [ $value -ge 1024 ]; do
12581         if [ $i -gt 3 ]; then
12582             #T is the biggest unit we get here, if that is bigger,
12583             #just return XXXT
12584             size_string=${value}T
12585             break
12586         fi
12587         value=$((value >> 10))
12588         if [ $value -lt 1024 ]; then
12589             size_string=${value}${size[$i]}
12590             break
12591         fi
12592         i=$((i + 1))
12593     done
12594
12595     echo $size_string
12596 }
12597
12598 get_rename_size() {
12599         local size=$1
12600         local context=${2:-.}
12601         local sample=$(do_facet $SINGLEMDS $LCTL \
12602                 get_param mdt.$FSNAME-MDT0000.rename_stats |
12603                 grep -A1 $context |
12604                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
12605         echo $sample
12606 }
12607
12608 test_133d() {
12609         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12610         remote_ost_nodsh && skip "remote OST with nodsh"
12611         remote_mds_nodsh && skip "remote MDS with nodsh"
12612         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
12613                 skip_env "MDS doesn't support rename stats"
12614
12615         local testdir1=$DIR/${tdir}/stats_testdir1
12616         local testdir2=$DIR/${tdir}/stats_testdir2
12617         mkdir -p $DIR/${tdir}
12618
12619         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
12620
12621         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
12622         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
12623
12624         createmany -o $testdir1/test 512 || error "createmany failed"
12625
12626         # check samedir rename size
12627         mv ${testdir1}/test0 ${testdir1}/test_0
12628
12629         local testdir1_size=$(ls -l $DIR/${tdir} |
12630                 awk '/stats_testdir1/ {print $5}')
12631         local testdir2_size=$(ls -l $DIR/${tdir} |
12632                 awk '/stats_testdir2/ {print $5}')
12633
12634         testdir1_size=$(order_2 $testdir1_size)
12635         testdir2_size=$(order_2 $testdir2_size)
12636
12637         testdir1_size=$(size_in_KMGT $testdir1_size)
12638         testdir2_size=$(size_in_KMGT $testdir2_size)
12639
12640         echo "source rename dir size: ${testdir1_size}"
12641         echo "target rename dir size: ${testdir2_size}"
12642
12643         local cmd="do_facet $SINGLEMDS $LCTL "
12644         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
12645
12646         eval $cmd || error "$cmd failed"
12647         local samedir=$($cmd | grep 'same_dir')
12648         local same_sample=$(get_rename_size $testdir1_size)
12649         [ -z "$samedir" ] && error "samedir_rename_size count error"
12650         [[ $same_sample -eq 1 ]] ||
12651                 error "samedir_rename_size error $same_sample"
12652         echo "Check same dir rename stats success"
12653
12654         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
12655
12656         # check crossdir rename size
12657         mv ${testdir1}/test_0 ${testdir2}/test_0
12658
12659         testdir1_size=$(ls -l $DIR/${tdir} |
12660                 awk '/stats_testdir1/ {print $5}')
12661         testdir2_size=$(ls -l $DIR/${tdir} |
12662                 awk '/stats_testdir2/ {print $5}')
12663
12664         testdir1_size=$(order_2 $testdir1_size)
12665         testdir2_size=$(order_2 $testdir2_size)
12666
12667         testdir1_size=$(size_in_KMGT $testdir1_size)
12668         testdir2_size=$(size_in_KMGT $testdir2_size)
12669
12670         echo "source rename dir size: ${testdir1_size}"
12671         echo "target rename dir size: ${testdir2_size}"
12672
12673         eval $cmd || error "$cmd failed"
12674         local crossdir=$($cmd | grep 'crossdir')
12675         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
12676         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
12677         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
12678         [[ $src_sample -eq 1 ]] ||
12679                 error "crossdir_rename_size error $src_sample"
12680         [[ $tgt_sample -eq 1 ]] ||
12681                 error "crossdir_rename_size error $tgt_sample"
12682         echo "Check cross dir rename stats success"
12683         rm -rf $DIR/${tdir}
12684 }
12685 run_test 133d "Verifying rename_stats ========================================"
12686
12687 test_133e() {
12688         remote_mds_nodsh && skip "remote MDS with nodsh"
12689         remote_ost_nodsh && skip "remote OST with nodsh"
12690         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12691
12692         local testdir=$DIR/${tdir}/stats_testdir
12693         local ctr f0 f1 bs=32768 count=42 sum
12694
12695         mkdir -p ${testdir} || error "mkdir failed"
12696
12697         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
12698
12699         for ctr in {write,read}_bytes; do
12700                 sync
12701                 cancel_lru_locks osc
12702
12703                 do_facet ost1 $LCTL set_param -n \
12704                         "obdfilter.*.exports.clear=clear"
12705
12706                 if [ $ctr = write_bytes ]; then
12707                         f0=/dev/zero
12708                         f1=${testdir}/${tfile}
12709                 else
12710                         f0=${testdir}/${tfile}
12711                         f1=/dev/null
12712                 fi
12713
12714                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
12715                         error "dd failed"
12716                 sync
12717                 cancel_lru_locks osc
12718
12719                 sum=$(do_facet ost1 $LCTL get_param \
12720                         "obdfilter.*.exports.*.stats" |
12721                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
12722                                 $1 == ctr { sum += $7 }
12723                                 END { printf("%0.0f", sum) }')
12724
12725                 if ((sum != bs * count)); then
12726                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
12727                 fi
12728         done
12729
12730         rm -rf $DIR/${tdir}
12731 }
12732 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
12733
12734 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
12735
12736 # Some versions of find (4.5.11, 4.5.14) included in CentOS 7.3-7.5 do
12737 # not honor the -ignore_readdir_race option correctly. So we call
12738 # error_ignore() rather than error() in these cases. See LU-11152.
12739 error_133() {
12740         if (find --version; do_facet mds1 find --version) |
12741                 grep -q '\b4\.5\.1[1-4]\b'; then
12742                 error_ignore LU-11152 "$@"
12743         else
12744                 error "$@"
12745         fi
12746 }
12747
12748 test_133f() {
12749         # First without trusting modes.
12750         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
12751         echo "proc_dirs='$proc_dirs'"
12752         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
12753         find $proc_dirs -exec cat '{}' \; &> /dev/null
12754
12755         # Second verifying readability.
12756         $LCTL get_param -R '*' &> /dev/null
12757
12758         # Verifing writability with badarea_io.
12759         find $proc_dirs \
12760                 -ignore_readdir_race \
12761                 -type f \
12762                 -not -name force_lbug \
12763                 -not -name changelog_mask \
12764                 -exec badarea_io '{}' \; ||
12765                         error_133 "find $proc_dirs failed"
12766 }
12767 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
12768
12769 test_133g() {
12770         remote_mds_nodsh && skip "remote MDS with nodsh"
12771         remote_ost_nodsh && skip "remote OST with nodsh"
12772
12773         local facet
12774         for facet in mds1 ost1; do
12775                 local facet_ver=$(lustre_version_code $facet)
12776                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
12777                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
12778                 else
12779                         log "$facet: too old lustre for get_param -R"
12780                 fi
12781                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
12782                         do_facet $facet "$LCTL list_param -R '*' | grep '=' |
12783                                 tr -d = | egrep -v 'force_lbug|changelog_mask' |
12784                                 xargs badarea_io" ||
12785                                         error_133 "$facet badarea_io failed"
12786                 else
12787                         skip_noexit "$facet: too old lustre for get_param -R"
12788                 fi
12789         done
12790
12791         # remount the FS in case writes/reads /proc break the FS
12792         cleanup || error "failed to unmount"
12793         setup || error "failed to setup"
12794         true
12795 }
12796 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
12797
12798 test_133h() {
12799         remote_mds_nodsh && skip "remote MDS with nodsh"
12800         remote_ost_nodsh && skip "remote OST with nodsh"
12801         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
12802                 skip "Need MDS version at least 2.9.54"
12803
12804         local facet
12805
12806         for facet in client mds1 ost1; do
12807                 local facet_proc_dirs=$(do_facet $facet \
12808                                         \\\ls -d $proc_regexp 2> /dev/null)
12809                 [ -z "$facet_proc_dirs" ] && error "no proc_dirs on $facet"
12810                 echo "${facet}_proc_dirs='$facet_proc_dirs'"
12811                 # Get the list of files that are missing the terminating newline
12812                 local missing=($(do_facet $facet \
12813                         find ${facet_proc_dirs} -type f \|              \
12814                                 while read F\; do                       \
12815                                         awk -v FS='\v' -v RS='\v\v'     \
12816                                         "'END { if(NR>0 &&              \
12817                                         \\\$NF !~ /.*\\\n\$/)           \
12818                                                 print FILENAME}'"       \
12819                                         '\$F'\;                         \
12820                                 done 2>/dev/null))
12821                 [ ${#missing[*]} -eq 0 ] ||
12822                         error "files do not end with newline: ${missing[*]}"
12823         done
12824 }
12825 run_test 133h "Proc files should end with newlines"
12826
12827 test_134a() {
12828         remote_mds_nodsh && skip "remote MDS with nodsh"
12829         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
12830                 skip "Need MDS version at least 2.7.54"
12831
12832         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
12833         cancel_lru_locks mdc
12834
12835         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12836         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12837         [ $unused -eq 0 ] || error "$unused locks are not cleared"
12838
12839         local nr=1000
12840         createmany -o $DIR/$tdir/f $nr ||
12841                 error "failed to create $nr files in $DIR/$tdir"
12842         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12843
12844         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
12845         do_facet mds1 $LCTL set_param fail_loc=0x327
12846         do_facet mds1 $LCTL set_param fail_val=500
12847         touch $DIR/$tdir/m
12848
12849         echo "sleep 10 seconds ..."
12850         sleep 10
12851         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
12852
12853         do_facet mds1 $LCTL set_param fail_loc=0
12854         do_facet mds1 $LCTL set_param fail_val=0
12855         [ $lck_cnt -lt $unused ] ||
12856                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
12857
12858         rm $DIR/$tdir/m
12859         unlinkmany $DIR/$tdir/f $nr
12860 }
12861 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
12862
12863 test_134b() {
12864         remote_mds_nodsh && skip "remote MDS with nodsh"
12865         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
12866                 skip "Need MDS version at least 2.7.54"
12867
12868         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
12869         cancel_lru_locks mdc
12870
12871         local low_wm=$(do_facet mds1 $LCTL get_param -n \
12872                         ldlm.lock_reclaim_threshold_mb)
12873         # disable reclaim temporarily
12874         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
12875
12876         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
12877         do_facet mds1 $LCTL set_param fail_loc=0x328
12878         do_facet mds1 $LCTL set_param fail_val=500
12879
12880         $LCTL set_param debug=+trace
12881
12882         local nr=600
12883         createmany -o $DIR/$tdir/f $nr &
12884         local create_pid=$!
12885
12886         echo "Sleep $TIMEOUT seconds ..."
12887         sleep $TIMEOUT
12888         if ! ps -p $create_pid  > /dev/null 2>&1; then
12889                 do_facet mds1 $LCTL set_param fail_loc=0
12890                 do_facet mds1 $LCTL set_param fail_val=0
12891                 do_facet mds1 $LCTL set_param \
12892                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
12893                 error "createmany finished incorrectly!"
12894         fi
12895         do_facet mds1 $LCTL set_param fail_loc=0
12896         do_facet mds1 $LCTL set_param fail_val=0
12897         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
12898         wait $create_pid || return 1
12899
12900         unlinkmany $DIR/$tdir/f $nr
12901 }
12902 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
12903
12904 test_135() {
12905         remote_mds_nodsh && skip "remote MDS with nodsh"
12906         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
12907                 skip "Need MDS version at least 2.13.50"
12908         local fname
12909
12910         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
12911
12912 #define OBD_FAIL_PLAIN_RECORDS 0x1319
12913         #set only one record at plain llog
12914         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
12915
12916         #fill already existed plain llog each 64767
12917         #wrapping whole catalog
12918         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
12919
12920         createmany -o $DIR/$tdir/$tfile_ 64700
12921         for (( i = 0; i < 64700; i = i + 2 ))
12922         do
12923                 rm $DIR/$tdir/$tfile_$i &
12924                 rm $DIR/$tdir/$tfile_$((i + 1)) &
12925                 local pid=$!
12926                 wait $pid
12927         done
12928
12929         #waiting osp synchronization
12930         wait_delete_completed
12931 }
12932 run_test 135 "Race catalog processing"
12933
12934 test_136() {
12935         remote_mds_nodsh && skip "remote MDS with nodsh"
12936         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
12937                 skip "Need MDS version at least 2.13.50"
12938         local fname
12939
12940         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
12941         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
12942         #set only one record at plain llog
12943 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
12944         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
12945
12946         #fill already existed 2 plain llogs each 64767
12947         #wrapping whole catalog
12948         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
12949         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
12950         wait_delete_completed
12951
12952         createmany -o $DIR/$tdir/$tfile_ 10
12953         sleep 25
12954
12955         do_facet $SINGLEMDS $LCTL set_param fail_val=3
12956         for (( i = 0; i < 10; i = i + 3 ))
12957         do
12958                 rm $DIR/$tdir/$tfile_$i &
12959                 rm $DIR/$tdir/$tfile_$((i + 1)) &
12960                 local pid=$!
12961                 wait $pid
12962                 sleep 7
12963                 rm $DIR/$tdir/$tfile_$((i + 2)) &
12964         done
12965
12966         #waiting osp synchronization
12967         wait_delete_completed
12968 }
12969 run_test 136 "Race catalog processing 2"
12970
12971 test_140() { #bug-17379
12972         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12973
12974         test_mkdir $DIR/$tdir
12975         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
12976         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
12977
12978         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
12979         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
12980         local i=0
12981         while i=$((i + 1)); do
12982                 test_mkdir $i
12983                 cd $i || error "Changing to $i"
12984                 ln -s ../stat stat || error "Creating stat symlink"
12985                 # Read the symlink until ELOOP present,
12986                 # not LBUGing the system is considered success,
12987                 # we didn't overrun the stack.
12988                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
12989                 if [ $ret -ne 0 ]; then
12990                         if [ $ret -eq 40 ]; then
12991                                 break  # -ELOOP
12992                         else
12993                                 error "Open stat symlink"
12994                                         return
12995                         fi
12996                 fi
12997         done
12998         i=$((i - 1))
12999         echo "The symlink depth = $i"
13000         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
13001                 error "Invalid symlink depth"
13002
13003         # Test recursive symlink
13004         ln -s symlink_self symlink_self
13005         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
13006         echo "open symlink_self returns $ret"
13007         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
13008 }
13009 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
13010
13011 test_150() {
13012         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13013
13014         local TF="$TMP/$tfile"
13015
13016         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13017         cp $TF $DIR/$tfile
13018         cancel_lru_locks $OSC
13019         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
13020         remount_client $MOUNT
13021         df -P $MOUNT
13022         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
13023
13024         $TRUNCATE $TF 6000
13025         $TRUNCATE $DIR/$tfile 6000
13026         cancel_lru_locks $OSC
13027         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
13028
13029         echo "12345" >>$TF
13030         echo "12345" >>$DIR/$tfile
13031         cancel_lru_locks $OSC
13032         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
13033
13034         echo "12345" >>$TF
13035         echo "12345" >>$DIR/$tfile
13036         cancel_lru_locks $OSC
13037         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
13038
13039         rm -f $TF
13040         true
13041 }
13042 run_test 150 "truncate/append tests"
13043
13044 #LU-2902 roc_hit was not able to read all values from lproc
13045 function roc_hit_init() {
13046         local list=$(comma_list $(osts_nodes))
13047         local dir=$DIR/$tdir-check
13048         local file=$dir/$tfile
13049         local BEFORE
13050         local AFTER
13051         local idx
13052
13053         test_mkdir $dir
13054         #use setstripe to do a write to every ost
13055         for i in $(seq 0 $((OSTCOUNT-1))); do
13056                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
13057                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
13058                 idx=$(printf %04x $i)
13059                 BEFORE=$(get_osd_param $list *OST*$idx stats |
13060                         awk '$1 == "cache_access" {sum += $7}
13061                                 END { printf("%0.0f", sum) }')
13062
13063                 cancel_lru_locks osc
13064                 cat $file >/dev/null
13065
13066                 AFTER=$(get_osd_param $list *OST*$idx stats |
13067                         awk '$1 == "cache_access" {sum += $7}
13068                                 END { printf("%0.0f", sum) }')
13069
13070                 echo BEFORE:$BEFORE AFTER:$AFTER
13071                 if ! let "AFTER - BEFORE == 4"; then
13072                         rm -rf $dir
13073                         error "roc_hit is not safe to use"
13074                 fi
13075                 rm $file
13076         done
13077
13078         rm -rf $dir
13079 }
13080
13081 function roc_hit() {
13082         local list=$(comma_list $(osts_nodes))
13083         echo $(get_osd_param $list '' stats |
13084                 awk '$1 == "cache_hit" {sum += $7}
13085                         END { printf("%0.0f", sum) }')
13086 }
13087
13088 function set_cache() {
13089         local on=1
13090
13091         if [ "$2" == "off" ]; then
13092                 on=0;
13093         fi
13094         local list=$(comma_list $(osts_nodes))
13095         set_osd_param $list '' $1_cache_enable $on
13096
13097         cancel_lru_locks osc
13098 }
13099
13100 test_151() {
13101         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13102         remote_ost_nodsh && skip "remote OST with nodsh"
13103
13104         local CPAGES=3
13105         local list=$(comma_list $(osts_nodes))
13106
13107         # check whether obdfilter is cache capable at all
13108         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
13109                 skip "not cache-capable obdfilter"
13110         fi
13111
13112         # check cache is enabled on all obdfilters
13113         if get_osd_param $list '' read_cache_enable | grep 0; then
13114                 skip "oss cache is disabled"
13115         fi
13116
13117         set_osd_param $list '' writethrough_cache_enable 1
13118
13119         # check write cache is enabled on all obdfilters
13120         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
13121                 skip "oss write cache is NOT enabled"
13122         fi
13123
13124         roc_hit_init
13125
13126         #define OBD_FAIL_OBD_NO_LRU  0x609
13127         do_nodes $list $LCTL set_param fail_loc=0x609
13128
13129         # pages should be in the case right after write
13130         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
13131                 error "dd failed"
13132
13133         local BEFORE=$(roc_hit)
13134         cancel_lru_locks osc
13135         cat $DIR/$tfile >/dev/null
13136         local AFTER=$(roc_hit)
13137
13138         do_nodes $list $LCTL set_param fail_loc=0
13139
13140         if ! let "AFTER - BEFORE == CPAGES"; then
13141                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
13142         fi
13143
13144         cancel_lru_locks osc
13145         # invalidates OST cache
13146         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
13147         set_osd_param $list '' read_cache_enable 0
13148         cat $DIR/$tfile >/dev/null
13149
13150         # now data shouldn't be found in the cache
13151         BEFORE=$(roc_hit)
13152         cancel_lru_locks osc
13153         cat $DIR/$tfile >/dev/null
13154         AFTER=$(roc_hit)
13155         if let "AFTER - BEFORE != 0"; then
13156                 error "IN CACHE: before: $BEFORE, after: $AFTER"
13157         fi
13158
13159         set_osd_param $list '' read_cache_enable 1
13160         rm -f $DIR/$tfile
13161 }
13162 run_test 151 "test cache on oss and controls ==============================="
13163
13164 test_152() {
13165         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13166
13167         local TF="$TMP/$tfile"
13168
13169         # simulate ENOMEM during write
13170 #define OBD_FAIL_OST_NOMEM      0x226
13171         lctl set_param fail_loc=0x80000226
13172         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13173         cp $TF $DIR/$tfile
13174         sync || error "sync failed"
13175         lctl set_param fail_loc=0
13176
13177         # discard client's cache
13178         cancel_lru_locks osc
13179
13180         # simulate ENOMEM during read
13181         lctl set_param fail_loc=0x80000226
13182         cmp $TF $DIR/$tfile || error "cmp failed"
13183         lctl set_param fail_loc=0
13184
13185         rm -f $TF
13186 }
13187 run_test 152 "test read/write with enomem ============================"
13188
13189 test_153() {
13190         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
13191 }
13192 run_test 153 "test if fdatasync does not crash ======================="
13193
13194 dot_lustre_fid_permission_check() {
13195         local fid=$1
13196         local ffid=$MOUNT/.lustre/fid/$fid
13197         local test_dir=$2
13198
13199         echo "stat fid $fid"
13200         stat $ffid > /dev/null || error "stat $ffid failed."
13201         echo "touch fid $fid"
13202         touch $ffid || error "touch $ffid failed."
13203         echo "write to fid $fid"
13204         cat /etc/hosts > $ffid || error "write $ffid failed."
13205         echo "read fid $fid"
13206         diff /etc/hosts $ffid || error "read $ffid failed."
13207         echo "append write to fid $fid"
13208         cat /etc/hosts >> $ffid || error "append write $ffid failed."
13209         echo "rename fid $fid"
13210         mv $ffid $test_dir/$tfile.1 &&
13211                 error "rename $ffid to $tfile.1 should fail."
13212         touch $test_dir/$tfile.1
13213         mv $test_dir/$tfile.1 $ffid &&
13214                 error "rename $tfile.1 to $ffid should fail."
13215         rm -f $test_dir/$tfile.1
13216         echo "truncate fid $fid"
13217         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
13218         echo "link fid $fid"
13219         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
13220         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
13221                 echo "setfacl fid $fid"
13222                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
13223                 echo "getfacl fid $fid"
13224                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
13225         fi
13226         echo "unlink fid $fid"
13227         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
13228         echo "mknod fid $fid"
13229         mknod $ffid c 1 3 && error "mknod $ffid should fail."
13230
13231         fid=[0xf00000400:0x1:0x0]
13232         ffid=$MOUNT/.lustre/fid/$fid
13233
13234         echo "stat non-exist fid $fid"
13235         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
13236         echo "write to non-exist fid $fid"
13237         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
13238         echo "link new fid $fid"
13239         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
13240
13241         mkdir -p $test_dir/$tdir
13242         touch $test_dir/$tdir/$tfile
13243         fid=$($LFS path2fid $test_dir/$tdir)
13244         rc=$?
13245         [ $rc -ne 0 ] &&
13246                 error "error: could not get fid for $test_dir/$dir/$tfile."
13247
13248         ffid=$MOUNT/.lustre/fid/$fid
13249
13250         echo "ls $fid"
13251         ls $ffid > /dev/null || error "ls $ffid failed."
13252         echo "touch $fid/$tfile.1"
13253         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
13254
13255         echo "touch $MOUNT/.lustre/fid/$tfile"
13256         touch $MOUNT/.lustre/fid/$tfile && \
13257                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
13258
13259         echo "setxattr to $MOUNT/.lustre/fid"
13260         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
13261
13262         echo "listxattr for $MOUNT/.lustre/fid"
13263         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
13264
13265         echo "delxattr from $MOUNT/.lustre/fid"
13266         setfattr -x trusted.name1 $MOUNT/.lustre/fid
13267
13268         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
13269         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
13270                 error "touch invalid fid should fail."
13271
13272         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
13273         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
13274                 error "touch non-normal fid should fail."
13275
13276         echo "rename $tdir to $MOUNT/.lustre/fid"
13277         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
13278                 error "rename to $MOUNT/.lustre/fid should fail."
13279
13280         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
13281         then            # LU-3547
13282                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
13283                 local new_obf_mode=777
13284
13285                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
13286                 chmod $new_obf_mode $DIR/.lustre/fid ||
13287                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
13288
13289                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
13290                 [ $obf_mode -eq $new_obf_mode ] ||
13291                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
13292
13293                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
13294                 chmod $old_obf_mode $DIR/.lustre/fid ||
13295                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
13296         fi
13297
13298         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
13299         fid=$($LFS path2fid $test_dir/$tfile-2)
13300
13301         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
13302         then # LU-5424
13303                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
13304                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
13305                         error "create lov data thru .lustre failed"
13306         fi
13307         echo "cp /etc/passwd $test_dir/$tfile-2"
13308         cp /etc/passwd $test_dir/$tfile-2 ||
13309                 error "copy to $test_dir/$tfile-2 failed."
13310         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
13311         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
13312                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
13313
13314         rm -rf $test_dir/tfile.lnk
13315         rm -rf $test_dir/$tfile-2
13316 }
13317
13318 test_154A() {
13319         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13320                 skip "Need MDS version at least 2.4.1"
13321
13322         local tf=$DIR/$tfile
13323         touch $tf
13324
13325         local fid=$($LFS path2fid $tf)
13326         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
13327
13328         # check that we get the same pathname back
13329         local found=$($LFS fid2path $MOUNT "$fid")
13330         [ -z "$found" ] && error "fid2path unable to get '$fid' path"
13331         [ "$found" == "$tf" ] ||
13332                 error "fid2path($fid=path2fid($tf)) = $found != $tf"
13333 }
13334 run_test 154A "lfs path2fid and fid2path basic checks"
13335
13336 test_154B() {
13337         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13338                 skip "Need MDS version at least 2.4.1"
13339
13340         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
13341         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
13342         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
13343         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
13344
13345         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
13346         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
13347
13348         # check that we get the same pathname
13349         echo "PFID: $PFID, name: $name"
13350         local FOUND=$($LFS fid2path $MOUNT "$PFID")
13351         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
13352         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
13353                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
13354
13355         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
13356 }
13357 run_test 154B "verify the ll_decode_linkea tool"
13358
13359 test_154a() {
13360         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13361         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13362         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
13363                 skip "Need MDS version at least 2.2.51"
13364         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13365
13366         cp /etc/hosts $DIR/$tfile
13367
13368         fid=$($LFS path2fid $DIR/$tfile)
13369         rc=$?
13370         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
13371
13372         dot_lustre_fid_permission_check "$fid" $DIR ||
13373                 error "dot lustre permission check $fid failed"
13374
13375         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
13376
13377         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
13378
13379         touch $MOUNT/.lustre/file &&
13380                 error "creation is not allowed under .lustre"
13381
13382         mkdir $MOUNT/.lustre/dir &&
13383                 error "mkdir is not allowed under .lustre"
13384
13385         rm -rf $DIR/$tfile
13386 }
13387 run_test 154a "Open-by-FID"
13388
13389 test_154b() {
13390         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13391         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13392         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13393         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
13394                 skip "Need MDS version at least 2.2.51"
13395
13396         local remote_dir=$DIR/$tdir/remote_dir
13397         local MDTIDX=1
13398         local rc=0
13399
13400         mkdir -p $DIR/$tdir
13401         $LFS mkdir -i $MDTIDX $remote_dir ||
13402                 error "create remote directory failed"
13403
13404         cp /etc/hosts $remote_dir/$tfile
13405
13406         fid=$($LFS path2fid $remote_dir/$tfile)
13407         rc=$?
13408         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
13409
13410         dot_lustre_fid_permission_check "$fid" $remote_dir ||
13411                 error "dot lustre permission check $fid failed"
13412         rm -rf $DIR/$tdir
13413 }
13414 run_test 154b "Open-by-FID for remote directory"
13415
13416 test_154c() {
13417         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13418                 skip "Need MDS version at least 2.4.1"
13419
13420         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
13421         local FID1=$($LFS path2fid $DIR/$tfile.1)
13422         local FID2=$($LFS path2fid $DIR/$tfile.2)
13423         local FID3=$($LFS path2fid $DIR/$tfile.3)
13424
13425         local N=1
13426         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
13427                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
13428                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
13429                 local want=FID$N
13430                 [ "$FID" = "${!want}" ] ||
13431                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
13432                 N=$((N + 1))
13433         done
13434
13435         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
13436         do
13437                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
13438                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
13439                 N=$((N + 1))
13440         done
13441 }
13442 run_test 154c "lfs path2fid and fid2path multiple arguments"
13443
13444 test_154d() {
13445         remote_mds_nodsh && skip "remote MDS with nodsh"
13446         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
13447                 skip "Need MDS version at least 2.5.53"
13448
13449         if remote_mds; then
13450                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
13451         else
13452                 nid="0@lo"
13453         fi
13454         local proc_ofile="mdt.*.exports.'$nid'.open_files"
13455         local fd
13456         local cmd
13457
13458         rm -f $DIR/$tfile
13459         touch $DIR/$tfile
13460
13461         local fid=$($LFS path2fid $DIR/$tfile)
13462         # Open the file
13463         fd=$(free_fd)
13464         cmd="exec $fd<$DIR/$tfile"
13465         eval $cmd
13466         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
13467         echo "$fid_list" | grep "$fid"
13468         rc=$?
13469
13470         cmd="exec $fd>/dev/null"
13471         eval $cmd
13472         if [ $rc -ne 0 ]; then
13473                 error "FID $fid not found in open files list $fid_list"
13474         fi
13475 }
13476 run_test 154d "Verify open file fid"
13477
13478 test_154e()
13479 {
13480         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
13481                 skip "Need MDS version at least 2.6.50"
13482
13483         if ls -a $MOUNT | grep -q '^\.lustre$'; then
13484                 error ".lustre returned by readdir"
13485         fi
13486 }
13487 run_test 154e ".lustre is not returned by readdir"
13488
13489 test_154f() {
13490         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13491
13492         # create parent directory on a single MDT to avoid cross-MDT hardlinks
13493         test_mkdir -p -c1 $DIR/$tdir/d
13494         # test dirs inherit from its stripe
13495         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
13496         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
13497         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
13498         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
13499         touch $DIR/f
13500
13501         # get fid of parents
13502         local FID0=$($LFS path2fid $DIR/$tdir/d)
13503         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
13504         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
13505         local FID3=$($LFS path2fid $DIR)
13506
13507         # check that path2fid --parents returns expected <parent_fid>/name
13508         # 1) test for a directory (single parent)
13509         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
13510         [ "$parent" == "$FID0/foo1" ] ||
13511                 error "expected parent: $FID0/foo1, got: $parent"
13512
13513         # 2) test for a file with nlink > 1 (multiple parents)
13514         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
13515         echo "$parent" | grep -F "$FID1/$tfile" ||
13516                 error "$FID1/$tfile not returned in parent list"
13517         echo "$parent" | grep -F "$FID2/link" ||
13518                 error "$FID2/link not returned in parent list"
13519
13520         # 3) get parent by fid
13521         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
13522         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13523         echo "$parent" | grep -F "$FID1/$tfile" ||
13524                 error "$FID1/$tfile not returned in parent list (by fid)"
13525         echo "$parent" | grep -F "$FID2/link" ||
13526                 error "$FID2/link not returned in parent list (by fid)"
13527
13528         # 4) test for entry in root directory
13529         parent=$($LFS path2fid --parents $DIR/f)
13530         echo "$parent" | grep -F "$FID3/f" ||
13531                 error "$FID3/f not returned in parent list"
13532
13533         # 5) test it on root directory
13534         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
13535                 error "$MOUNT should not have parents"
13536
13537         # enable xattr caching and check that linkea is correctly updated
13538         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
13539         save_lustre_params client "llite.*.xattr_cache" > $save
13540         lctl set_param llite.*.xattr_cache 1
13541
13542         # 6.1) linkea update on rename
13543         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
13544
13545         # get parents by fid
13546         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13547         # foo1 should no longer be returned in parent list
13548         echo "$parent" | grep -F "$FID1" &&
13549                 error "$FID1 should no longer be in parent list"
13550         # the new path should appear
13551         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
13552                 error "$FID2/$tfile.moved is not in parent list"
13553
13554         # 6.2) linkea update on unlink
13555         rm -f $DIR/$tdir/d/foo2/link
13556         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13557         # foo2/link should no longer be returned in parent list
13558         echo "$parent" | grep -F "$FID2/link" &&
13559                 error "$FID2/link should no longer be in parent list"
13560         true
13561
13562         rm -f $DIR/f
13563         restore_lustre_params < $save
13564         rm -f $save
13565 }
13566 run_test 154f "get parent fids by reading link ea"
13567
13568 test_154g()
13569 {
13570         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13571         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
13572            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
13573                 skip "Need MDS version at least 2.6.92"
13574
13575         mkdir -p $DIR/$tdir
13576         llapi_fid_test -d $DIR/$tdir
13577 }
13578 run_test 154g "various llapi FID tests"
13579
13580 test_155_small_load() {
13581     local temp=$TMP/$tfile
13582     local file=$DIR/$tfile
13583
13584     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
13585         error "dd of=$temp bs=6096 count=1 failed"
13586     cp $temp $file
13587     cancel_lru_locks $OSC
13588     cmp $temp $file || error "$temp $file differ"
13589
13590     $TRUNCATE $temp 6000
13591     $TRUNCATE $file 6000
13592     cmp $temp $file || error "$temp $file differ (truncate1)"
13593
13594     echo "12345" >>$temp
13595     echo "12345" >>$file
13596     cmp $temp $file || error "$temp $file differ (append1)"
13597
13598     echo "12345" >>$temp
13599     echo "12345" >>$file
13600     cmp $temp $file || error "$temp $file differ (append2)"
13601
13602     rm -f $temp $file
13603     true
13604 }
13605
13606 test_155_big_load() {
13607         remote_ost_nodsh && skip "remote OST with nodsh"
13608
13609         local temp=$TMP/$tfile
13610         local file=$DIR/$tfile
13611
13612         free_min_max
13613         local cache_size=$(do_facet ost$((MAXI+1)) \
13614                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
13615         local large_file_size=$((cache_size * 2))
13616
13617         echo "OSS cache size: $cache_size KB"
13618         echo "Large file size: $large_file_size KB"
13619
13620         [ $MAXV -le $large_file_size ] &&
13621                 skip_env "max available OST size needs > $large_file_size KB"
13622
13623         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
13624
13625         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
13626                 error "dd of=$temp bs=$large_file_size count=1k failed"
13627         cp $temp $file
13628         ls -lh $temp $file
13629         cancel_lru_locks osc
13630         cmp $temp $file || error "$temp $file differ"
13631
13632         rm -f $temp $file
13633         true
13634 }
13635
13636 save_writethrough() {
13637         local facets=$(get_facets OST)
13638
13639         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
13640 }
13641
13642 test_155a() {
13643         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13644
13645         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13646
13647         save_writethrough $p
13648
13649         set_cache read on
13650         set_cache writethrough on
13651         test_155_small_load
13652         restore_lustre_params < $p
13653         rm -f $p
13654 }
13655 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
13656
13657 test_155b() {
13658         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13659
13660         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13661
13662         save_writethrough $p
13663
13664         set_cache read on
13665         set_cache writethrough off
13666         test_155_small_load
13667         restore_lustre_params < $p
13668         rm -f $p
13669 }
13670 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
13671
13672 test_155c() {
13673         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13674
13675         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13676
13677         save_writethrough $p
13678
13679         set_cache read off
13680         set_cache writethrough on
13681         test_155_small_load
13682         restore_lustre_params < $p
13683         rm -f $p
13684 }
13685 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
13686
13687 test_155d() {
13688         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13689
13690         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13691
13692         save_writethrough $p
13693
13694         set_cache read off
13695         set_cache writethrough off
13696         test_155_small_load
13697         restore_lustre_params < $p
13698         rm -f $p
13699 }
13700 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
13701
13702 test_155e() {
13703         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13704
13705         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13706
13707         save_writethrough $p
13708
13709         set_cache read on
13710         set_cache writethrough on
13711         test_155_big_load
13712         restore_lustre_params < $p
13713         rm -f $p
13714 }
13715 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
13716
13717 test_155f() {
13718         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13719
13720         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13721
13722         save_writethrough $p
13723
13724         set_cache read on
13725         set_cache writethrough off
13726         test_155_big_load
13727         restore_lustre_params < $p
13728         rm -f $p
13729 }
13730 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
13731
13732 test_155g() {
13733         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13734
13735         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13736
13737         save_writethrough $p
13738
13739         set_cache read off
13740         set_cache writethrough on
13741         test_155_big_load
13742         restore_lustre_params < $p
13743         rm -f $p
13744 }
13745 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
13746
13747 test_155h() {
13748         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13749
13750         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13751
13752         save_writethrough $p
13753
13754         set_cache read off
13755         set_cache writethrough off
13756         test_155_big_load
13757         restore_lustre_params < $p
13758         rm -f $p
13759 }
13760 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
13761
13762 test_156() {
13763         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13764         remote_ost_nodsh && skip "remote OST with nodsh"
13765         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
13766                 skip "stats not implemented on old servers"
13767         [ "$ost1_FSTYPE" = "zfs" ] &&
13768                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
13769
13770         local CPAGES=3
13771         local BEFORE
13772         local AFTER
13773         local file="$DIR/$tfile"
13774         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13775
13776         save_writethrough $p
13777         roc_hit_init
13778
13779         log "Turn on read and write cache"
13780         set_cache read on
13781         set_cache writethrough on
13782
13783         log "Write data and read it back."
13784         log "Read should be satisfied from the cache."
13785         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
13786         BEFORE=$(roc_hit)
13787         cancel_lru_locks osc
13788         cat $file >/dev/null
13789         AFTER=$(roc_hit)
13790         if ! let "AFTER - BEFORE == CPAGES"; then
13791                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
13792         else
13793                 log "cache hits: before: $BEFORE, after: $AFTER"
13794         fi
13795
13796         log "Read again; it should be satisfied from the cache."
13797         BEFORE=$AFTER
13798         cancel_lru_locks osc
13799         cat $file >/dev/null
13800         AFTER=$(roc_hit)
13801         if ! let "AFTER - BEFORE == CPAGES"; then
13802                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
13803         else
13804                 log "cache hits:: before: $BEFORE, after: $AFTER"
13805         fi
13806
13807         log "Turn off the read cache and turn on the write cache"
13808         set_cache read off
13809         set_cache writethrough on
13810
13811         log "Read again; it should be satisfied from the cache."
13812         BEFORE=$(roc_hit)
13813         cancel_lru_locks osc
13814         cat $file >/dev/null
13815         AFTER=$(roc_hit)
13816         if ! let "AFTER - BEFORE == CPAGES"; then
13817                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
13818         else
13819                 log "cache hits:: before: $BEFORE, after: $AFTER"
13820         fi
13821
13822         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
13823                 # > 2.12.56 uses pagecache if cached
13824                 log "Read again; it should not be satisfied from the cache."
13825                 BEFORE=$AFTER
13826                 cancel_lru_locks osc
13827                 cat $file >/dev/null
13828                 AFTER=$(roc_hit)
13829                 if ! let "AFTER - BEFORE == 0"; then
13830                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
13831                 else
13832                         log "cache hits:: before: $BEFORE, after: $AFTER"
13833                 fi
13834         fi
13835
13836         log "Write data and read it back."
13837         log "Read should be satisfied from the cache."
13838         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
13839         BEFORE=$(roc_hit)
13840         cancel_lru_locks osc
13841         cat $file >/dev/null
13842         AFTER=$(roc_hit)
13843         if ! let "AFTER - BEFORE == CPAGES"; then
13844                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
13845         else
13846                 log "cache hits:: before: $BEFORE, after: $AFTER"
13847         fi
13848
13849         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
13850                 # > 2.12.56 uses pagecache if cached
13851                 log "Read again; it should not be satisfied from the cache."
13852                 BEFORE=$AFTER
13853                 cancel_lru_locks osc
13854                 cat $file >/dev/null
13855                 AFTER=$(roc_hit)
13856                 if ! let "AFTER - BEFORE == 0"; then
13857                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
13858                 else
13859                         log "cache hits:: before: $BEFORE, after: $AFTER"
13860                 fi
13861         fi
13862
13863         log "Turn off read and write cache"
13864         set_cache read off
13865         set_cache writethrough off
13866
13867         log "Write data and read it back"
13868         log "It should not be satisfied from the cache."
13869         rm -f $file
13870         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
13871         cancel_lru_locks osc
13872         BEFORE=$(roc_hit)
13873         cat $file >/dev/null
13874         AFTER=$(roc_hit)
13875         if ! let "AFTER - BEFORE == 0"; then
13876                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
13877         else
13878                 log "cache hits:: before: $BEFORE, after: $AFTER"
13879         fi
13880
13881         log "Turn on the read cache and turn off the write cache"
13882         set_cache read on
13883         set_cache writethrough off
13884
13885         log "Write data and read it back"
13886         log "It should not be satisfied from the cache."
13887         rm -f $file
13888         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
13889         BEFORE=$(roc_hit)
13890         cancel_lru_locks osc
13891         cat $file >/dev/null
13892         AFTER=$(roc_hit)
13893         if ! let "AFTER - BEFORE == 0"; then
13894                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
13895         else
13896                 log "cache hits:: before: $BEFORE, after: $AFTER"
13897         fi
13898
13899         log "Read again; it should be satisfied from the cache."
13900         BEFORE=$(roc_hit)
13901         cancel_lru_locks osc
13902         cat $file >/dev/null
13903         AFTER=$(roc_hit)
13904         if ! let "AFTER - BEFORE == CPAGES"; then
13905                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
13906         else
13907                 log "cache hits:: before: $BEFORE, after: $AFTER"
13908         fi
13909
13910         restore_lustre_params < $p
13911         rm -f $p $file
13912 }
13913 run_test 156 "Verification of tunables"
13914
13915 test_160a() {
13916         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13917         remote_mds_nodsh && skip "remote MDS with nodsh"
13918         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
13919                 skip "Need MDS version at least 2.2.0"
13920
13921         changelog_register || error "changelog_register failed"
13922         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
13923         changelog_users $SINGLEMDS | grep -q $cl_user ||
13924                 error "User $cl_user not found in changelog_users"
13925
13926         # change something
13927         test_mkdir -p $DIR/$tdir/pics/2008/zachy
13928         changelog_clear 0 || error "changelog_clear failed"
13929         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
13930         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
13931         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
13932         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
13933         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
13934         rm $DIR/$tdir/pics/desktop.jpg
13935
13936         changelog_dump | tail -10
13937
13938         echo "verifying changelog mask"
13939         changelog_chmask "-MKDIR"
13940         changelog_chmask "-CLOSE"
13941
13942         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
13943         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
13944
13945         changelog_chmask "+MKDIR"
13946         changelog_chmask "+CLOSE"
13947
13948         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
13949         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
13950
13951         changelog_dump | tail -10
13952         MKDIRS=$(changelog_dump | grep -c "MKDIR")
13953         CLOSES=$(changelog_dump | grep -c "CLOSE")
13954         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
13955         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
13956
13957         # verify contents
13958         echo "verifying target fid"
13959         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
13960         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
13961         [ "$fidc" == "$fidf" ] ||
13962                 error "changelog '$tfile' fid $fidc != file fid $fidf"
13963         echo "verifying parent fid"
13964         # The FID returned from the Changelog may be the directory shard on
13965         # a different MDT, and not the FID returned by path2fid on the parent.
13966         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
13967         # since this is what will matter when recreating this file in the tree.
13968         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
13969         local pathp=$($LFS fid2path $MOUNT "$fidp")
13970         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
13971                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
13972
13973         echo "getting records for $cl_user"
13974         changelog_users $SINGLEMDS
13975         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
13976         local nclr=3
13977         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
13978                 error "changelog_clear failed"
13979         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
13980         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
13981         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
13982                 error "user index expect $user_rec1 + $nclr != $user_rec2"
13983
13984         local min0_rec=$(changelog_users $SINGLEMDS |
13985                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
13986         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
13987                           awk '{ print $1; exit; }')
13988
13989         changelog_dump | tail -n 5
13990         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
13991         [ $first_rec == $((min0_rec + 1)) ] ||
13992                 error "first index should be $min0_rec + 1 not $first_rec"
13993
13994         # LU-3446 changelog index reset on MDT restart
13995         local cur_rec1=$(changelog_users $SINGLEMDS |
13996                          awk '/^current.index:/ { print $NF }')
13997         changelog_clear 0 ||
13998                 error "clear all changelog records for $cl_user failed"
13999         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
14000         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
14001                 error "Fail to start $SINGLEMDS"
14002         local cur_rec2=$(changelog_users $SINGLEMDS |
14003                          awk '/^current.index:/ { print $NF }')
14004         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
14005         [ $cur_rec1 == $cur_rec2 ] ||
14006                 error "current index should be $cur_rec1 not $cur_rec2"
14007
14008         echo "verifying users from this test are deregistered"
14009         changelog_deregister || error "changelog_deregister failed"
14010         changelog_users $SINGLEMDS | grep -q $cl_user &&
14011                 error "User '$cl_user' still in changelog_users"
14012
14013         # lctl get_param -n mdd.*.changelog_users
14014         # current index: 144
14015         # ID    index (idle seconds)
14016         # cl3   144 (2)
14017         if ! changelog_users $SINGLEMDS | grep "^cl"; then
14018                 # this is the normal case where all users were deregistered
14019                 # make sure no new records are added when no users are present
14020                 local last_rec1=$(changelog_users $SINGLEMDS |
14021                                   awk '/^current.index:/ { print $NF }')
14022                 touch $DIR/$tdir/chloe
14023                 local last_rec2=$(changelog_users $SINGLEMDS |
14024                                   awk '/^current.index:/ { print $NF }')
14025                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
14026                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
14027         else
14028                 # any changelog users must be leftovers from a previous test
14029                 changelog_users $SINGLEMDS
14030                 echo "other changelog users; can't verify off"
14031         fi
14032 }
14033 run_test 160a "changelog sanity"
14034
14035 test_160b() { # LU-3587
14036         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14037         remote_mds_nodsh && skip "remote MDS with nodsh"
14038         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14039                 skip "Need MDS version at least 2.2.0"
14040
14041         changelog_register || error "changelog_register failed"
14042         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14043         changelog_users $SINGLEMDS | grep -q $cl_user ||
14044                 error "User '$cl_user' not found in changelog_users"
14045
14046         local longname1=$(str_repeat a 255)
14047         local longname2=$(str_repeat b 255)
14048
14049         cd $DIR
14050         echo "creating very long named file"
14051         touch $longname1 || error "create of '$longname1' failed"
14052         echo "renaming very long named file"
14053         mv $longname1 $longname2
14054
14055         changelog_dump | grep RENME | tail -n 5
14056         rm -f $longname2
14057 }
14058 run_test 160b "Verify that very long rename doesn't crash in changelog"
14059
14060 test_160c() {
14061         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14062         remote_mds_nodsh && skip "remote MDS with nodsh"
14063
14064         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
14065                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
14066                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
14067                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
14068
14069         local rc=0
14070
14071         # Registration step
14072         changelog_register || error "changelog_register failed"
14073
14074         rm -rf $DIR/$tdir
14075         mkdir -p $DIR/$tdir
14076         $MCREATE $DIR/$tdir/foo_160c
14077         changelog_chmask "-TRUNC"
14078         $TRUNCATE $DIR/$tdir/foo_160c 200
14079         changelog_chmask "+TRUNC"
14080         $TRUNCATE $DIR/$tdir/foo_160c 199
14081         changelog_dump | tail -n 5
14082         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
14083         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
14084 }
14085 run_test 160c "verify that changelog log catch the truncate event"
14086
14087 test_160d() {
14088         remote_mds_nodsh && skip "remote MDS with nodsh"
14089         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14090         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14091         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
14092                 skip "Need MDS version at least 2.7.60"
14093
14094         # Registration step
14095         changelog_register || error "changelog_register failed"
14096
14097         mkdir -p $DIR/$tdir/migrate_dir
14098         changelog_clear 0 || error "changelog_clear failed"
14099
14100         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
14101         changelog_dump | tail -n 5
14102         local migrates=$(changelog_dump | grep -c "MIGRT")
14103         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
14104 }
14105 run_test 160d "verify that changelog log catch the migrate event"
14106
14107 test_160e() {
14108         remote_mds_nodsh && skip "remote MDS with nodsh"
14109
14110         # Create a user
14111         changelog_register || error "changelog_register failed"
14112
14113         # Delete a future user (expect fail)
14114         local MDT0=$(facet_svc $SINGLEMDS)
14115         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
14116         local rc=$?
14117
14118         if [ $rc -eq 0 ]; then
14119                 error "Deleted non-existant user cl77"
14120         elif [ $rc -ne 2 ]; then
14121                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
14122         fi
14123
14124         # Clear to a bad index (1 billion should be safe)
14125         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
14126         rc=$?
14127
14128         if [ $rc -eq 0 ]; then
14129                 error "Successfully cleared to invalid CL index"
14130         elif [ $rc -ne 22 ]; then
14131                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
14132         fi
14133 }
14134 run_test 160e "changelog negative testing (should return errors)"
14135
14136 test_160f() {
14137         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14138         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14139                 skip "Need MDS version at least 2.10.56"
14140
14141         local mdts=$(comma_list $(mdts_nodes))
14142
14143         # Create a user
14144         changelog_register || error "first changelog_register failed"
14145         changelog_register || error "second changelog_register failed"
14146         local cl_users
14147         declare -A cl_user1
14148         declare -A cl_user2
14149         local user_rec1
14150         local user_rec2
14151         local i
14152
14153         # generate some changelog records to accumulate on each MDT
14154         # use fnv1a because created files should be evenly distributed
14155         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14156                 error "test_mkdir $tdir failed"
14157         log "$(date +%s): creating first files"
14158         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14159                 error "create $DIR/$tdir/$tfile failed"
14160
14161         # check changelogs have been generated
14162         local start=$SECONDS
14163         local idle_time=$((MDSCOUNT * 5 + 5))
14164         local nbcl=$(changelog_dump | wc -l)
14165         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14166
14167         for param in "changelog_max_idle_time=$idle_time" \
14168                      "changelog_gc=1" \
14169                      "changelog_min_gc_interval=2" \
14170                      "changelog_min_free_cat_entries=3"; do
14171                 local MDT0=$(facet_svc $SINGLEMDS)
14172                 local var="${param%=*}"
14173                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14174
14175                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14176                 do_nodes $mdts $LCTL set_param mdd.*.$param
14177         done
14178
14179         # force cl_user2 to be idle (1st part), but also cancel the
14180         # cl_user1 records so that it is not evicted later in the test.
14181         local sleep1=$((idle_time / 2))
14182         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
14183         sleep $sleep1
14184
14185         # simulate changelog catalog almost full
14186         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
14187         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
14188
14189         for i in $(seq $MDSCOUNT); do
14190                 cl_users=(${CL_USERS[mds$i]})
14191                 cl_user1[mds$i]="${cl_users[0]}"
14192                 cl_user2[mds$i]="${cl_users[1]}"
14193
14194                 [ -n "${cl_user1[mds$i]}" ] ||
14195                         error "mds$i: no user registered"
14196                 [ -n "${cl_user2[mds$i]}" ] ||
14197                         error "mds$i: only ${cl_user2[mds$i]} is registered"
14198
14199                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14200                 [ -n "$user_rec1" ] ||
14201                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14202                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14203                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14204                 [ -n "$user_rec2" ] ||
14205                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14206                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14207                      "$user_rec1 + 2 == $user_rec2"
14208                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14209                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14210                               "$user_rec1 + 2, but is $user_rec2"
14211                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14212                 [ -n "$user_rec2" ] ||
14213                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14214                 [ $user_rec1 == $user_rec2 ] ||
14215                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14216                               "$user_rec1, but is $user_rec2"
14217         done
14218
14219         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
14220         local sleep2=$((idle_time - (SECONDS - start) + 1))
14221         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
14222         sleep $sleep2
14223
14224         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
14225         # cl_user1 should be OK because it recently processed records.
14226         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
14227         createmany -m $DIR/$tdir/${tfile}b $((MDSCOUNT * 2)) ||
14228                 error "create $DIR/$tdir/${tfile}b failed"
14229
14230         # ensure gc thread is done
14231         for i in $(mdts_nodes); do
14232                 wait_update $i \
14233                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
14234                         error "$i: GC-thread not done"
14235         done
14236
14237         local first_rec
14238         for i in $(seq $MDSCOUNT); do
14239                 # check cl_user1 still registered
14240                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14241                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14242                 # check cl_user2 unregistered
14243                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14244                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14245
14246                 # check changelogs are present and starting at $user_rec1 + 1
14247                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14248                 [ -n "$user_rec1" ] ||
14249                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14250                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14251                             awk '{ print $1; exit; }')
14252
14253                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14254                 [ $((user_rec1 + 1)) == $first_rec ] ||
14255                         error "mds$i: first index should be $user_rec1 + 1, " \
14256                               "but is $first_rec"
14257         done
14258 }
14259 run_test 160f "changelog garbage collect (timestamped users)"
14260
14261 test_160g() {
14262         remote_mds_nodsh && skip "remote MDS with nodsh"
14263         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14264                 skip "Need MDS version at least 2.10.56"
14265
14266         local mdts=$(comma_list $(mdts_nodes))
14267
14268         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
14269         do_nodes $mdts $LCTL set_param fail_loc=0x1314
14270
14271         # Create a user
14272         changelog_register || error "first changelog_register failed"
14273         changelog_register || error "second changelog_register failed"
14274         local cl_users
14275         declare -A cl_user1
14276         declare -A cl_user2
14277         local user_rec1
14278         local user_rec2
14279         local i
14280
14281         # generate some changelog records to accumulate on each MDT
14282         # use fnv1a because created files should be evenly distributed
14283         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14284                 error "mkdir $tdir failed"
14285         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14286                 error "create $DIR/$tdir/$tfile failed"
14287
14288         # check changelogs have been generated
14289         local nbcl=$(changelog_dump | wc -l)
14290         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14291
14292         # reduce the max_idle_indexes value to make sure we exceed it
14293         max_ndx=$((nbcl / 2 - 1))
14294
14295         for param in "changelog_max_idle_indexes=$max_ndx" \
14296                      "changelog_gc=1" \
14297                      "changelog_min_gc_interval=2" \
14298                      "changelog_min_free_cat_entries=3"; do
14299                 local MDT0=$(facet_svc $SINGLEMDS)
14300                 local var="${param%=*}"
14301                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14302
14303                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14304                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
14305                         error "unable to set mdd.*.$param"
14306         done
14307
14308         # simulate changelog catalog almost full
14309         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
14310         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
14311
14312         for i in $(seq $MDSCOUNT); do
14313                 cl_users=(${CL_USERS[mds$i]})
14314                 cl_user1[mds$i]="${cl_users[0]}"
14315                 cl_user2[mds$i]="${cl_users[1]}"
14316
14317                 [ -n "${cl_user1[mds$i]}" ] ||
14318                         error "mds$i: no user registered"
14319                 [ -n "${cl_user2[mds$i]}" ] ||
14320                         error "mds$i: only ${cl_user1[mds$i]} is registered"
14321
14322                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14323                 [ -n "$user_rec1" ] ||
14324                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14325                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14326                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14327                 [ -n "$user_rec2" ] ||
14328                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14329                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14330                      "$user_rec1 + 2 == $user_rec2"
14331                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14332                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14333                               "$user_rec1 + 2, but is $user_rec2"
14334                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14335                 [ -n "$user_rec2" ] ||
14336                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14337                 [ $user_rec1 == $user_rec2 ] ||
14338                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14339                               "$user_rec1, but is $user_rec2"
14340         done
14341
14342         # ensure we are past the previous changelog_min_gc_interval set above
14343         sleep 2
14344
14345         # generate one more changelog to trigger fail_loc
14346         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14347                 error "create $DIR/$tdir/${tfile}bis failed"
14348
14349         # ensure gc thread is done
14350         for i in $(mdts_nodes); do
14351                 wait_update $i \
14352                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
14353                         error "$i: GC-thread not done"
14354         done
14355
14356         local first_rec
14357         for i in $(seq $MDSCOUNT); do
14358                 # check cl_user1 still registered
14359                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14360                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14361                 # check cl_user2 unregistered
14362                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14363                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14364
14365                 # check changelogs are present and starting at $user_rec1 + 1
14366                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14367                 [ -n "$user_rec1" ] ||
14368                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14369                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14370                             awk '{ print $1; exit; }')
14371
14372                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14373                 [ $((user_rec1 + 1)) == $first_rec ] ||
14374                         error "mds$i: first index should be $user_rec1 + 1, " \
14375                               "but is $first_rec"
14376         done
14377 }
14378 run_test 160g "changelog garbage collect (old users)"
14379
14380 test_160h() {
14381         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14382         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14383                 skip "Need MDS version at least 2.10.56"
14384
14385         local mdts=$(comma_list $(mdts_nodes))
14386
14387         # Create a user
14388         changelog_register || error "first changelog_register failed"
14389         changelog_register || error "second changelog_register failed"
14390         local cl_users
14391         declare -A cl_user1
14392         declare -A cl_user2
14393         local user_rec1
14394         local user_rec2
14395         local i
14396
14397         # generate some changelog records to accumulate on each MDT
14398         # use fnv1a because created files should be evenly distributed
14399         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14400                 error "test_mkdir $tdir failed"
14401         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14402                 error "create $DIR/$tdir/$tfile failed"
14403
14404         # check changelogs have been generated
14405         local nbcl=$(changelog_dump | wc -l)
14406         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14407
14408         for param in "changelog_max_idle_time=10" \
14409                      "changelog_gc=1" \
14410                      "changelog_min_gc_interval=2"; do
14411                 local MDT0=$(facet_svc $SINGLEMDS)
14412                 local var="${param%=*}"
14413                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14414
14415                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14416                 do_nodes $mdts $LCTL set_param mdd.*.$param
14417         done
14418
14419         # force cl_user2 to be idle (1st part)
14420         sleep 9
14421
14422         for i in $(seq $MDSCOUNT); do
14423                 cl_users=(${CL_USERS[mds$i]})
14424                 cl_user1[mds$i]="${cl_users[0]}"
14425                 cl_user2[mds$i]="${cl_users[1]}"
14426
14427                 [ -n "${cl_user1[mds$i]}" ] ||
14428                         error "mds$i: no user registered"
14429                 [ -n "${cl_user2[mds$i]}" ] ||
14430                         error "mds$i: only ${cl_user2[mds$i]} is registered"
14431
14432                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14433                 [ -n "$user_rec1" ] ||
14434                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14435                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14436                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14437                 [ -n "$user_rec2" ] ||
14438                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14439                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14440                      "$user_rec1 + 2 == $user_rec2"
14441                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14442                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14443                               "$user_rec1 + 2, but is $user_rec2"
14444                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14445                 [ -n "$user_rec2" ] ||
14446                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14447                 [ $user_rec1 == $user_rec2 ] ||
14448                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14449                               "$user_rec1, but is $user_rec2"
14450         done
14451
14452         # force cl_user2 to be idle (2nd part) and to reach
14453         # changelog_max_idle_time
14454         sleep 2
14455
14456         # force each GC-thread start and block then
14457         # one per MDT/MDD, set fail_val accordingly
14458         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
14459         do_nodes $mdts $LCTL set_param fail_loc=0x1316
14460
14461         # generate more changelogs to trigger fail_loc
14462         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14463                 error "create $DIR/$tdir/${tfile}bis failed"
14464
14465         # stop MDT to stop GC-thread, should be done in back-ground as it will
14466         # block waiting for the thread to be released and exit
14467         declare -A stop_pids
14468         for i in $(seq $MDSCOUNT); do
14469                 stop mds$i &
14470                 stop_pids[mds$i]=$!
14471         done
14472
14473         for i in $(mdts_nodes); do
14474                 local facet
14475                 local nb=0
14476                 local facets=$(facets_up_on_host $i)
14477
14478                 for facet in ${facets//,/ }; do
14479                         if [[ $facet == mds* ]]; then
14480                                 nb=$((nb + 1))
14481                         fi
14482                 done
14483                 # ensure each MDS's gc threads are still present and all in "R"
14484                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
14485                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
14486                         error "$i: expected $nb GC-thread"
14487                 wait_update $i \
14488                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
14489                         "R" 20 ||
14490                         error "$i: GC-thread not found in R-state"
14491                 # check umounts of each MDT on MDS have reached kthread_stop()
14492                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
14493                         error "$i: expected $nb umount"
14494                 wait_update $i \
14495                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
14496                         error "$i: umount not found in D-state"
14497         done
14498
14499         # release all GC-threads
14500         do_nodes $mdts $LCTL set_param fail_loc=0
14501
14502         # wait for MDT stop to complete
14503         for i in $(seq $MDSCOUNT); do
14504                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
14505         done
14506
14507         # XXX
14508         # may try to check if any orphan changelog records are present
14509         # via ldiskfs/zfs and llog_reader...
14510
14511         # re-start/mount MDTs
14512         for i in $(seq $MDSCOUNT); do
14513                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
14514                         error "Fail to start mds$i"
14515         done
14516
14517         local first_rec
14518         for i in $(seq $MDSCOUNT); do
14519                 # check cl_user1 still registered
14520                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14521                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14522                 # check cl_user2 unregistered
14523                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14524                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14525
14526                 # check changelogs are present and starting at $user_rec1 + 1
14527                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14528                 [ -n "$user_rec1" ] ||
14529                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14530                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14531                             awk '{ print $1; exit; }')
14532
14533                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14534                 [ $((user_rec1 + 1)) == $first_rec ] ||
14535                         error "mds$i: first index should be $user_rec1 + 1, " \
14536                               "but is $first_rec"
14537         done
14538 }
14539 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
14540               "during mount"
14541
14542 test_160i() {
14543
14544         local mdts=$(comma_list $(mdts_nodes))
14545
14546         changelog_register || error "first changelog_register failed"
14547
14548         # generate some changelog records to accumulate on each MDT
14549         # use fnv1a because created files should be evenly distributed
14550         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14551                 error "mkdir $tdir failed"
14552         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14553                 error "create $DIR/$tdir/$tfile failed"
14554
14555         # check changelogs have been generated
14556         local nbcl=$(changelog_dump | wc -l)
14557         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14558
14559         # simulate race between register and unregister
14560         # XXX as fail_loc is set per-MDS, with DNE configs the race
14561         # simulation will only occur for one MDT per MDS and for the
14562         # others the normal race scenario will take place
14563         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
14564         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
14565         do_nodes $mdts $LCTL set_param fail_val=1
14566
14567         # unregister 1st user
14568         changelog_deregister &
14569         local pid1=$!
14570         # wait some time for deregister work to reach race rdv
14571         sleep 2
14572         # register 2nd user
14573         changelog_register || error "2nd user register failed"
14574
14575         wait $pid1 || error "1st user deregister failed"
14576
14577         local i
14578         local last_rec
14579         declare -A LAST_REC
14580         for i in $(seq $MDSCOUNT); do
14581                 if changelog_users mds$i | grep "^cl"; then
14582                         # make sure new records are added with one user present
14583                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
14584                                           awk '/^current.index:/ { print $NF }')
14585                 else
14586                         error "mds$i has no user registered"
14587                 fi
14588         done
14589
14590         # generate more changelog records to accumulate on each MDT
14591         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14592                 error "create $DIR/$tdir/${tfile}bis failed"
14593
14594         for i in $(seq $MDSCOUNT); do
14595                 last_rec=$(changelog_users $SINGLEMDS |
14596                            awk '/^current.index:/ { print $NF }')
14597                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
14598                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
14599                         error "changelogs are off on mds$i"
14600         done
14601 }
14602 run_test 160i "changelog user register/unregister race"
14603
14604 test_160j() {
14605         remote_mds_nodsh && skip "remote MDS with nodsh"
14606         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
14607                 skip "Need MDS version at least 2.12.56"
14608
14609         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
14610         stack_trap "umount $MOUNT2" EXIT
14611
14612         changelog_register || error "first changelog_register failed"
14613         stack_trap "changelog_deregister" EXIT
14614
14615         # generate some changelog
14616         # use fnv1a because created files should be evenly distributed
14617         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14618                 error "mkdir $tdir failed"
14619         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14620                 error "create $DIR/$tdir/${tfile}bis failed"
14621
14622         # open the changelog device
14623         exec 3>/dev/changelog-$FSNAME-MDT0000
14624         stack_trap "exec 3>&-" EXIT
14625         exec 4</dev/changelog-$FSNAME-MDT0000
14626         stack_trap "exec 4<&-" EXIT
14627
14628         # umount the first lustre mount
14629         umount $MOUNT
14630         stack_trap "mount_client $MOUNT" EXIT
14631
14632         # read changelog
14633         cat <&4 >/dev/null || error "read changelog failed"
14634
14635         # clear changelog
14636         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14637         changelog_users $SINGLEMDS | grep -q $cl_user ||
14638                 error "User $cl_user not found in changelog_users"
14639
14640         printf 'clear:'$cl_user':0' >&3
14641 }
14642 run_test 160j "client can be umounted  while its chanangelog is being used"
14643
14644 test_160k() {
14645         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14646         remote_mds_nodsh && skip "remote MDS with nodsh"
14647
14648         mkdir -p $DIR/$tdir/1/1
14649
14650         changelog_register || error "changelog_register failed"
14651         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14652
14653         changelog_users $SINGLEMDS | grep -q $cl_user ||
14654                 error "User '$cl_user' not found in changelog_users"
14655 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
14656         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
14657         rmdir $DIR/$tdir/1/1 & sleep 1
14658         mkdir $DIR/$tdir/2
14659         touch $DIR/$tdir/2/2
14660         rm -rf $DIR/$tdir/2
14661
14662         wait
14663         sleep 4
14664
14665         changelog_dump | grep rmdir || error "rmdir not recorded"
14666
14667         rm -rf $DIR/$tdir
14668         changelog_deregister
14669 }
14670 run_test 160k "Verify that changelog records are not lost"
14671
14672 test_161a() {
14673         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14674
14675         test_mkdir -c1 $DIR/$tdir
14676         cp /etc/hosts $DIR/$tdir/$tfile
14677         test_mkdir -c1 $DIR/$tdir/foo1
14678         test_mkdir -c1 $DIR/$tdir/foo2
14679         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
14680         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
14681         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
14682         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
14683         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
14684         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
14685                 $LFS fid2path $DIR $FID
14686                 error "bad link ea"
14687         fi
14688         # middle
14689         rm $DIR/$tdir/foo2/zachary
14690         # last
14691         rm $DIR/$tdir/foo2/thor
14692         # first
14693         rm $DIR/$tdir/$tfile
14694         # rename
14695         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
14696         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
14697                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
14698         rm $DIR/$tdir/foo2/maggie
14699
14700         # overflow the EA
14701         local longname=$tfile.avg_len_is_thirty_two_
14702         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
14703                 error_noexit 'failed to unlink many hardlinks'" EXIT
14704         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
14705                 error "failed to hardlink many files"
14706         links=$($LFS fid2path $DIR $FID | wc -l)
14707         echo -n "${links}/1000 links in link EA"
14708         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
14709 }
14710 run_test 161a "link ea sanity"
14711
14712 test_161b() {
14713         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14714         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
14715
14716         local MDTIDX=1
14717         local remote_dir=$DIR/$tdir/remote_dir
14718
14719         mkdir -p $DIR/$tdir
14720         $LFS mkdir -i $MDTIDX $remote_dir ||
14721                 error "create remote directory failed"
14722
14723         cp /etc/hosts $remote_dir/$tfile
14724         mkdir -p $remote_dir/foo1
14725         mkdir -p $remote_dir/foo2
14726         ln $remote_dir/$tfile $remote_dir/foo1/sofia
14727         ln $remote_dir/$tfile $remote_dir/foo2/zachary
14728         ln $remote_dir/$tfile $remote_dir/foo1/luna
14729         ln $remote_dir/$tfile $remote_dir/foo2/thor
14730
14731         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
14732                      tr -d ']')
14733         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
14734                 $LFS fid2path $DIR $FID
14735                 error "bad link ea"
14736         fi
14737         # middle
14738         rm $remote_dir/foo2/zachary
14739         # last
14740         rm $remote_dir/foo2/thor
14741         # first
14742         rm $remote_dir/$tfile
14743         # rename
14744         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
14745         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
14746         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
14747                 $LFS fid2path $DIR $FID
14748                 error "bad link rename"
14749         fi
14750         rm $remote_dir/foo2/maggie
14751
14752         # overflow the EA
14753         local longname=filename_avg_len_is_thirty_two_
14754         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
14755                 error "failed to hardlink many files"
14756         links=$($LFS fid2path $DIR $FID | wc -l)
14757         echo -n "${links}/1000 links in link EA"
14758         [[ ${links} -gt 60 ]] ||
14759                 error "expected at least 60 links in link EA"
14760         unlinkmany $remote_dir/foo2/$longname 1000 ||
14761         error "failed to unlink many hardlinks"
14762 }
14763 run_test 161b "link ea sanity under remote directory"
14764
14765 test_161c() {
14766         remote_mds_nodsh && skip "remote MDS with nodsh"
14767         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14768         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
14769                 skip "Need MDS version at least 2.1.5"
14770
14771         # define CLF_RENAME_LAST 0x0001
14772         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
14773         changelog_register || error "changelog_register failed"
14774
14775         rm -rf $DIR/$tdir
14776         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
14777         touch $DIR/$tdir/foo_161c
14778         touch $DIR/$tdir/bar_161c
14779         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
14780         changelog_dump | grep RENME | tail -n 5
14781         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
14782         changelog_clear 0 || error "changelog_clear failed"
14783         if [ x$flags != "x0x1" ]; then
14784                 error "flag $flags is not 0x1"
14785         fi
14786
14787         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
14788         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
14789         touch $DIR/$tdir/foo_161c
14790         touch $DIR/$tdir/bar_161c
14791         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
14792         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
14793         changelog_dump | grep RENME | tail -n 5
14794         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
14795         changelog_clear 0 || error "changelog_clear failed"
14796         if [ x$flags != "x0x0" ]; then
14797                 error "flag $flags is not 0x0"
14798         fi
14799         echo "rename overwrite a target having nlink > 1," \
14800                 "changelog record has flags of $flags"
14801
14802         # rename doesn't overwrite a target (changelog flag 0x0)
14803         touch $DIR/$tdir/foo_161c
14804         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
14805         changelog_dump | grep RENME | tail -n 5
14806         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
14807         changelog_clear 0 || error "changelog_clear failed"
14808         if [ x$flags != "x0x0" ]; then
14809                 error "flag $flags is not 0x0"
14810         fi
14811         echo "rename doesn't overwrite a target," \
14812                 "changelog record has flags of $flags"
14813
14814         # define CLF_UNLINK_LAST 0x0001
14815         # unlink a file having nlink = 1 (changelog flag 0x1)
14816         rm -f $DIR/$tdir/foo2_161c
14817         changelog_dump | grep UNLNK | tail -n 5
14818         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
14819         changelog_clear 0 || error "changelog_clear failed"
14820         if [ x$flags != "x0x1" ]; then
14821                 error "flag $flags is not 0x1"
14822         fi
14823         echo "unlink a file having nlink = 1," \
14824                 "changelog record has flags of $flags"
14825
14826         # unlink a file having nlink > 1 (changelog flag 0x0)
14827         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
14828         rm -f $DIR/$tdir/foobar_161c
14829         changelog_dump | grep UNLNK | tail -n 5
14830         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
14831         changelog_clear 0 || error "changelog_clear failed"
14832         if [ x$flags != "x0x0" ]; then
14833                 error "flag $flags is not 0x0"
14834         fi
14835         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
14836 }
14837 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
14838
14839 test_161d() {
14840         remote_mds_nodsh && skip "remote MDS with nodsh"
14841         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
14842
14843         local pid
14844         local fid
14845
14846         changelog_register || error "changelog_register failed"
14847
14848         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
14849         # interfer with $MOUNT/.lustre/fid/ access
14850         mkdir $DIR/$tdir
14851         [[ $? -eq 0 ]] || error "mkdir failed"
14852
14853         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
14854         $LCTL set_param fail_loc=0x8000140c
14855         # 5s pause
14856         $LCTL set_param fail_val=5
14857
14858         # create file
14859         echo foofoo > $DIR/$tdir/$tfile &
14860         pid=$!
14861
14862         # wait for create to be delayed
14863         sleep 2
14864
14865         ps -p $pid
14866         [[ $? -eq 0 ]] || error "create should be blocked"
14867
14868         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
14869         stack_trap "rm -f $tempfile"
14870         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
14871         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
14872         # some delay may occur during ChangeLog publishing and file read just
14873         # above, that could allow file write to happen finally
14874         [[ -s $tempfile ]] && echo "file should be empty"
14875
14876         $LCTL set_param fail_loc=0
14877
14878         wait $pid
14879         [[ $? -eq 0 ]] || error "create failed"
14880 }
14881 run_test 161d "create with concurrent .lustre/fid access"
14882
14883 check_path() {
14884         local expected="$1"
14885         shift
14886         local fid="$2"
14887
14888         local path
14889         path=$($LFS fid2path "$@")
14890         local rc=$?
14891
14892         if [ $rc -ne 0 ]; then
14893                 error "path looked up of '$expected' failed: rc=$rc"
14894         elif [ "$path" != "$expected" ]; then
14895                 error "path looked up '$path' instead of '$expected'"
14896         else
14897                 echo "FID '$fid' resolves to path '$path' as expected"
14898         fi
14899 }
14900
14901 test_162a() { # was test_162
14902         test_mkdir -p -c1 $DIR/$tdir/d2
14903         touch $DIR/$tdir/d2/$tfile
14904         touch $DIR/$tdir/d2/x1
14905         touch $DIR/$tdir/d2/x2
14906         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
14907         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
14908         # regular file
14909         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
14910         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
14911
14912         # softlink
14913         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
14914         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
14915         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
14916
14917         # softlink to wrong file
14918         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
14919         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
14920         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
14921
14922         # hardlink
14923         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
14924         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
14925         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
14926         # fid2path dir/fsname should both work
14927         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
14928         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
14929
14930         # hardlink count: check that there are 2 links
14931         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
14932         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
14933
14934         # hardlink indexing: remove the first link
14935         rm $DIR/$tdir/d2/p/q/r/hlink
14936         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
14937 }
14938 run_test 162a "path lookup sanity"
14939
14940 test_162b() {
14941         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14942         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14943
14944         mkdir $DIR/$tdir
14945         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
14946                                 error "create striped dir failed"
14947
14948         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
14949                                         tail -n 1 | awk '{print $2}')
14950         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
14951
14952         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
14953         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
14954
14955         # regular file
14956         for ((i=0;i<5;i++)); do
14957                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
14958                         error "get fid for f$i failed"
14959                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
14960
14961                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
14962                         error "get fid for d$i failed"
14963                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
14964         done
14965
14966         return 0
14967 }
14968 run_test 162b "striped directory path lookup sanity"
14969
14970 # LU-4239: Verify fid2path works with paths 100 or more directories deep
14971 test_162c() {
14972         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
14973                 skip "Need MDS version at least 2.7.51"
14974
14975         local lpath=$tdir.local
14976         local rpath=$tdir.remote
14977
14978         test_mkdir $DIR/$lpath
14979         test_mkdir $DIR/$rpath
14980
14981         for ((i = 0; i <= 101; i++)); do
14982                 lpath="$lpath/$i"
14983                 mkdir $DIR/$lpath
14984                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
14985                         error "get fid for local directory $DIR/$lpath failed"
14986                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
14987
14988                 rpath="$rpath/$i"
14989                 test_mkdir $DIR/$rpath
14990                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
14991                         error "get fid for remote directory $DIR/$rpath failed"
14992                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
14993         done
14994
14995         return 0
14996 }
14997 run_test 162c "fid2path works with paths 100 or more directories deep"
14998
14999 oalr_event_count() {
15000         local event="${1}"
15001         local trace="${2}"
15002
15003         awk -v name="${FSNAME}-OST0000" \
15004             -v event="${event}" \
15005             '$1 == "TRACE" && $2 == event && $3 == name' \
15006             "${trace}" |
15007         wc -l
15008 }
15009
15010 oalr_expect_event_count() {
15011         local event="${1}"
15012         local trace="${2}"
15013         local expect="${3}"
15014         local count
15015
15016         count=$(oalr_event_count "${event}" "${trace}")
15017         if ((count == expect)); then
15018                 return 0
15019         fi
15020
15021         error_noexit "${event} event count was '${count}', expected ${expect}"
15022         cat "${trace}" >&2
15023         exit 1
15024 }
15025
15026 cleanup_165() {
15027         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
15028         stop ost1
15029         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
15030 }
15031
15032 setup_165() {
15033         sync # Flush previous IOs so we can count log entries.
15034         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
15035         stack_trap cleanup_165 EXIT
15036 }
15037
15038 test_165a() {
15039         local trace="/tmp/${tfile}.trace"
15040         local rc
15041         local count
15042
15043         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15044         setup_165
15045         sleep 5
15046
15047         do_facet ost1 ofd_access_log_reader --list
15048         stop ost1
15049
15050         do_facet ost1 killall -TERM ofd_access_log_reader
15051         wait
15052         rc=$?
15053
15054         if ((rc != 0)); then
15055                 error "ofd_access_log_reader exited with rc = '${rc}'"
15056         fi
15057
15058         # Parse trace file for discovery events:
15059         oalr_expect_event_count alr_log_add "${trace}" 1
15060         oalr_expect_event_count alr_log_eof "${trace}" 1
15061         oalr_expect_event_count alr_log_free "${trace}" 1
15062 }
15063 run_test 165a "ofd access log discovery"
15064
15065 test_165b() {
15066         local trace="/tmp/${tfile}.trace"
15067         local file="${DIR}/${tfile}"
15068         local pfid1
15069         local pfid2
15070         local -a entry
15071         local rc
15072         local count
15073         local size
15074         local flags
15075
15076         setup_165
15077
15078         lfs setstripe -c 1 -i 0 "${file}"
15079         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15080         do_facet ost1 ofd_access_log_reader --list
15081
15082         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15083         sleep 5
15084         do_facet ost1 killall -TERM ofd_access_log_reader
15085         wait
15086         rc=$?
15087
15088         if ((rc != 0)); then
15089                 error "ofd_access_log_reader exited with rc = '${rc}'"
15090         fi
15091
15092         oalr_expect_event_count alr_log_entry "${trace}" 1
15093
15094         pfid1=$($LFS path2fid "${file}")
15095
15096         # 1     2             3   4    5     6   7    8    9     10
15097         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
15098         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
15099
15100         echo "entry = '${entry[*]}'" >&2
15101
15102         pfid2=${entry[4]}
15103         if [[ "${pfid1}" != "${pfid2}" ]]; then
15104                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
15105         fi
15106
15107         size=${entry[8]}
15108         if ((size != 1048576)); then
15109                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
15110         fi
15111
15112         flags=${entry[10]}
15113         if [[ "${flags}" != "w" ]]; then
15114                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
15115         fi
15116
15117         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15118         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c || error "cannot read '${file}'"
15119         sleep 5
15120         do_facet ost1 killall -TERM ofd_access_log_reader
15121         wait
15122         rc=$?
15123
15124         if ((rc != 0)); then
15125                 error "ofd_access_log_reader exited with rc = '${rc}'"
15126         fi
15127
15128         oalr_expect_event_count alr_log_entry "${trace}" 1
15129
15130         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
15131         echo "entry = '${entry[*]}'" >&2
15132
15133         pfid2=${entry[4]}
15134         if [[ "${pfid1}" != "${pfid2}" ]]; then
15135                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
15136         fi
15137
15138         size=${entry[8]}
15139         if ((size != 524288)); then
15140                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
15141         fi
15142
15143         flags=${entry[10]}
15144         if [[ "${flags}" != "r" ]]; then
15145                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
15146         fi
15147 }
15148 run_test 165b "ofd access log entries are produced and consumed"
15149
15150 test_165c() {
15151         local file="${DIR}/${tdir}/${tfile}"
15152         test_mkdir "${DIR}/${tdir}"
15153
15154         setup_165
15155
15156         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
15157
15158         # 4096 / 64 = 64. Create twice as many entries.
15159         for ((i = 0; i < 128; i++)); do
15160                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c || error "cannot create file"
15161         done
15162
15163         sync
15164         do_facet ost1 ofd_access_log_reader --list
15165         unlinkmany  "${file}-%d" 128
15166 }
15167 run_test 165c "full ofd access logs do not block IOs"
15168
15169 oal_peek_entry_count() {
15170         do_facet ost1 ofd_access_log_reader --list | awk '$1 == "_entry_count:" { print $2; }'
15171 }
15172
15173 oal_expect_entry_count() {
15174         local entry_count=$(oal_peek_entry_count)
15175         local expect="$1"
15176
15177         if ((entry_count == expect)); then
15178                 return 0
15179         fi
15180
15181         error_noexit "bad entry count, got ${entry_count}, expected ${expect}"
15182         do_facet ost1 ofd_access_log_reader --list >&2
15183         exit 1
15184 }
15185
15186 test_165d() {
15187         local trace="/tmp/${tfile}.trace"
15188         local file="${DIR}/${tdir}/${tfile}"
15189         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
15190         local entry_count
15191         test_mkdir "${DIR}/${tdir}"
15192
15193         setup_165
15194         lfs setstripe -c 1 -i 0 "${file}"
15195
15196         do_facet ost1 lctl set_param "${param}=rw"
15197         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15198         oal_expect_entry_count 1
15199
15200         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15201         oal_expect_entry_count 2
15202
15203         do_facet ost1 lctl set_param "${param}=r"
15204         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15205         oal_expect_entry_count 2
15206
15207         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15208         oal_expect_entry_count 3
15209
15210         do_facet ost1 lctl set_param "${param}=w"
15211         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15212         oal_expect_entry_count 4
15213
15214         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15215         oal_expect_entry_count 4
15216
15217         do_facet ost1 lctl set_param "${param}=0"
15218         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15219         oal_expect_entry_count 4
15220
15221         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15222         oal_expect_entry_count 4
15223 }
15224 run_test 165d "ofd_access_log mask works"
15225
15226 test_169() {
15227         # do directio so as not to populate the page cache
15228         log "creating a 10 Mb file"
15229         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
15230         log "starting reads"
15231         dd if=$DIR/$tfile of=/dev/null bs=4096 &
15232         log "truncating the file"
15233         $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
15234         log "killing dd"
15235         kill %+ || true # reads might have finished
15236         echo "wait until dd is finished"
15237         wait
15238         log "removing the temporary file"
15239         rm -rf $DIR/$tfile || error "tmp file removal failed"
15240 }
15241 run_test 169 "parallel read and truncate should not deadlock"
15242
15243 test_170() {
15244         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15245
15246         $LCTL clear     # bug 18514
15247         $LCTL debug_daemon start $TMP/${tfile}_log_good
15248         touch $DIR/$tfile
15249         $LCTL debug_daemon stop
15250         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
15251                 error "sed failed to read log_good"
15252
15253         $LCTL debug_daemon start $TMP/${tfile}_log_good
15254         rm -rf $DIR/$tfile
15255         $LCTL debug_daemon stop
15256
15257         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
15258                error "lctl df log_bad failed"
15259
15260         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
15261         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
15262
15263         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
15264         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
15265
15266         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
15267                 error "bad_line good_line1 good_line2 are empty"
15268
15269         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
15270         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
15271         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
15272
15273         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
15274         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
15275         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
15276
15277         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
15278                 error "bad_line_new good_line_new are empty"
15279
15280         local expected_good=$((good_line1 + good_line2*2))
15281
15282         rm -f $TMP/${tfile}*
15283         # LU-231, short malformed line may not be counted into bad lines
15284         if [ $bad_line -ne $bad_line_new ] &&
15285                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
15286                 error "expected $bad_line bad lines, but got $bad_line_new"
15287                 return 1
15288         fi
15289
15290         if [ $expected_good -ne $good_line_new ]; then
15291                 error "expected $expected_good good lines, but got $good_line_new"
15292                 return 2
15293         fi
15294         true
15295 }
15296 run_test 170 "test lctl df to handle corrupted log ====================="
15297
15298 test_171() { # bug20592
15299         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15300
15301         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
15302         $LCTL set_param fail_loc=0x50e
15303         $LCTL set_param fail_val=3000
15304         multiop_bg_pause $DIR/$tfile O_s || true
15305         local MULTIPID=$!
15306         kill -USR1 $MULTIPID
15307         # cause log dump
15308         sleep 3
15309         wait $MULTIPID
15310         if dmesg | grep "recursive fault"; then
15311                 error "caught a recursive fault"
15312         fi
15313         $LCTL set_param fail_loc=0
15314         true
15315 }
15316 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
15317
15318 # it would be good to share it with obdfilter-survey/iokit-libecho code
15319 setup_obdecho_osc () {
15320         local rc=0
15321         local ost_nid=$1
15322         local obdfilter_name=$2
15323         echo "Creating new osc for $obdfilter_name on $ost_nid"
15324         # make sure we can find loopback nid
15325         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
15326
15327         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
15328                            ${obdfilter_name}_osc_UUID || rc=2; }
15329         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
15330                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
15331         return $rc
15332 }
15333
15334 cleanup_obdecho_osc () {
15335         local obdfilter_name=$1
15336         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
15337         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
15338         return 0
15339 }
15340
15341 obdecho_test() {
15342         local OBD=$1
15343         local node=$2
15344         local pages=${3:-64}
15345         local rc=0
15346         local id
15347
15348         local count=10
15349         local obd_size=$(get_obd_size $node $OBD)
15350         local page_size=$(get_page_size $node)
15351         if [[ -n "$obd_size" ]]; then
15352                 local new_count=$((obd_size / (pages * page_size / 1024)))
15353                 [[ $new_count -ge $count ]] || count=$new_count
15354         fi
15355
15356         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
15357         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
15358                            rc=2; }
15359         if [ $rc -eq 0 ]; then
15360             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
15361             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
15362         fi
15363         echo "New object id is $id"
15364         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
15365                            rc=4; }
15366         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
15367                            "test_brw $count w v $pages $id" || rc=4; }
15368         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
15369                            rc=4; }
15370         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
15371                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
15372         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
15373                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
15374         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
15375         return $rc
15376 }
15377
15378 test_180a() {
15379         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15380
15381         if ! module_loaded obdecho; then
15382                 load_module obdecho/obdecho &&
15383                         stack_trap "rmmod obdecho" EXIT ||
15384                         error "unable to load obdecho on client"
15385         fi
15386
15387         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
15388         local host=$($LCTL get_param -n osc.$osc.import |
15389                      awk '/current_connection:/ { print $2 }' )
15390         local target=$($LCTL get_param -n osc.$osc.import |
15391                        awk '/target:/ { print $2 }' )
15392         target=${target%_UUID}
15393
15394         if [ -n "$target" ]; then
15395                 setup_obdecho_osc $host $target &&
15396                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
15397                         { error "obdecho setup failed with $?"; return; }
15398
15399                 obdecho_test ${target}_osc client ||
15400                         error "obdecho_test failed on ${target}_osc"
15401         else
15402                 $LCTL get_param osc.$osc.import
15403                 error "there is no osc.$osc.import target"
15404         fi
15405 }
15406 run_test 180a "test obdecho on osc"
15407
15408 test_180b() {
15409         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15410         remote_ost_nodsh && skip "remote OST with nodsh"
15411
15412         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
15413                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
15414                 error "failed to load module obdecho"
15415
15416         local target=$(do_facet ost1 $LCTL dl |
15417                        awk '/obdfilter/ { print $4; exit; }')
15418
15419         if [ -n "$target" ]; then
15420                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
15421         else
15422                 do_facet ost1 $LCTL dl
15423                 error "there is no obdfilter target on ost1"
15424         fi
15425 }
15426 run_test 180b "test obdecho directly on obdfilter"
15427
15428 test_180c() { # LU-2598
15429         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15430         remote_ost_nodsh && skip "remote OST with nodsh"
15431         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
15432                 skip "Need MDS version at least 2.4.0"
15433
15434         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
15435                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
15436                 error "failed to load module obdecho"
15437
15438         local target=$(do_facet ost1 $LCTL dl |
15439                        awk '/obdfilter/ { print $4; exit; }')
15440
15441         if [ -n "$target" ]; then
15442                 local pages=16384 # 64MB bulk I/O RPC size
15443
15444                 obdecho_test "$target" ost1 "$pages" ||
15445                         error "obdecho_test with pages=$pages failed with $?"
15446         else
15447                 do_facet ost1 $LCTL dl
15448                 error "there is no obdfilter target on ost1"
15449         fi
15450 }
15451 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
15452
15453 test_181() { # bug 22177
15454         test_mkdir $DIR/$tdir
15455         # create enough files to index the directory
15456         createmany -o $DIR/$tdir/foobar 4000
15457         # print attributes for debug purpose
15458         lsattr -d .
15459         # open dir
15460         multiop_bg_pause $DIR/$tdir D_Sc || return 1
15461         MULTIPID=$!
15462         # remove the files & current working dir
15463         unlinkmany $DIR/$tdir/foobar 4000
15464         rmdir $DIR/$tdir
15465         kill -USR1 $MULTIPID
15466         wait $MULTIPID
15467         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
15468         return 0
15469 }
15470 run_test 181 "Test open-unlinked dir ========================"
15471
15472 test_182() {
15473         local fcount=1000
15474         local tcount=10
15475
15476         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
15477
15478         $LCTL set_param mdc.*.rpc_stats=clear
15479
15480         for (( i = 0; i < $tcount; i++ )) ; do
15481                 mkdir $DIR/$tdir/$i
15482         done
15483
15484         for (( i = 0; i < $tcount; i++ )) ; do
15485                 createmany -o $DIR/$tdir/$i/f- $fcount &
15486         done
15487         wait
15488
15489         for (( i = 0; i < $tcount; i++ )) ; do
15490                 unlinkmany $DIR/$tdir/$i/f- $fcount &
15491         done
15492         wait
15493
15494         $LCTL get_param mdc.*.rpc_stats
15495
15496         rm -rf $DIR/$tdir
15497 }
15498 run_test 182 "Test parallel modify metadata operations ================"
15499
15500 test_183() { # LU-2275
15501         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15502         remote_mds_nodsh && skip "remote MDS with nodsh"
15503         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
15504                 skip "Need MDS version at least 2.3.56"
15505
15506         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
15507         echo aaa > $DIR/$tdir/$tfile
15508
15509 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
15510         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
15511
15512         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
15513         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
15514
15515         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
15516
15517         # Flush negative dentry cache
15518         touch $DIR/$tdir/$tfile
15519
15520         # We are not checking for any leaked references here, they'll
15521         # become evident next time we do cleanup with module unload.
15522         rm -rf $DIR/$tdir
15523 }
15524 run_test 183 "No crash or request leak in case of strange dispositions ========"
15525
15526 # test suite 184 is for LU-2016, LU-2017
15527 test_184a() {
15528         check_swap_layouts_support
15529
15530         dir0=$DIR/$tdir/$testnum
15531         test_mkdir -p -c1 $dir0
15532         ref1=/etc/passwd
15533         ref2=/etc/group
15534         file1=$dir0/f1
15535         file2=$dir0/f2
15536         $LFS setstripe -c1 $file1
15537         cp $ref1 $file1
15538         $LFS setstripe -c2 $file2
15539         cp $ref2 $file2
15540         gen1=$($LFS getstripe -g $file1)
15541         gen2=$($LFS getstripe -g $file2)
15542
15543         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
15544         gen=$($LFS getstripe -g $file1)
15545         [[ $gen1 != $gen ]] ||
15546                 "Layout generation on $file1 does not change"
15547         gen=$($LFS getstripe -g $file2)
15548         [[ $gen2 != $gen ]] ||
15549                 "Layout generation on $file2 does not change"
15550
15551         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
15552         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
15553
15554         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
15555 }
15556 run_test 184a "Basic layout swap"
15557
15558 test_184b() {
15559         check_swap_layouts_support
15560
15561         dir0=$DIR/$tdir/$testnum
15562         mkdir -p $dir0 || error "creating dir $dir0"
15563         file1=$dir0/f1
15564         file2=$dir0/f2
15565         file3=$dir0/f3
15566         dir1=$dir0/d1
15567         dir2=$dir0/d2
15568         mkdir $dir1 $dir2
15569         $LFS setstripe -c1 $file1
15570         $LFS setstripe -c2 $file2
15571         $LFS setstripe -c1 $file3
15572         chown $RUNAS_ID $file3
15573         gen1=$($LFS getstripe -g $file1)
15574         gen2=$($LFS getstripe -g $file2)
15575
15576         $LFS swap_layouts $dir1 $dir2 &&
15577                 error "swap of directories layouts should fail"
15578         $LFS swap_layouts $dir1 $file1 &&
15579                 error "swap of directory and file layouts should fail"
15580         $RUNAS $LFS swap_layouts $file1 $file2 &&
15581                 error "swap of file we cannot write should fail"
15582         $LFS swap_layouts $file1 $file3 &&
15583                 error "swap of file with different owner should fail"
15584         /bin/true # to clear error code
15585 }
15586 run_test 184b "Forbidden layout swap (will generate errors)"
15587
15588 test_184c() {
15589         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
15590         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
15591         check_swap_layouts_support
15592
15593         local dir0=$DIR/$tdir/$testnum
15594         mkdir -p $dir0 || error "creating dir $dir0"
15595
15596         local ref1=$dir0/ref1
15597         local ref2=$dir0/ref2
15598         local file1=$dir0/file1
15599         local file2=$dir0/file2
15600         # create a file large enough for the concurrent test
15601         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
15602         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
15603         echo "ref file size: ref1($(stat -c %s $ref1))," \
15604              "ref2($(stat -c %s $ref2))"
15605
15606         cp $ref2 $file2
15607         dd if=$ref1 of=$file1 bs=16k &
15608         local DD_PID=$!
15609
15610         # Make sure dd starts to copy file
15611         while [ ! -f $file1 ]; do sleep 0.1; done
15612
15613         $LFS swap_layouts $file1 $file2
15614         local rc=$?
15615         wait $DD_PID
15616         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
15617         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
15618
15619         # how many bytes copied before swapping layout
15620         local copied=$(stat -c %s $file2)
15621         local remaining=$(stat -c %s $ref1)
15622         remaining=$((remaining - copied))
15623         echo "Copied $copied bytes before swapping layout..."
15624
15625         cmp -n $copied $file1 $ref2 | grep differ &&
15626                 error "Content mismatch [0, $copied) of ref2 and file1"
15627         cmp -n $copied $file2 $ref1 ||
15628                 error "Content mismatch [0, $copied) of ref1 and file2"
15629         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
15630                 error "Content mismatch [$copied, EOF) of ref1 and file1"
15631
15632         # clean up
15633         rm -f $ref1 $ref2 $file1 $file2
15634 }
15635 run_test 184c "Concurrent write and layout swap"
15636
15637 test_184d() {
15638         check_swap_layouts_support
15639         [ -z "$(which getfattr 2>/dev/null)" ] &&
15640                 skip_env "no getfattr command"
15641
15642         local file1=$DIR/$tdir/$tfile-1
15643         local file2=$DIR/$tdir/$tfile-2
15644         local file3=$DIR/$tdir/$tfile-3
15645         local lovea1
15646         local lovea2
15647
15648         mkdir -p $DIR/$tdir
15649         touch $file1 || error "create $file1 failed"
15650         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
15651                 error "create $file2 failed"
15652         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
15653                 error "create $file3 failed"
15654         lovea1=$(get_layout_param $file1)
15655
15656         $LFS swap_layouts $file2 $file3 ||
15657                 error "swap $file2 $file3 layouts failed"
15658         $LFS swap_layouts $file1 $file2 ||
15659                 error "swap $file1 $file2 layouts failed"
15660
15661         lovea2=$(get_layout_param $file2)
15662         echo "$lovea1"
15663         echo "$lovea2"
15664         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
15665
15666         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
15667         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
15668 }
15669 run_test 184d "allow stripeless layouts swap"
15670
15671 test_184e() {
15672         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
15673                 skip "Need MDS version at least 2.6.94"
15674         check_swap_layouts_support
15675         [ -z "$(which getfattr 2>/dev/null)" ] &&
15676                 skip_env "no getfattr command"
15677
15678         local file1=$DIR/$tdir/$tfile-1
15679         local file2=$DIR/$tdir/$tfile-2
15680         local file3=$DIR/$tdir/$tfile-3
15681         local lovea
15682
15683         mkdir -p $DIR/$tdir
15684         touch $file1 || error "create $file1 failed"
15685         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
15686                 error "create $file2 failed"
15687         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
15688                 error "create $file3 failed"
15689
15690         $LFS swap_layouts $file1 $file2 ||
15691                 error "swap $file1 $file2 layouts failed"
15692
15693         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
15694         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
15695
15696         echo 123 > $file1 || error "Should be able to write into $file1"
15697
15698         $LFS swap_layouts $file1 $file3 ||
15699                 error "swap $file1 $file3 layouts failed"
15700
15701         echo 123 > $file1 || error "Should be able to write into $file1"
15702
15703         rm -rf $file1 $file2 $file3
15704 }
15705 run_test 184e "Recreate layout after stripeless layout swaps"
15706
15707 test_184f() {
15708         # Create a file with name longer than sizeof(struct stat) ==
15709         # 144 to see if we can get chars from the file name to appear
15710         # in the returned striping. Note that 'f' == 0x66.
15711         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
15712
15713         mkdir -p $DIR/$tdir
15714         mcreate $DIR/$tdir/$file
15715         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
15716                 error "IOC_MDC_GETFILEINFO returned garbage striping"
15717         fi
15718 }
15719 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
15720
15721 test_185() { # LU-2441
15722         # LU-3553 - no volatile file support in old servers
15723         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
15724                 skip "Need MDS version at least 2.3.60"
15725
15726         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
15727         touch $DIR/$tdir/spoo
15728         local mtime1=$(stat -c "%Y" $DIR/$tdir)
15729         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
15730                 error "cannot create/write a volatile file"
15731         [ "$FILESET" == "" ] &&
15732         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
15733                 error "FID is still valid after close"
15734
15735         multiop_bg_pause $DIR/$tdir vVw4096_c
15736         local multi_pid=$!
15737
15738         local OLD_IFS=$IFS
15739         IFS=":"
15740         local fidv=($fid)
15741         IFS=$OLD_IFS
15742         # assume that the next FID for this client is sequential, since stdout
15743         # is unfortunately eaten by multiop_bg_pause
15744         local n=$((${fidv[1]} + 1))
15745         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
15746         if [ "$FILESET" == "" ]; then
15747                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
15748                         error "FID is missing before close"
15749         fi
15750         kill -USR1 $multi_pid
15751         # 1 second delay, so if mtime change we will see it
15752         sleep 1
15753         local mtime2=$(stat -c "%Y" $DIR/$tdir)
15754         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
15755 }
15756 run_test 185 "Volatile file support"
15757
15758 function create_check_volatile() {
15759         local idx=$1
15760         local tgt
15761
15762         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
15763         local PID=$!
15764         sleep 1
15765         local FID=$(cat /tmp/${tfile}.fid)
15766         [ "$FID" == "" ] && error "can't get FID for volatile"
15767         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
15768         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
15769         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
15770         kill -USR1 $PID
15771         wait
15772         sleep 1
15773         cancel_lru_locks mdc # flush opencache
15774         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
15775         return 0
15776 }
15777
15778 test_185a(){
15779         # LU-12516 - volatile creation via .lustre
15780         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
15781                 skip "Need MDS version at least 2.3.55"
15782
15783         create_check_volatile 0
15784         [ $MDSCOUNT -lt 2 ] && return 0
15785
15786         # DNE case
15787         create_check_volatile 1
15788
15789         return 0
15790 }
15791 run_test 185a "Volatile file creation in .lustre/fid/"
15792
15793 test_187a() {
15794         remote_mds_nodsh && skip "remote MDS with nodsh"
15795         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
15796                 skip "Need MDS version at least 2.3.0"
15797
15798         local dir0=$DIR/$tdir/$testnum
15799         mkdir -p $dir0 || error "creating dir $dir0"
15800
15801         local file=$dir0/file1
15802         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
15803         local dv1=$($LFS data_version $file)
15804         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
15805         local dv2=$($LFS data_version $file)
15806         [[ $dv1 != $dv2 ]] ||
15807                 error "data version did not change on write $dv1 == $dv2"
15808
15809         # clean up
15810         rm -f $file1
15811 }
15812 run_test 187a "Test data version change"
15813
15814 test_187b() {
15815         remote_mds_nodsh && skip "remote MDS with nodsh"
15816         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
15817                 skip "Need MDS version at least 2.3.0"
15818
15819         local dir0=$DIR/$tdir/$testnum
15820         mkdir -p $dir0 || error "creating dir $dir0"
15821
15822         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
15823         [[ ${DV[0]} != ${DV[1]} ]] ||
15824                 error "data version did not change on write"\
15825                       " ${DV[0]} == ${DV[1]}"
15826
15827         # clean up
15828         rm -f $file1
15829 }
15830 run_test 187b "Test data version change on volatile file"
15831
15832 test_200() {
15833         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15834         remote_mgs_nodsh && skip "remote MGS with nodsh"
15835         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15836
15837         local POOL=${POOL:-cea1}
15838         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
15839         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
15840         # Pool OST targets
15841         local first_ost=0
15842         local last_ost=$(($OSTCOUNT - 1))
15843         local ost_step=2
15844         local ost_list=$(seq $first_ost $ost_step $last_ost)
15845         local ost_range="$first_ost $last_ost $ost_step"
15846         local test_path=$POOL_ROOT/$POOL_DIR_NAME
15847         local file_dir=$POOL_ROOT/file_tst
15848         local subdir=$test_path/subdir
15849         local rc=0
15850
15851         while : ; do
15852                 # former test_200a test_200b
15853                 pool_add $POOL                          || { rc=$? ; break; }
15854                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
15855                 # former test_200c test_200d
15856                 mkdir -p $test_path
15857                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
15858                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
15859                 mkdir -p $subdir
15860                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
15861                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
15862                                                         || { rc=$? ; break; }
15863                 # former test_200e test_200f
15864                 local files=$((OSTCOUNT*3))
15865                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
15866                                                         || { rc=$? ; break; }
15867                 pool_create_files $POOL $file_dir $files "$ost_list" \
15868                                                         || { rc=$? ; break; }
15869                 # former test_200g test_200h
15870                 pool_lfs_df $POOL                       || { rc=$? ; break; }
15871                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
15872
15873                 # former test_201a test_201b test_201c
15874                 pool_remove_first_target $POOL          || { rc=$? ; break; }
15875
15876                 local f=$test_path/$tfile
15877                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
15878                 pool_remove $POOL $f                    || { rc=$? ; break; }
15879                 break
15880         done
15881
15882         destroy_test_pools
15883
15884         return $rc
15885 }
15886 run_test 200 "OST pools"
15887
15888 # usage: default_attr <count | size | offset>
15889 default_attr() {
15890         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
15891 }
15892
15893 # usage: check_default_stripe_attr
15894 check_default_stripe_attr() {
15895         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
15896         case $1 in
15897         --stripe-count|-c)
15898                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
15899         --stripe-size|-S)
15900                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
15901         --stripe-index|-i)
15902                 EXPECTED=-1;;
15903         *)
15904                 error "unknown getstripe attr '$1'"
15905         esac
15906
15907         [ $ACTUAL == $EXPECTED ] ||
15908                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
15909 }
15910
15911 test_204a() {
15912         test_mkdir $DIR/$tdir
15913         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
15914
15915         check_default_stripe_attr --stripe-count
15916         check_default_stripe_attr --stripe-size
15917         check_default_stripe_attr --stripe-index
15918 }
15919 run_test 204a "Print default stripe attributes"
15920
15921 test_204b() {
15922         test_mkdir $DIR/$tdir
15923         $LFS setstripe --stripe-count 1 $DIR/$tdir
15924
15925         check_default_stripe_attr --stripe-size
15926         check_default_stripe_attr --stripe-index
15927 }
15928 run_test 204b "Print default stripe size and offset"
15929
15930 test_204c() {
15931         test_mkdir $DIR/$tdir
15932         $LFS setstripe --stripe-size 65536 $DIR/$tdir
15933
15934         check_default_stripe_attr --stripe-count
15935         check_default_stripe_attr --stripe-index
15936 }
15937 run_test 204c "Print default stripe count and offset"
15938
15939 test_204d() {
15940         test_mkdir $DIR/$tdir
15941         $LFS setstripe --stripe-index 0 $DIR/$tdir
15942
15943         check_default_stripe_attr --stripe-count
15944         check_default_stripe_attr --stripe-size
15945 }
15946 run_test 204d "Print default stripe count and size"
15947
15948 test_204e() {
15949         test_mkdir $DIR/$tdir
15950         $LFS setstripe -d $DIR/$tdir
15951
15952         check_default_stripe_attr --stripe-count --raw
15953         check_default_stripe_attr --stripe-size --raw
15954         check_default_stripe_attr --stripe-index --raw
15955 }
15956 run_test 204e "Print raw stripe attributes"
15957
15958 test_204f() {
15959         test_mkdir $DIR/$tdir
15960         $LFS setstripe --stripe-count 1 $DIR/$tdir
15961
15962         check_default_stripe_attr --stripe-size --raw
15963         check_default_stripe_attr --stripe-index --raw
15964 }
15965 run_test 204f "Print raw stripe size and offset"
15966
15967 test_204g() {
15968         test_mkdir $DIR/$tdir
15969         $LFS setstripe --stripe-size 65536 $DIR/$tdir
15970
15971         check_default_stripe_attr --stripe-count --raw
15972         check_default_stripe_attr --stripe-index --raw
15973 }
15974 run_test 204g "Print raw stripe count and offset"
15975
15976 test_204h() {
15977         test_mkdir $DIR/$tdir
15978         $LFS setstripe --stripe-index 0 $DIR/$tdir
15979
15980         check_default_stripe_attr --stripe-count --raw
15981         check_default_stripe_attr --stripe-size --raw
15982 }
15983 run_test 204h "Print raw stripe count and size"
15984
15985 # Figure out which job scheduler is being used, if any,
15986 # or use a fake one
15987 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
15988         JOBENV=SLURM_JOB_ID
15989 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
15990         JOBENV=LSB_JOBID
15991 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
15992         JOBENV=PBS_JOBID
15993 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
15994         JOBENV=LOADL_STEP_ID
15995 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
15996         JOBENV=JOB_ID
15997 else
15998         $LCTL list_param jobid_name > /dev/null 2>&1
15999         if [ $? -eq 0 ]; then
16000                 JOBENV=nodelocal
16001         else
16002                 JOBENV=FAKE_JOBID
16003         fi
16004 fi
16005 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
16006
16007 verify_jobstats() {
16008         local cmd=($1)
16009         shift
16010         local facets="$@"
16011
16012 # we don't really need to clear the stats for this test to work, since each
16013 # command has a unique jobid, but it makes debugging easier if needed.
16014 #       for facet in $facets; do
16015 #               local dev=$(convert_facet2label $facet)
16016 #               # clear old jobstats
16017 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
16018 #       done
16019
16020         # use a new JobID for each test, or we might see an old one
16021         [ "$JOBENV" = "FAKE_JOBID" ] &&
16022                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
16023
16024         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
16025
16026         [ "$JOBENV" = "nodelocal" ] && {
16027                 FAKE_JOBID=id.$testnum.%e.$RANDOM
16028                 $LCTL set_param jobid_name=$FAKE_JOBID
16029                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
16030         }
16031
16032         log "Test: ${cmd[*]}"
16033         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
16034
16035         if [ $JOBENV = "FAKE_JOBID" ]; then
16036                 FAKE_JOBID=$JOBVAL ${cmd[*]}
16037         else
16038                 ${cmd[*]}
16039         fi
16040
16041         # all files are created on OST0000
16042         for facet in $facets; do
16043                 local stats="*.$(convert_facet2label $facet).job_stats"
16044
16045                 # strip out libtool wrappers for in-tree executables
16046                 if [ $(do_facet $facet lctl get_param $stats |
16047                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
16048                         do_facet $facet lctl get_param $stats
16049                         error "No jobstats for $JOBVAL found on $facet::$stats"
16050                 fi
16051         done
16052 }
16053
16054 jobstats_set() {
16055         local new_jobenv=$1
16056
16057         set_persistent_param_and_check client "jobid_var" \
16058                 "$FSNAME.sys.jobid_var" $new_jobenv
16059 }
16060
16061 test_205a() { # Job stats
16062         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16063         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
16064                 skip "Need MDS version with at least 2.7.1"
16065         remote_mgs_nodsh && skip "remote MGS with nodsh"
16066         remote_mds_nodsh && skip "remote MDS with nodsh"
16067         remote_ost_nodsh && skip "remote OST with nodsh"
16068         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
16069                 skip "Server doesn't support jobstats"
16070         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
16071
16072         local old_jobenv=$($LCTL get_param -n jobid_var)
16073         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
16074
16075         if [[ $PERM_CMD == *"set_param -P"* ]]; then
16076                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
16077         else
16078                 stack_trap "do_facet mgs $PERM_CMD \
16079                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
16080         fi
16081         changelog_register
16082
16083         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
16084                                 mdt.*.job_cleanup_interval | head -n 1)
16085         local new_interval=5
16086         do_facet $SINGLEMDS \
16087                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
16088         stack_trap "do_facet $SINGLEMDS \
16089                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
16090         local start=$SECONDS
16091
16092         local cmd
16093         # mkdir
16094         cmd="mkdir $DIR/$tdir"
16095         verify_jobstats "$cmd" "$SINGLEMDS"
16096         # rmdir
16097         cmd="rmdir $DIR/$tdir"
16098         verify_jobstats "$cmd" "$SINGLEMDS"
16099         # mkdir on secondary MDT
16100         if [ $MDSCOUNT -gt 1 ]; then
16101                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
16102                 verify_jobstats "$cmd" "mds2"
16103         fi
16104         # mknod
16105         cmd="mknod $DIR/$tfile c 1 3"
16106         verify_jobstats "$cmd" "$SINGLEMDS"
16107         # unlink
16108         cmd="rm -f $DIR/$tfile"
16109         verify_jobstats "$cmd" "$SINGLEMDS"
16110         # create all files on OST0000 so verify_jobstats can find OST stats
16111         # open & close
16112         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
16113         verify_jobstats "$cmd" "$SINGLEMDS"
16114         # setattr
16115         cmd="touch $DIR/$tfile"
16116         verify_jobstats "$cmd" "$SINGLEMDS ost1"
16117         # write
16118         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
16119         verify_jobstats "$cmd" "ost1"
16120         # read
16121         cancel_lru_locks osc
16122         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
16123         verify_jobstats "$cmd" "ost1"
16124         # truncate
16125         cmd="$TRUNCATE $DIR/$tfile 0"
16126         verify_jobstats "$cmd" "$SINGLEMDS ost1"
16127         # rename
16128         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
16129         verify_jobstats "$cmd" "$SINGLEMDS"
16130         # jobstats expiry - sleep until old stats should be expired
16131         local left=$((new_interval + 5 - (SECONDS - start)))
16132         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
16133                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
16134                         "0" $left
16135         cmd="mkdir $DIR/$tdir.expire"
16136         verify_jobstats "$cmd" "$SINGLEMDS"
16137         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
16138             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
16139
16140         # Ensure that jobid are present in changelog (if supported by MDS)
16141         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
16142                 changelog_dump | tail -10
16143                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
16144                 [ $jobids -eq 9 ] ||
16145                         error "Wrong changelog jobid count $jobids != 9"
16146
16147                 # LU-5862
16148                 JOBENV="disable"
16149                 jobstats_set $JOBENV
16150                 touch $DIR/$tfile
16151                 changelog_dump | grep $tfile
16152                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
16153                 [ $jobids -eq 0 ] ||
16154                         error "Unexpected jobids when jobid_var=$JOBENV"
16155         fi
16156
16157         lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"
16158         JOBENV="JOBCOMPLEX"
16159         JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
16160
16161         verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
16162 }
16163 run_test 205a "Verify job stats"
16164
16165 # LU-13117
16166 test_205b() {
16167         $LCTL set_param jobid_var=USER jobid_name="%e.%u"
16168         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
16169         do_facet $SINGLEMDS $LCTL get_param mdt.*.job_stats |
16170                 grep job_id: | grep foolish &&
16171                         error "Unexpected jobid found"
16172         true
16173 }
16174 run_test 205b "Verify job stats jobid parsing"
16175
16176 # LU-1480, LU-1773 and LU-1657
16177 test_206() {
16178         mkdir -p $DIR/$tdir
16179         $LFS setstripe -c -1 $DIR/$tdir
16180 #define OBD_FAIL_LOV_INIT 0x1403
16181         $LCTL set_param fail_loc=0xa0001403
16182         $LCTL set_param fail_val=1
16183         touch $DIR/$tdir/$tfile || true
16184 }
16185 run_test 206 "fail lov_init_raid0() doesn't lbug"
16186
16187 test_207a() {
16188         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
16189         local fsz=`stat -c %s $DIR/$tfile`
16190         cancel_lru_locks mdc
16191
16192         # do not return layout in getattr intent
16193 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
16194         $LCTL set_param fail_loc=0x170
16195         local sz=`stat -c %s $DIR/$tfile`
16196
16197         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
16198
16199         rm -rf $DIR/$tfile
16200 }
16201 run_test 207a "can refresh layout at glimpse"
16202
16203 test_207b() {
16204         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
16205         local cksum=`md5sum $DIR/$tfile`
16206         local fsz=`stat -c %s $DIR/$tfile`
16207         cancel_lru_locks mdc
16208         cancel_lru_locks osc
16209
16210         # do not return layout in getattr intent
16211 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
16212         $LCTL set_param fail_loc=0x171
16213
16214         # it will refresh layout after the file is opened but before read issues
16215         echo checksum is "$cksum"
16216         echo "$cksum" |md5sum -c --quiet || error "file differs"
16217
16218         rm -rf $DIR/$tfile
16219 }
16220 run_test 207b "can refresh layout at open"
16221
16222 test_208() {
16223         # FIXME: in this test suite, only RD lease is used. This is okay
16224         # for now as only exclusive open is supported. After generic lease
16225         # is done, this test suite should be revised. - Jinshan
16226
16227         remote_mds_nodsh && skip "remote MDS with nodsh"
16228         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
16229                 skip "Need MDS version at least 2.4.52"
16230
16231         echo "==== test 1: verify get lease work"
16232         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
16233
16234         echo "==== test 2: verify lease can be broken by upcoming open"
16235         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
16236         local PID=$!
16237         sleep 1
16238
16239         $MULTIOP $DIR/$tfile oO_RDONLY:c
16240         kill -USR1 $PID && wait $PID || error "break lease error"
16241
16242         echo "==== test 3: verify lease can't be granted if an open already exists"
16243         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
16244         local PID=$!
16245         sleep 1
16246
16247         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
16248         kill -USR1 $PID && wait $PID || error "open file error"
16249
16250         echo "==== test 4: lease can sustain over recovery"
16251         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
16252         PID=$!
16253         sleep 1
16254
16255         fail mds1
16256
16257         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
16258
16259         echo "==== test 5: lease broken can't be regained by replay"
16260         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
16261         PID=$!
16262         sleep 1
16263
16264         # open file to break lease and then recovery
16265         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
16266         fail mds1
16267
16268         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
16269
16270         rm -f $DIR/$tfile
16271 }
16272 run_test 208 "Exclusive open"
16273
16274 test_209() {
16275         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
16276                 skip_env "must have disp_stripe"
16277
16278         touch $DIR/$tfile
16279         sync; sleep 5; sync;
16280
16281         echo 3 > /proc/sys/vm/drop_caches
16282         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
16283
16284         # open/close 500 times
16285         for i in $(seq 500); do
16286                 cat $DIR/$tfile
16287         done
16288
16289         echo 3 > /proc/sys/vm/drop_caches
16290         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
16291
16292         echo "before: $req_before, after: $req_after"
16293         [ $((req_after - req_before)) -ge 300 ] &&
16294                 error "open/close requests are not freed"
16295         return 0
16296 }
16297 run_test 209 "read-only open/close requests should be freed promptly"
16298
16299 test_212() {
16300         size=`date +%s`
16301         size=$((size % 8192 + 1))
16302         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
16303         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
16304         rm -f $DIR/f212 $DIR/f212.xyz
16305 }
16306 run_test 212 "Sendfile test ============================================"
16307
16308 test_213() {
16309         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
16310         cancel_lru_locks osc
16311         lctl set_param fail_loc=0x8000040f
16312         # generate a read lock
16313         cat $DIR/$tfile > /dev/null
16314         # write to the file, it will try to cancel the above read lock.
16315         cat /etc/hosts >> $DIR/$tfile
16316 }
16317 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
16318
16319 test_214() { # for bug 20133
16320         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
16321         for (( i=0; i < 340; i++ )) ; do
16322                 touch $DIR/$tdir/d214c/a$i
16323         done
16324
16325         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
16326         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
16327         ls $DIR/d214c || error "ls $DIR/d214c failed"
16328         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
16329         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
16330 }
16331 run_test 214 "hash-indexed directory test - bug 20133"
16332
16333 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
16334 create_lnet_proc_files() {
16335         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
16336 }
16337
16338 # counterpart of create_lnet_proc_files
16339 remove_lnet_proc_files() {
16340         rm -f $TMP/lnet_$1.sys
16341 }
16342
16343 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
16344 # 3rd arg as regexp for body
16345 check_lnet_proc_stats() {
16346         local l=$(cat "$TMP/lnet_$1" |wc -l)
16347         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
16348
16349         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
16350 }
16351
16352 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
16353 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
16354 # optional and can be regexp for 2nd line (lnet.routes case)
16355 check_lnet_proc_entry() {
16356         local blp=2          # blp stands for 'position of 1st line of body'
16357         [ -z "$5" ] || blp=3 # lnet.routes case
16358
16359         local l=$(cat "$TMP/lnet_$1" |wc -l)
16360         # subtracting one from $blp because the body can be empty
16361         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
16362
16363         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
16364                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
16365
16366         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
16367                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
16368
16369         # bail out if any unexpected line happened
16370         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
16371         [ "$?" != 0 ] || error "$2 misformatted"
16372 }
16373
16374 test_215() { # for bugs 18102, 21079, 21517
16375         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16376
16377         local N='(0|[1-9][0-9]*)'       # non-negative numeric
16378         local P='[1-9][0-9]*'           # positive numeric
16379         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
16380         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
16381         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
16382         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
16383
16384         local L1 # regexp for 1st line
16385         local L2 # regexp for 2nd line (optional)
16386         local BR # regexp for the rest (body)
16387
16388         # lnet.stats should look as 11 space-separated non-negative numerics
16389         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
16390         create_lnet_proc_files "stats"
16391         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
16392         remove_lnet_proc_files "stats"
16393
16394         # lnet.routes should look like this:
16395         # Routing disabled/enabled
16396         # net hops priority state router
16397         # where net is a string like tcp0, hops > 0, priority >= 0,
16398         # state is up/down,
16399         # router is a string like 192.168.1.1@tcp2
16400         L1="^Routing (disabled|enabled)$"
16401         L2="^net +hops +priority +state +router$"
16402         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
16403         create_lnet_proc_files "routes"
16404         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
16405         remove_lnet_proc_files "routes"
16406
16407         # lnet.routers should look like this:
16408         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
16409         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
16410         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
16411         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
16412         L1="^ref +rtr_ref +alive +router$"
16413         BR="^$P +$P +(up|down) +$NID$"
16414         create_lnet_proc_files "routers"
16415         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
16416         remove_lnet_proc_files "routers"
16417
16418         # lnet.peers should look like this:
16419         # nid refs state last max rtr min tx min queue
16420         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
16421         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
16422         # numeric (0 or >0 or <0), queue >= 0.
16423         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
16424         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
16425         create_lnet_proc_files "peers"
16426         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
16427         remove_lnet_proc_files "peers"
16428
16429         # lnet.buffers  should look like this:
16430         # pages count credits min
16431         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
16432         L1="^pages +count +credits +min$"
16433         BR="^ +$N +$N +$I +$I$"
16434         create_lnet_proc_files "buffers"
16435         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
16436         remove_lnet_proc_files "buffers"
16437
16438         # lnet.nis should look like this:
16439         # nid status alive refs peer rtr max tx min
16440         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
16441         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
16442         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
16443         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
16444         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
16445         create_lnet_proc_files "nis"
16446         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
16447         remove_lnet_proc_files "nis"
16448
16449         # can we successfully write to lnet.stats?
16450         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
16451 }
16452 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
16453
16454 test_216() { # bug 20317
16455         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16456         remote_ost_nodsh && skip "remote OST with nodsh"
16457
16458         local node
16459         local facets=$(get_facets OST)
16460         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16461
16462         save_lustre_params client "osc.*.contention_seconds" > $p
16463         save_lustre_params $facets \
16464                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
16465         save_lustre_params $facets \
16466                 "ldlm.namespaces.filter-*.contended_locks" >> $p
16467         save_lustre_params $facets \
16468                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
16469         clear_stats osc.*.osc_stats
16470
16471         # agressive lockless i/o settings
16472         do_nodes $(comma_list $(osts_nodes)) \
16473                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
16474                         ldlm.namespaces.filter-*.contended_locks=0 \
16475                         ldlm.namespaces.filter-*.contention_seconds=60"
16476         lctl set_param -n osc.*.contention_seconds=60
16477
16478         $DIRECTIO write $DIR/$tfile 0 10 4096
16479         $CHECKSTAT -s 40960 $DIR/$tfile
16480
16481         # disable lockless i/o
16482         do_nodes $(comma_list $(osts_nodes)) \
16483                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
16484                         ldlm.namespaces.filter-*.contended_locks=32 \
16485                         ldlm.namespaces.filter-*.contention_seconds=0"
16486         lctl set_param -n osc.*.contention_seconds=0
16487         clear_stats osc.*.osc_stats
16488
16489         dd if=/dev/zero of=$DIR/$tfile count=0
16490         $CHECKSTAT -s 0 $DIR/$tfile
16491
16492         restore_lustre_params <$p
16493         rm -f $p
16494         rm $DIR/$tfile
16495 }
16496 run_test 216 "check lockless direct write updates file size and kms correctly"
16497
16498 test_217() { # bug 22430
16499         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16500
16501         local node
16502         local nid
16503
16504         for node in $(nodes_list); do
16505                 nid=$(host_nids_address $node $NETTYPE)
16506                 if [[ $nid = *-* ]] ; then
16507                         echo "lctl ping $(h2nettype $nid)"
16508                         lctl ping $(h2nettype $nid)
16509                 else
16510                         echo "skipping $node (no hyphen detected)"
16511                 fi
16512         done
16513 }
16514 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
16515
16516 test_218() {
16517        # do directio so as not to populate the page cache
16518        log "creating a 10 Mb file"
16519        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
16520        log "starting reads"
16521        dd if=$DIR/$tfile of=/dev/null bs=4096 &
16522        log "truncating the file"
16523        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
16524        log "killing dd"
16525        kill %+ || true # reads might have finished
16526        echo "wait until dd is finished"
16527        wait
16528        log "removing the temporary file"
16529        rm -rf $DIR/$tfile || error "tmp file removal failed"
16530 }
16531 run_test 218 "parallel read and truncate should not deadlock"
16532
16533 test_219() {
16534         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16535
16536         # write one partial page
16537         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
16538         # set no grant so vvp_io_commit_write will do sync write
16539         $LCTL set_param fail_loc=0x411
16540         # write a full page at the end of file
16541         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
16542
16543         $LCTL set_param fail_loc=0
16544         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
16545         $LCTL set_param fail_loc=0x411
16546         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
16547
16548         # LU-4201
16549         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
16550         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
16551 }
16552 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
16553
16554 test_220() { #LU-325
16555         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16556         remote_ost_nodsh && skip "remote OST with nodsh"
16557         remote_mds_nodsh && skip "remote MDS with nodsh"
16558         remote_mgs_nodsh && skip "remote MGS with nodsh"
16559
16560         local OSTIDX=0
16561
16562         # create on MDT0000 so the last_id and next_id are correct
16563         mkdir $DIR/$tdir
16564         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
16565         OST=${OST%_UUID}
16566
16567         # on the mdt's osc
16568         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
16569         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
16570                         osp.$mdtosc_proc1.prealloc_last_id)
16571         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
16572                         osp.$mdtosc_proc1.prealloc_next_id)
16573
16574         $LFS df -i
16575
16576         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
16577         #define OBD_FAIL_OST_ENOINO              0x229
16578         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
16579         create_pool $FSNAME.$TESTNAME || return 1
16580         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
16581
16582         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
16583
16584         MDSOBJS=$((last_id - next_id))
16585         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
16586
16587         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
16588         echo "OST still has $count kbytes free"
16589
16590         echo "create $MDSOBJS files @next_id..."
16591         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
16592
16593         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
16594                         osp.$mdtosc_proc1.prealloc_last_id)
16595         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
16596                         osp.$mdtosc_proc1.prealloc_next_id)
16597
16598         echo "after creation, last_id=$last_id2, next_id=$next_id2"
16599         $LFS df -i
16600
16601         echo "cleanup..."
16602
16603         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
16604         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
16605
16606         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
16607                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
16608         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
16609                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
16610         echo "unlink $MDSOBJS files @$next_id..."
16611         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
16612 }
16613 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
16614
16615 test_221() {
16616         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16617
16618         dd if=`which date` of=$MOUNT/date oflag=sync
16619         chmod +x $MOUNT/date
16620
16621         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
16622         $LCTL set_param fail_loc=0x80001401
16623
16624         $MOUNT/date > /dev/null
16625         rm -f $MOUNT/date
16626 }
16627 run_test 221 "make sure fault and truncate race to not cause OOM"
16628
16629 test_222a () {
16630         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16631
16632         rm -rf $DIR/$tdir
16633         test_mkdir $DIR/$tdir
16634         $LFS setstripe -c 1 -i 0 $DIR/$tdir
16635         createmany -o $DIR/$tdir/$tfile 10
16636         cancel_lru_locks mdc
16637         cancel_lru_locks osc
16638         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
16639         $LCTL set_param fail_loc=0x31a
16640         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
16641         $LCTL set_param fail_loc=0
16642         rm -r $DIR/$tdir
16643 }
16644 run_test 222a "AGL for ls should not trigger CLIO lock failure"
16645
16646 test_222b () {
16647         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16648
16649         rm -rf $DIR/$tdir
16650         test_mkdir $DIR/$tdir
16651         $LFS setstripe -c 1 -i 0 $DIR/$tdir
16652         createmany -o $DIR/$tdir/$tfile 10
16653         cancel_lru_locks mdc
16654         cancel_lru_locks osc
16655         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
16656         $LCTL set_param fail_loc=0x31a
16657         rm -r $DIR/$tdir || error "AGL for rmdir failed"
16658         $LCTL set_param fail_loc=0
16659 }
16660 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
16661
16662 test_223 () {
16663         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16664
16665         rm -rf $DIR/$tdir
16666         test_mkdir $DIR/$tdir
16667         $LFS setstripe -c 1 -i 0 $DIR/$tdir
16668         createmany -o $DIR/$tdir/$tfile 10
16669         cancel_lru_locks mdc
16670         cancel_lru_locks osc
16671         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
16672         $LCTL set_param fail_loc=0x31b
16673         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
16674         $LCTL set_param fail_loc=0
16675         rm -r $DIR/$tdir
16676 }
16677 run_test 223 "osc reenqueue if without AGL lock granted ======================="
16678
16679 test_224a() { # LU-1039, MRP-303
16680         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16681
16682         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
16683         $LCTL set_param fail_loc=0x508
16684         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
16685         $LCTL set_param fail_loc=0
16686         df $DIR
16687 }
16688 run_test 224a "Don't panic on bulk IO failure"
16689
16690 test_224b() { # LU-1039, MRP-303
16691         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16692
16693         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
16694         cancel_lru_locks osc
16695         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
16696         $LCTL set_param fail_loc=0x515
16697         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
16698         $LCTL set_param fail_loc=0
16699         df $DIR
16700 }
16701 run_test 224b "Don't panic on bulk IO failure"
16702
16703 test_224c() { # LU-6441
16704         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16705         remote_mds_nodsh && skip "remote MDS with nodsh"
16706
16707         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16708         save_writethrough $p
16709         set_cache writethrough on
16710
16711         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
16712         local at_max=$($LCTL get_param -n at_max)
16713         local timeout=$($LCTL get_param -n timeout)
16714         local test_at="at_max"
16715         local param_at="$FSNAME.sys.at_max"
16716         local test_timeout="timeout"
16717         local param_timeout="$FSNAME.sys.timeout"
16718
16719         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
16720
16721         set_persistent_param_and_check client "$test_at" "$param_at" 0
16722         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
16723
16724         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
16725         do_facet ost1 "$LCTL set_param fail_loc=0x520"
16726         $LFS setstripe -c 1 -i 0 $DIR/$tfile
16727         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
16728         sync
16729         do_facet ost1 "$LCTL set_param fail_loc=0"
16730
16731         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
16732         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
16733                 $timeout
16734
16735         $LCTL set_param -n $pages_per_rpc
16736         restore_lustre_params < $p
16737         rm -f $p
16738 }
16739 run_test 224c "Don't hang if one of md lost during large bulk RPC"
16740
16741 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
16742 test_225a () {
16743         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16744         if [ -z ${MDSSURVEY} ]; then
16745                 skip_env "mds-survey not found"
16746         fi
16747         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
16748                 skip "Need MDS version at least 2.2.51"
16749
16750         local mds=$(facet_host $SINGLEMDS)
16751         local target=$(do_nodes $mds 'lctl dl' |
16752                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
16753
16754         local cmd1="file_count=1000 thrhi=4"
16755         local cmd2="dir_count=2 layer=mdd stripe_count=0"
16756         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
16757         local cmd="$cmd1 $cmd2 $cmd3"
16758
16759         rm -f ${TMP}/mds_survey*
16760         echo + $cmd
16761         eval $cmd || error "mds-survey with zero-stripe failed"
16762         cat ${TMP}/mds_survey*
16763         rm -f ${TMP}/mds_survey*
16764 }
16765 run_test 225a "Metadata survey sanity with zero-stripe"
16766
16767 test_225b () {
16768         if [ -z ${MDSSURVEY} ]; then
16769                 skip_env "mds-survey not found"
16770         fi
16771         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
16772                 skip "Need MDS version at least 2.2.51"
16773         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16774         remote_mds_nodsh && skip "remote MDS with nodsh"
16775         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
16776                 skip_env "Need to mount OST to test"
16777         fi
16778
16779         local mds=$(facet_host $SINGLEMDS)
16780         local target=$(do_nodes $mds 'lctl dl' |
16781                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
16782
16783         local cmd1="file_count=1000 thrhi=4"
16784         local cmd2="dir_count=2 layer=mdd stripe_count=1"
16785         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
16786         local cmd="$cmd1 $cmd2 $cmd3"
16787
16788         rm -f ${TMP}/mds_survey*
16789         echo + $cmd
16790         eval $cmd || error "mds-survey with stripe_count failed"
16791         cat ${TMP}/mds_survey*
16792         rm -f ${TMP}/mds_survey*
16793 }
16794 run_test 225b "Metadata survey sanity with stripe_count = 1"
16795
16796 mcreate_path2fid () {
16797         local mode=$1
16798         local major=$2
16799         local minor=$3
16800         local name=$4
16801         local desc=$5
16802         local path=$DIR/$tdir/$name
16803         local fid
16804         local rc
16805         local fid_path
16806
16807         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
16808                 error "cannot create $desc"
16809
16810         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
16811         rc=$?
16812         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
16813
16814         fid_path=$($LFS fid2path $MOUNT $fid)
16815         rc=$?
16816         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
16817
16818         [ "$path" == "$fid_path" ] ||
16819                 error "fid2path returned $fid_path, expected $path"
16820
16821         echo "pass with $path and $fid"
16822 }
16823
16824 test_226a () {
16825         rm -rf $DIR/$tdir
16826         mkdir -p $DIR/$tdir
16827
16828         mcreate_path2fid 0010666 0 0 fifo "FIFO"
16829         mcreate_path2fid 0020666 1 3 null "character special file (null)"
16830         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
16831         mcreate_path2fid 0040666 0 0 dir "directory"
16832         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
16833         mcreate_path2fid 0100666 0 0 file "regular file"
16834         mcreate_path2fid 0120666 0 0 link "symbolic link"
16835         mcreate_path2fid 0140666 0 0 sock "socket"
16836 }
16837 run_test 226a "call path2fid and fid2path on files of all type"
16838
16839 test_226b () {
16840         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16841
16842         local MDTIDX=1
16843
16844         rm -rf $DIR/$tdir
16845         mkdir -p $DIR/$tdir
16846         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
16847                 error "create remote directory failed"
16848         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
16849         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
16850                                 "character special file (null)"
16851         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
16852                                 "character special file (no device)"
16853         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
16854         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
16855                                 "block special file (loop)"
16856         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
16857         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
16858         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
16859 }
16860 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
16861
16862 # LU-1299 Executing or running ldd on a truncated executable does not
16863 # cause an out-of-memory condition.
16864 test_227() {
16865         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16866         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
16867
16868         dd if=$(which date) of=$MOUNT/date bs=1k count=1
16869         chmod +x $MOUNT/date
16870
16871         $MOUNT/date > /dev/null
16872         ldd $MOUNT/date > /dev/null
16873         rm -f $MOUNT/date
16874 }
16875 run_test 227 "running truncated executable does not cause OOM"
16876
16877 # LU-1512 try to reuse idle OI blocks
16878 test_228a() {
16879         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16880         remote_mds_nodsh && skip "remote MDS with nodsh"
16881         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
16882
16883         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
16884         local myDIR=$DIR/$tdir
16885
16886         mkdir -p $myDIR
16887         #define OBD_FAIL_SEQ_EXHAUST             0x1002
16888         $LCTL set_param fail_loc=0x80001002
16889         createmany -o $myDIR/t- 10000
16890         $LCTL set_param fail_loc=0
16891         # The guard is current the largest FID holder
16892         touch $myDIR/guard
16893         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
16894                     tr -d '[')
16895         local IDX=$(($SEQ % 64))
16896
16897         do_facet $SINGLEMDS sync
16898         # Make sure journal flushed.
16899         sleep 6
16900         local blk1=$(do_facet $SINGLEMDS \
16901                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16902                      grep Blockcount | awk '{print $4}')
16903
16904         # Remove old files, some OI blocks will become idle.
16905         unlinkmany $myDIR/t- 10000
16906         # Create new files, idle OI blocks should be reused.
16907         createmany -o $myDIR/t- 2000
16908         do_facet $SINGLEMDS sync
16909         # Make sure journal flushed.
16910         sleep 6
16911         local blk2=$(do_facet $SINGLEMDS \
16912                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16913                      grep Blockcount | awk '{print $4}')
16914
16915         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
16916 }
16917 run_test 228a "try to reuse idle OI blocks"
16918
16919 test_228b() {
16920         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16921         remote_mds_nodsh && skip "remote MDS with nodsh"
16922         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
16923
16924         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
16925         local myDIR=$DIR/$tdir
16926
16927         mkdir -p $myDIR
16928         #define OBD_FAIL_SEQ_EXHAUST             0x1002
16929         $LCTL set_param fail_loc=0x80001002
16930         createmany -o $myDIR/t- 10000
16931         $LCTL set_param fail_loc=0
16932         # The guard is current the largest FID holder
16933         touch $myDIR/guard
16934         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
16935                     tr -d '[')
16936         local IDX=$(($SEQ % 64))
16937
16938         do_facet $SINGLEMDS sync
16939         # Make sure journal flushed.
16940         sleep 6
16941         local blk1=$(do_facet $SINGLEMDS \
16942                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16943                      grep Blockcount | awk '{print $4}')
16944
16945         # Remove old files, some OI blocks will become idle.
16946         unlinkmany $myDIR/t- 10000
16947
16948         # stop the MDT
16949         stop $SINGLEMDS || error "Fail to stop MDT."
16950         # remount the MDT
16951         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
16952
16953         df $MOUNT || error "Fail to df."
16954         # Create new files, idle OI blocks should be reused.
16955         createmany -o $myDIR/t- 2000
16956         do_facet $SINGLEMDS sync
16957         # Make sure journal flushed.
16958         sleep 6
16959         local blk2=$(do_facet $SINGLEMDS \
16960                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16961                      grep Blockcount | awk '{print $4}')
16962
16963         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
16964 }
16965 run_test 228b "idle OI blocks can be reused after MDT restart"
16966
16967 #LU-1881
16968 test_228c() {
16969         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16970         remote_mds_nodsh && skip "remote MDS with nodsh"
16971         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
16972
16973         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
16974         local myDIR=$DIR/$tdir
16975
16976         mkdir -p $myDIR
16977         #define OBD_FAIL_SEQ_EXHAUST             0x1002
16978         $LCTL set_param fail_loc=0x80001002
16979         # 20000 files can guarantee there are index nodes in the OI file
16980         createmany -o $myDIR/t- 20000
16981         $LCTL set_param fail_loc=0
16982         # The guard is current the largest FID holder
16983         touch $myDIR/guard
16984         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
16985                     tr -d '[')
16986         local IDX=$(($SEQ % 64))
16987
16988         do_facet $SINGLEMDS sync
16989         # Make sure journal flushed.
16990         sleep 6
16991         local blk1=$(do_facet $SINGLEMDS \
16992                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16993                      grep Blockcount | awk '{print $4}')
16994
16995         # Remove old files, some OI blocks will become idle.
16996         unlinkmany $myDIR/t- 20000
16997         rm -f $myDIR/guard
16998         # The OI file should become empty now
16999
17000         # Create new files, idle OI blocks should be reused.
17001         createmany -o $myDIR/t- 2000
17002         do_facet $SINGLEMDS sync
17003         # Make sure journal flushed.
17004         sleep 6
17005         local blk2=$(do_facet $SINGLEMDS \
17006                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17007                      grep Blockcount | awk '{print $4}')
17008
17009         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17010 }
17011 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
17012
17013 test_229() { # LU-2482, LU-3448
17014         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17015         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
17016         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
17017                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
17018
17019         rm -f $DIR/$tfile
17020
17021         # Create a file with a released layout and stripe count 2.
17022         $MULTIOP $DIR/$tfile H2c ||
17023                 error "failed to create file with released layout"
17024
17025         $LFS getstripe -v $DIR/$tfile
17026
17027         local pattern=$($LFS getstripe -L $DIR/$tfile)
17028         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
17029
17030         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
17031                 error "getstripe"
17032         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
17033         stat $DIR/$tfile || error "failed to stat released file"
17034
17035         chown $RUNAS_ID $DIR/$tfile ||
17036                 error "chown $RUNAS_ID $DIR/$tfile failed"
17037
17038         chgrp $RUNAS_ID $DIR/$tfile ||
17039                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
17040
17041         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
17042         rm $DIR/$tfile || error "failed to remove released file"
17043 }
17044 run_test 229 "getstripe/stat/rm/attr changes work on released files"
17045
17046 test_230a() {
17047         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17048         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17049         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17050                 skip "Need MDS version at least 2.11.52"
17051
17052         local MDTIDX=1
17053
17054         test_mkdir $DIR/$tdir
17055         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
17056         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
17057         [ $mdt_idx -ne 0 ] &&
17058                 error "create local directory on wrong MDT $mdt_idx"
17059
17060         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
17061                         error "create remote directory failed"
17062         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
17063         [ $mdt_idx -ne $MDTIDX ] &&
17064                 error "create remote directory on wrong MDT $mdt_idx"
17065
17066         createmany -o $DIR/$tdir/test_230/t- 10 ||
17067                 error "create files on remote directory failed"
17068         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
17069         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
17070         rm -r $DIR/$tdir || error "unlink remote directory failed"
17071 }
17072 run_test 230a "Create remote directory and files under the remote directory"
17073
17074 test_230b() {
17075         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17076         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17077         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17078                 skip "Need MDS version at least 2.11.52"
17079
17080         local MDTIDX=1
17081         local mdt_index
17082         local i
17083         local file
17084         local pid
17085         local stripe_count
17086         local migrate_dir=$DIR/$tdir/migrate_dir
17087         local other_dir=$DIR/$tdir/other_dir
17088
17089         test_mkdir $DIR/$tdir
17090         test_mkdir -i0 -c1 $migrate_dir
17091         test_mkdir -i0 -c1 $other_dir
17092         for ((i=0; i<10; i++)); do
17093                 mkdir -p $migrate_dir/dir_${i}
17094                 createmany -o $migrate_dir/dir_${i}/f 10 ||
17095                         error "create files under remote dir failed $i"
17096         done
17097
17098         cp /etc/passwd $migrate_dir/$tfile
17099         cp /etc/passwd $other_dir/$tfile
17100         chattr +SAD $migrate_dir
17101         chattr +SAD $migrate_dir/$tfile
17102
17103         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17104         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17105         local old_dir_mode=$(stat -c%f $migrate_dir)
17106         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
17107
17108         mkdir -p $migrate_dir/dir_default_stripe2
17109         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
17110         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
17111
17112         mkdir -p $other_dir
17113         ln $migrate_dir/$tfile $other_dir/luna
17114         ln $migrate_dir/$tfile $migrate_dir/sofia
17115         ln $other_dir/$tfile $migrate_dir/david
17116         ln -s $migrate_dir/$tfile $other_dir/zachary
17117         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
17118         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
17119
17120         local len
17121         local lnktgt
17122
17123         # inline symlink
17124         for len in 58 59 60; do
17125                 lnktgt=$(str_repeat 'l' $len)
17126                 touch $migrate_dir/$lnktgt
17127                 ln -s $lnktgt $migrate_dir/${len}char_ln
17128         done
17129
17130         # PATH_MAX
17131         for len in 4094 4095; do
17132                 lnktgt=$(str_repeat 'l' $len)
17133                 ln -s $lnktgt $migrate_dir/${len}char_ln
17134         done
17135
17136         # NAME_MAX
17137         for len in 254 255; do
17138                 touch $migrate_dir/$(str_repeat 'l' $len)
17139         done
17140
17141         $LFS migrate -m $MDTIDX $migrate_dir ||
17142                 error "fails on migrating remote dir to MDT1"
17143
17144         echo "migratate to MDT1, then checking.."
17145         for ((i = 0; i < 10; i++)); do
17146                 for file in $(find $migrate_dir/dir_${i}); do
17147                         mdt_index=$($LFS getstripe -m $file)
17148                         # broken symlink getstripe will fail
17149                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
17150                                 error "$file is not on MDT${MDTIDX}"
17151                 done
17152         done
17153
17154         # the multiple link file should still in MDT0
17155         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
17156         [ $mdt_index == 0 ] ||
17157                 error "$file is not on MDT${MDTIDX}"
17158
17159         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17160         [ "$old_dir_flag" = "$new_dir_flag" ] ||
17161                 error " expect $old_dir_flag get $new_dir_flag"
17162
17163         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17164         [ "$old_file_flag" = "$new_file_flag" ] ||
17165                 error " expect $old_file_flag get $new_file_flag"
17166
17167         local new_dir_mode=$(stat -c%f $migrate_dir)
17168         [ "$old_dir_mode" = "$new_dir_mode" ] ||
17169                 error "expect mode $old_dir_mode get $new_dir_mode"
17170
17171         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
17172         [ "$old_file_mode" = "$new_file_mode" ] ||
17173                 error "expect mode $old_file_mode get $new_file_mode"
17174
17175         diff /etc/passwd $migrate_dir/$tfile ||
17176                 error "$tfile different after migration"
17177
17178         diff /etc/passwd $other_dir/luna ||
17179                 error "luna different after migration"
17180
17181         diff /etc/passwd $migrate_dir/sofia ||
17182                 error "sofia different after migration"
17183
17184         diff /etc/passwd $migrate_dir/david ||
17185                 error "david different after migration"
17186
17187         diff /etc/passwd $other_dir/zachary ||
17188                 error "zachary different after migration"
17189
17190         diff /etc/passwd $migrate_dir/${tfile}_ln ||
17191                 error "${tfile}_ln different after migration"
17192
17193         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
17194                 error "${tfile}_ln_other different after migration"
17195
17196         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
17197         [ $stripe_count = 2 ] ||
17198                 error "dir strpe_count $d != 2 after migration."
17199
17200         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
17201         [ $stripe_count = 2 ] ||
17202                 error "file strpe_count $d != 2 after migration."
17203
17204         #migrate back to MDT0
17205         MDTIDX=0
17206
17207         $LFS migrate -m $MDTIDX $migrate_dir ||
17208                 error "fails on migrating remote dir to MDT0"
17209
17210         echo "migrate back to MDT0, checking.."
17211         for file in $(find $migrate_dir); do
17212                 mdt_index=$($LFS getstripe -m $file)
17213                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
17214                         error "$file is not on MDT${MDTIDX}"
17215         done
17216
17217         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17218         [ "$old_dir_flag" = "$new_dir_flag" ] ||
17219                 error " expect $old_dir_flag get $new_dir_flag"
17220
17221         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17222         [ "$old_file_flag" = "$new_file_flag" ] ||
17223                 error " expect $old_file_flag get $new_file_flag"
17224
17225         local new_dir_mode=$(stat -c%f $migrate_dir)
17226         [ "$old_dir_mode" = "$new_dir_mode" ] ||
17227                 error "expect mode $old_dir_mode get $new_dir_mode"
17228
17229         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
17230         [ "$old_file_mode" = "$new_file_mode" ] ||
17231                 error "expect mode $old_file_mode get $new_file_mode"
17232
17233         diff /etc/passwd ${migrate_dir}/$tfile ||
17234                 error "$tfile different after migration"
17235
17236         diff /etc/passwd ${other_dir}/luna ||
17237                 error "luna different after migration"
17238
17239         diff /etc/passwd ${migrate_dir}/sofia ||
17240                 error "sofia different after migration"
17241
17242         diff /etc/passwd ${other_dir}/zachary ||
17243                 error "zachary different after migration"
17244
17245         diff /etc/passwd $migrate_dir/${tfile}_ln ||
17246                 error "${tfile}_ln different after migration"
17247
17248         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
17249                 error "${tfile}_ln_other different after migration"
17250
17251         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
17252         [ $stripe_count = 2 ] ||
17253                 error "dir strpe_count $d != 2 after migration."
17254
17255         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
17256         [ $stripe_count = 2 ] ||
17257                 error "file strpe_count $d != 2 after migration."
17258
17259         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17260 }
17261 run_test 230b "migrate directory"
17262
17263 test_230c() {
17264         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17265         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17266         remote_mds_nodsh && skip "remote MDS with nodsh"
17267         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17268                 skip "Need MDS version at least 2.11.52"
17269
17270         local MDTIDX=1
17271         local total=3
17272         local mdt_index
17273         local file
17274         local migrate_dir=$DIR/$tdir/migrate_dir
17275
17276         #If migrating directory fails in the middle, all entries of
17277         #the directory is still accessiable.
17278         test_mkdir $DIR/$tdir
17279         test_mkdir -i0 -c1 $migrate_dir
17280         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
17281         stat $migrate_dir
17282         createmany -o $migrate_dir/f $total ||
17283                 error "create files under ${migrate_dir} failed"
17284
17285         # fail after migrating top dir, and this will fail only once, so the
17286         # first sub file migration will fail (currently f3), others succeed.
17287         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
17288         do_facet mds1 lctl set_param fail_loc=0x1801
17289         local t=$(ls $migrate_dir | wc -l)
17290         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
17291                 error "migrate should fail"
17292         local u=$(ls $migrate_dir | wc -l)
17293         [ "$u" == "$t" ] || error "$u != $t during migration"
17294
17295         # add new dir/file should succeed
17296         mkdir $migrate_dir/dir ||
17297                 error "mkdir failed under migrating directory"
17298         touch $migrate_dir/file ||
17299                 error "create file failed under migrating directory"
17300
17301         # add file with existing name should fail
17302         for file in $migrate_dir/f*; do
17303                 stat $file > /dev/null || error "stat $file failed"
17304                 $OPENFILE -f O_CREAT:O_EXCL $file &&
17305                         error "open(O_CREAT|O_EXCL) $file should fail"
17306                 $MULTIOP $file m && error "create $file should fail"
17307                 touch $DIR/$tdir/remote_dir/$tfile ||
17308                         error "touch $tfile failed"
17309                 ln $DIR/$tdir/remote_dir/$tfile $file &&
17310                         error "link $file should fail"
17311                 mdt_index=$($LFS getstripe -m $file)
17312                 if [ $mdt_index == 0 ]; then
17313                         # file failed to migrate is not allowed to rename to
17314                         mv $DIR/$tdir/remote_dir/$tfile $file &&
17315                                 error "rename to $file should fail"
17316                 else
17317                         mv $DIR/$tdir/remote_dir/$tfile $file ||
17318                                 error "rename to $file failed"
17319                 fi
17320                 echo hello >> $file || error "write $file failed"
17321         done
17322
17323         # resume migration with different options should fail
17324         $LFS migrate -m 0 $migrate_dir &&
17325                 error "migrate -m 0 $migrate_dir should fail"
17326
17327         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
17328                 error "migrate -c 2 $migrate_dir should fail"
17329
17330         # resume migration should succeed
17331         $LFS migrate -m $MDTIDX $migrate_dir ||
17332                 error "migrate $migrate_dir failed"
17333
17334         echo "Finish migration, then checking.."
17335         for file in $(find $migrate_dir); do
17336                 mdt_index=$($LFS getstripe -m $file)
17337                 [ $mdt_index == $MDTIDX ] ||
17338                         error "$file is not on MDT${MDTIDX}"
17339         done
17340
17341         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17342 }
17343 run_test 230c "check directory accessiblity if migration failed"
17344
17345 test_230d() {
17346         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17347         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17348         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17349                 skip "Need MDS version at least 2.11.52"
17350         # LU-11235
17351         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
17352
17353         local migrate_dir=$DIR/$tdir/migrate_dir
17354         local old_index
17355         local new_index
17356         local old_count
17357         local new_count
17358         local new_hash
17359         local mdt_index
17360         local i
17361         local j
17362
17363         old_index=$((RANDOM % MDSCOUNT))
17364         old_count=$((MDSCOUNT - old_index))
17365         new_index=$((RANDOM % MDSCOUNT))
17366         new_count=$((MDSCOUNT - new_index))
17367         new_hash=1 # for all_char
17368
17369         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
17370         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
17371
17372         test_mkdir $DIR/$tdir
17373         test_mkdir -i $old_index -c $old_count $migrate_dir
17374
17375         for ((i=0; i<100; i++)); do
17376                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
17377                 createmany -o $migrate_dir/dir_${i}/f 100 ||
17378                         error "create files under remote dir failed $i"
17379         done
17380
17381         echo -n "Migrate from MDT$old_index "
17382         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
17383         echo -n "to MDT$new_index"
17384         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
17385         echo
17386
17387         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
17388         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
17389                 error "migrate remote dir error"
17390
17391         echo "Finish migration, then checking.."
17392         for file in $(find $migrate_dir); do
17393                 mdt_index=$($LFS getstripe -m $file)
17394                 if [ $mdt_index -lt $new_index ] ||
17395                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
17396                         error "$file is on MDT$mdt_index"
17397                 fi
17398         done
17399
17400         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17401 }
17402 run_test 230d "check migrate big directory"
17403
17404 test_230e() {
17405         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17406         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17407         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17408                 skip "Need MDS version at least 2.11.52"
17409
17410         local i
17411         local j
17412         local a_fid
17413         local b_fid
17414
17415         mkdir -p $DIR/$tdir
17416         mkdir $DIR/$tdir/migrate_dir
17417         mkdir $DIR/$tdir/other_dir
17418         touch $DIR/$tdir/migrate_dir/a
17419         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
17420         ls $DIR/$tdir/other_dir
17421
17422         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
17423                 error "migrate dir fails"
17424
17425         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
17426         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
17427
17428         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17429         [ $mdt_index == 0 ] || error "a is not on MDT0"
17430
17431         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
17432                 error "migrate dir fails"
17433
17434         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
17435         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
17436
17437         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17438         [ $mdt_index == 1 ] || error "a is not on MDT1"
17439
17440         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
17441         [ $mdt_index == 1 ] || error "b is not on MDT1"
17442
17443         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
17444         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
17445
17446         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
17447
17448         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17449 }
17450 run_test 230e "migrate mulitple local link files"
17451
17452 test_230f() {
17453         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17454         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17455         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17456                 skip "Need MDS version at least 2.11.52"
17457
17458         local a_fid
17459         local ln_fid
17460
17461         mkdir -p $DIR/$tdir
17462         mkdir $DIR/$tdir/migrate_dir
17463         $LFS mkdir -i1 $DIR/$tdir/other_dir
17464         touch $DIR/$tdir/migrate_dir/a
17465         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
17466         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
17467         ls $DIR/$tdir/other_dir
17468
17469         # a should be migrated to MDT1, since no other links on MDT0
17470         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
17471                 error "#1 migrate dir fails"
17472         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
17473         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
17474         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17475         [ $mdt_index == 1 ] || error "a is not on MDT1"
17476
17477         # a should stay on MDT1, because it is a mulitple link file
17478         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
17479                 error "#2 migrate dir fails"
17480         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17481         [ $mdt_index == 1 ] || error "a is not on MDT1"
17482
17483         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
17484                 error "#3 migrate dir fails"
17485
17486         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
17487         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
17488         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
17489
17490         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
17491         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
17492
17493         # a should be migrated to MDT0, since no other links on MDT1
17494         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
17495                 error "#4 migrate dir fails"
17496         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17497         [ $mdt_index == 0 ] || error "a is not on MDT0"
17498
17499         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17500 }
17501 run_test 230f "migrate mulitple remote link files"
17502
17503 test_230g() {
17504         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17505         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17506         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17507                 skip "Need MDS version at least 2.11.52"
17508
17509         mkdir -p $DIR/$tdir/migrate_dir
17510
17511         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
17512                 error "migrating dir to non-exist MDT succeeds"
17513         true
17514 }
17515 run_test 230g "migrate dir to non-exist MDT"
17516
17517 test_230h() {
17518         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17519         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17520         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17521                 skip "Need MDS version at least 2.11.52"
17522
17523         local mdt_index
17524
17525         mkdir -p $DIR/$tdir/migrate_dir
17526
17527         $LFS migrate -m1 $DIR &&
17528                 error "migrating mountpoint1 should fail"
17529
17530         $LFS migrate -m1 $DIR/$tdir/.. &&
17531                 error "migrating mountpoint2 should fail"
17532
17533         # same as mv
17534         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
17535                 error "migrating $tdir/migrate_dir/.. should fail"
17536
17537         true
17538 }
17539 run_test 230h "migrate .. and root"
17540
17541 test_230i() {
17542         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17543         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17544         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17545                 skip "Need MDS version at least 2.11.52"
17546
17547         mkdir -p $DIR/$tdir/migrate_dir
17548
17549         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
17550                 error "migration fails with a tailing slash"
17551
17552         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
17553                 error "migration fails with two tailing slashes"
17554 }
17555 run_test 230i "lfs migrate -m tolerates trailing slashes"
17556
17557 test_230j() {
17558         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
17559         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17560                 skip "Need MDS version at least 2.11.52"
17561
17562         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
17563         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
17564                 error "create $tfile failed"
17565         cat /etc/passwd > $DIR/$tdir/$tfile
17566
17567         $LFS migrate -m 1 $DIR/$tdir
17568
17569         cmp /etc/passwd $DIR/$tdir/$tfile ||
17570                 error "DoM file mismatch after migration"
17571 }
17572 run_test 230j "DoM file data not changed after dir migration"
17573
17574 test_230k() {
17575         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
17576         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
17577                 skip "Need MDS version at least 2.11.56"
17578
17579         local total=20
17580         local files_on_starting_mdt=0
17581
17582         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
17583         $LFS getdirstripe $DIR/$tdir
17584         for i in $(seq $total); do
17585                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
17586                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
17587                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
17588         done
17589
17590         echo "$files_on_starting_mdt files on MDT0"
17591
17592         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
17593         $LFS getdirstripe $DIR/$tdir
17594
17595         files_on_starting_mdt=0
17596         for i in $(seq $total); do
17597                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
17598                         error "file $tfile.$i mismatch after migration"
17599                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
17600                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
17601         done
17602
17603         echo "$files_on_starting_mdt files on MDT1 after migration"
17604         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
17605
17606         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
17607         $LFS getdirstripe $DIR/$tdir
17608
17609         files_on_starting_mdt=0
17610         for i in $(seq $total); do
17611                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
17612                         error "file $tfile.$i mismatch after 2nd migration"
17613                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
17614                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
17615         done
17616
17617         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
17618         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
17619
17620         true
17621 }
17622 run_test 230k "file data not changed after dir migration"
17623
17624 test_230l() {
17625         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
17626         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
17627                 skip "Need MDS version at least 2.11.56"
17628
17629         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
17630         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
17631                 error "create files under remote dir failed $i"
17632         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
17633 }
17634 run_test 230l "readdir between MDTs won't crash"
17635
17636 test_230m() {
17637         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
17638         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
17639                 skip "Need MDS version at least 2.11.56"
17640
17641         local MDTIDX=1
17642         local mig_dir=$DIR/$tdir/migrate_dir
17643         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
17644         local shortstr="b"
17645         local val
17646
17647         echo "Creating files and dirs with xattrs"
17648         test_mkdir $DIR/$tdir
17649         test_mkdir -i0 -c1 $mig_dir
17650         mkdir $mig_dir/dir
17651         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
17652                 error "cannot set xattr attr1 on dir"
17653         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
17654                 error "cannot set xattr attr2 on dir"
17655         touch $mig_dir/dir/f0
17656         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
17657                 error "cannot set xattr attr1 on file"
17658         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
17659                 error "cannot set xattr attr2 on file"
17660         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
17661         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
17662         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
17663         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
17664         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
17665         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
17666         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
17667         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
17668         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
17669
17670         echo "Migrating to MDT1"
17671         $LFS migrate -m $MDTIDX $mig_dir ||
17672                 error "fails on migrating dir to MDT1"
17673
17674         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
17675         echo "Checking xattrs"
17676         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
17677         [ "$val" = $longstr ] ||
17678                 error "expecting xattr1 $longstr on dir, found $val"
17679         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
17680         [ "$val" = $shortstr ] ||
17681                 error "expecting xattr2 $shortstr on dir, found $val"
17682         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
17683         [ "$val" = $longstr ] ||
17684                 error "expecting xattr1 $longstr on file, found $val"
17685         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
17686         [ "$val" = $shortstr ] ||
17687                 error "expecting xattr2 $shortstr on file, found $val"
17688 }
17689 run_test 230m "xattrs not changed after dir migration"
17690
17691 test_230n() {
17692         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
17693         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
17694                 skip "Need MDS version at least 2.13.53"
17695
17696         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
17697         cat /etc/hosts > $DIR/$tdir/$tfile
17698         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
17699         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
17700
17701         cmp /etc/hosts $DIR/$tdir/$tfile ||
17702                 error "File data mismatch after migration"
17703 }
17704 run_test 230n "Dir migration with mirrored file"
17705
17706 test_231a()
17707 {
17708         # For simplicity this test assumes that max_pages_per_rpc
17709         # is the same across all OSCs
17710         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
17711         local bulk_size=$((max_pages * PAGE_SIZE))
17712         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
17713                                        head -n 1)
17714
17715         mkdir -p $DIR/$tdir
17716         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
17717                 error "failed to set stripe with -S ${brw_size}M option"
17718
17719         # clear the OSC stats
17720         $LCTL set_param osc.*.stats=0 &>/dev/null
17721         stop_writeback
17722
17723         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
17724         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
17725                 oflag=direct &>/dev/null || error "dd failed"
17726
17727         sync; sleep 1; sync # just to be safe
17728         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
17729         if [ x$nrpcs != "x1" ]; then
17730                 $LCTL get_param osc.*.stats
17731                 error "found $nrpcs ost_write RPCs, not 1 as expected"
17732         fi
17733
17734         start_writeback
17735         # Drop the OSC cache, otherwise we will read from it
17736         cancel_lru_locks osc
17737
17738         # clear the OSC stats
17739         $LCTL set_param osc.*.stats=0 &>/dev/null
17740
17741         # Client reads $bulk_size.
17742         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
17743                 iflag=direct &>/dev/null || error "dd failed"
17744
17745         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
17746         if [ x$nrpcs != "x1" ]; then
17747                 $LCTL get_param osc.*.stats
17748                 error "found $nrpcs ost_read RPCs, not 1 as expected"
17749         fi
17750 }
17751 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
17752
17753 test_231b() {
17754         mkdir -p $DIR/$tdir
17755         local i
17756         for i in {0..1023}; do
17757                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
17758                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
17759                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
17760         done
17761         sync
17762 }
17763 run_test 231b "must not assert on fully utilized OST request buffer"
17764
17765 test_232a() {
17766         mkdir -p $DIR/$tdir
17767         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
17768
17769         #define OBD_FAIL_LDLM_OST_LVB            0x31c
17770         do_facet ost1 $LCTL set_param fail_loc=0x31c
17771
17772         # ignore dd failure
17773         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
17774
17775         do_facet ost1 $LCTL set_param fail_loc=0
17776         umount_client $MOUNT || error "umount failed"
17777         mount_client $MOUNT || error "mount failed"
17778         stop ost1 || error "cannot stop ost1"
17779         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
17780 }
17781 run_test 232a "failed lock should not block umount"
17782
17783 test_232b() {
17784         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
17785                 skip "Need MDS version at least 2.10.58"
17786
17787         mkdir -p $DIR/$tdir
17788         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
17789         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
17790         sync
17791         cancel_lru_locks osc
17792
17793         #define OBD_FAIL_LDLM_OST_LVB            0x31c
17794         do_facet ost1 $LCTL set_param fail_loc=0x31c
17795
17796         # ignore failure
17797         $LFS data_version $DIR/$tdir/$tfile || true
17798
17799         do_facet ost1 $LCTL set_param fail_loc=0
17800         umount_client $MOUNT || error "umount failed"
17801         mount_client $MOUNT || error "mount failed"
17802         stop ost1 || error "cannot stop ost1"
17803         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
17804 }
17805 run_test 232b "failed data version lock should not block umount"
17806
17807 test_233a() {
17808         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
17809                 skip "Need MDS version at least 2.3.64"
17810         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
17811
17812         local fid=$($LFS path2fid $MOUNT)
17813
17814         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
17815                 error "cannot access $MOUNT using its FID '$fid'"
17816 }
17817 run_test 233a "checking that OBF of the FS root succeeds"
17818
17819 test_233b() {
17820         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
17821                 skip "Need MDS version at least 2.5.90"
17822         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
17823
17824         local fid=$($LFS path2fid $MOUNT/.lustre)
17825
17826         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
17827                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
17828
17829         fid=$($LFS path2fid $MOUNT/.lustre/fid)
17830         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
17831                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
17832 }
17833 run_test 233b "checking that OBF of the FS .lustre succeeds"
17834
17835 test_234() {
17836         local p="$TMP/sanityN-$TESTNAME.parameters"
17837         save_lustre_params client "llite.*.xattr_cache" > $p
17838         lctl set_param llite.*.xattr_cache 1 ||
17839                 skip_env "xattr cache is not supported"
17840
17841         mkdir -p $DIR/$tdir || error "mkdir failed"
17842         touch $DIR/$tdir/$tfile || error "touch failed"
17843         # OBD_FAIL_LLITE_XATTR_ENOMEM
17844         $LCTL set_param fail_loc=0x1405
17845         getfattr -n user.attr $DIR/$tdir/$tfile &&
17846                 error "getfattr should have failed with ENOMEM"
17847         $LCTL set_param fail_loc=0x0
17848         rm -rf $DIR/$tdir
17849
17850         restore_lustre_params < $p
17851         rm -f $p
17852 }
17853 run_test 234 "xattr cache should not crash on ENOMEM"
17854
17855 test_235() {
17856         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
17857                 skip "Need MDS version at least 2.4.52"
17858
17859         flock_deadlock $DIR/$tfile
17860         local RC=$?
17861         case $RC in
17862                 0)
17863                 ;;
17864                 124) error "process hangs on a deadlock"
17865                 ;;
17866                 *) error "error executing flock_deadlock $DIR/$tfile"
17867                 ;;
17868         esac
17869 }
17870 run_test 235 "LU-1715: flock deadlock detection does not work properly"
17871
17872 #LU-2935
17873 test_236() {
17874         check_swap_layouts_support
17875
17876         local ref1=/etc/passwd
17877         local ref2=/etc/group
17878         local file1=$DIR/$tdir/f1
17879         local file2=$DIR/$tdir/f2
17880
17881         test_mkdir -c1 $DIR/$tdir
17882         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
17883         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
17884         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
17885         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
17886         local fd=$(free_fd)
17887         local cmd="exec $fd<>$file2"
17888         eval $cmd
17889         rm $file2
17890         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
17891                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
17892         cmd="exec $fd>&-"
17893         eval $cmd
17894         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
17895
17896         #cleanup
17897         rm -rf $DIR/$tdir
17898 }
17899 run_test 236 "Layout swap on open unlinked file"
17900
17901 # LU-4659 linkea consistency
17902 test_238() {
17903         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
17904                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
17905                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
17906                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
17907
17908         touch $DIR/$tfile
17909         ln $DIR/$tfile $DIR/$tfile.lnk
17910         touch $DIR/$tfile.new
17911         mv $DIR/$tfile.new $DIR/$tfile
17912         local fid1=$($LFS path2fid $DIR/$tfile)
17913         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
17914         local path1=$($LFS fid2path $FSNAME "$fid1")
17915         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
17916         local path2=$($LFS fid2path $FSNAME "$fid2")
17917         [ $tfile.lnk == $path2 ] ||
17918                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
17919         rm -f $DIR/$tfile*
17920 }
17921 run_test 238 "Verify linkea consistency"
17922
17923 test_239A() { # was test_239
17924         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
17925                 skip "Need MDS version at least 2.5.60"
17926
17927         local list=$(comma_list $(mdts_nodes))
17928
17929         mkdir -p $DIR/$tdir
17930         createmany -o $DIR/$tdir/f- 5000
17931         unlinkmany $DIR/$tdir/f- 5000
17932         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
17933                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
17934         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
17935                         osp.*MDT*.sync_in_flight" | calc_sum)
17936         [ "$changes" -eq 0 ] || error "$changes not synced"
17937 }
17938 run_test 239A "osp_sync test"
17939
17940 test_239a() { #LU-5297
17941         remote_mds_nodsh && skip "remote MDS with nodsh"
17942
17943         touch $DIR/$tfile
17944         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
17945         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
17946         chgrp $RUNAS_GID $DIR/$tfile
17947         wait_delete_completed
17948 }
17949 run_test 239a "process invalid osp sync record correctly"
17950
17951 test_239b() { #LU-5297
17952         remote_mds_nodsh && skip "remote MDS with nodsh"
17953
17954         touch $DIR/$tfile1
17955         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
17956         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
17957         chgrp $RUNAS_GID $DIR/$tfile1
17958         wait_delete_completed
17959         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
17960         touch $DIR/$tfile2
17961         chgrp $RUNAS_GID $DIR/$tfile2
17962         wait_delete_completed
17963 }
17964 run_test 239b "process osp sync record with ENOMEM error correctly"
17965
17966 test_240() {
17967         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17968         remote_mds_nodsh && skip "remote MDS with nodsh"
17969
17970         mkdir -p $DIR/$tdir
17971
17972         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
17973                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
17974         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
17975                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
17976
17977         umount_client $MOUNT || error "umount failed"
17978         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
17979         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
17980         mount_client $MOUNT || error "failed to mount client"
17981
17982         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
17983         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
17984 }
17985 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
17986
17987 test_241_bio() {
17988         local count=$1
17989         local bsize=$2
17990
17991         for LOOP in $(seq $count); do
17992                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
17993                 cancel_lru_locks $OSC || true
17994         done
17995 }
17996
17997 test_241_dio() {
17998         local count=$1
17999         local bsize=$2
18000
18001         for LOOP in $(seq $1); do
18002                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
18003                         2>/dev/null
18004         done
18005 }
18006
18007 test_241a() { # was test_241
18008         local bsize=$PAGE_SIZE
18009
18010         (( bsize < 40960 )) && bsize=40960
18011         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
18012         ls -la $DIR/$tfile
18013         cancel_lru_locks $OSC
18014         test_241_bio 1000 $bsize &
18015         PID=$!
18016         test_241_dio 1000 $bsize
18017         wait $PID
18018 }
18019 run_test 241a "bio vs dio"
18020
18021 test_241b() {
18022         local bsize=$PAGE_SIZE
18023
18024         (( bsize < 40960 )) && bsize=40960
18025         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
18026         ls -la $DIR/$tfile
18027         test_241_dio 1000 $bsize &
18028         PID=$!
18029         test_241_dio 1000 $bsize
18030         wait $PID
18031 }
18032 run_test 241b "dio vs dio"
18033
18034 test_242() {
18035         remote_mds_nodsh && skip "remote MDS with nodsh"
18036
18037         mkdir -p $DIR/$tdir
18038         touch $DIR/$tdir/$tfile
18039
18040         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
18041         do_facet mds1 lctl set_param fail_loc=0x105
18042         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
18043
18044         do_facet mds1 lctl set_param fail_loc=0
18045         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
18046 }
18047 run_test 242 "mdt_readpage failure should not cause directory unreadable"
18048
18049 test_243()
18050 {
18051         test_mkdir $DIR/$tdir
18052         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
18053 }
18054 run_test 243 "various group lock tests"
18055
18056 test_244a()
18057 {
18058         test_mkdir $DIR/$tdir
18059         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
18060         sendfile_grouplock $DIR/$tdir/$tfile || \
18061                 error "sendfile+grouplock failed"
18062         rm -rf $DIR/$tdir
18063 }
18064 run_test 244a "sendfile with group lock tests"
18065
18066 test_244b()
18067 {
18068         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
18069
18070         local threads=50
18071         local size=$((1024*1024))
18072
18073         test_mkdir $DIR/$tdir
18074         for i in $(seq 1 $threads); do
18075                 local file=$DIR/$tdir/file_$((i / 10))
18076                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
18077                 local pids[$i]=$!
18078         done
18079         for i in $(seq 1 $threads); do
18080                 wait ${pids[$i]}
18081         done
18082 }
18083 run_test 244b "multi-threaded write with group lock"
18084
18085 test_245() {
18086         local flagname="multi_mod_rpcs"
18087         local connect_data_name="max_mod_rpcs"
18088         local out
18089
18090         # check if multiple modify RPCs flag is set
18091         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
18092                 grep "connect_flags:")
18093         echo "$out"
18094
18095         echo "$out" | grep -qw $flagname
18096         if [ $? -ne 0 ]; then
18097                 echo "connect flag $flagname is not set"
18098                 return
18099         fi
18100
18101         # check if multiple modify RPCs data is set
18102         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
18103         echo "$out"
18104
18105         echo "$out" | grep -qw $connect_data_name ||
18106                 error "import should have connect data $connect_data_name"
18107 }
18108 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
18109
18110 cleanup_247() {
18111         local submount=$1
18112
18113         trap 0
18114         umount_client $submount
18115         rmdir $submount
18116 }
18117
18118 test_247a() {
18119         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
18120                 grep -q subtree ||
18121                 skip_env "Fileset feature is not supported"
18122
18123         local submount=${MOUNT}_$tdir
18124
18125         mkdir $MOUNT/$tdir
18126         mkdir -p $submount || error "mkdir $submount failed"
18127         FILESET="$FILESET/$tdir" mount_client $submount ||
18128                 error "mount $submount failed"
18129         trap "cleanup_247 $submount" EXIT
18130         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
18131         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
18132                 error "read $MOUNT/$tdir/$tfile failed"
18133         cleanup_247 $submount
18134 }
18135 run_test 247a "mount subdir as fileset"
18136
18137 test_247b() {
18138         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18139                 skip_env "Fileset feature is not supported"
18140
18141         local submount=${MOUNT}_$tdir
18142
18143         rm -rf $MOUNT/$tdir
18144         mkdir -p $submount || error "mkdir $submount failed"
18145         SKIP_FILESET=1
18146         FILESET="$FILESET/$tdir" mount_client $submount &&
18147                 error "mount $submount should fail"
18148         rmdir $submount
18149 }
18150 run_test 247b "mount subdir that dose not exist"
18151
18152 test_247c() {
18153         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18154                 skip_env "Fileset feature is not supported"
18155
18156         local submount=${MOUNT}_$tdir
18157
18158         mkdir -p $MOUNT/$tdir/dir1
18159         mkdir -p $submount || error "mkdir $submount failed"
18160         trap "cleanup_247 $submount" EXIT
18161         FILESET="$FILESET/$tdir" mount_client $submount ||
18162                 error "mount $submount failed"
18163         local fid=$($LFS path2fid $MOUNT/)
18164         $LFS fid2path $submount $fid && error "fid2path should fail"
18165         cleanup_247 $submount
18166 }
18167 run_test 247c "running fid2path outside root"
18168
18169 test_247d() {
18170         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18171                 skip "Fileset feature is not supported"
18172
18173         local submount=${MOUNT}_$tdir
18174
18175         mkdir -p $MOUNT/$tdir/dir1
18176         mkdir -p $submount || error "mkdir $submount failed"
18177         FILESET="$FILESET/$tdir" mount_client $submount ||
18178                 error "mount $submount failed"
18179         trap "cleanup_247 $submount" EXIT
18180         local fid=$($LFS path2fid $submount/dir1)
18181         $LFS fid2path $submount $fid || error "fid2path should succeed"
18182         cleanup_247 $submount
18183 }
18184 run_test 247d "running fid2path inside root"
18185
18186 # LU-8037
18187 test_247e() {
18188         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
18189                 grep -q subtree ||
18190                 skip "Fileset feature is not supported"
18191
18192         local submount=${MOUNT}_$tdir
18193
18194         mkdir $MOUNT/$tdir
18195         mkdir -p $submount || error "mkdir $submount failed"
18196         FILESET="$FILESET/.." mount_client $submount &&
18197                 error "mount $submount should fail"
18198         rmdir $submount
18199 }
18200 run_test 247e "mount .. as fileset"
18201
18202 test_248a() {
18203         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
18204         [ -z "$fast_read_sav" ] && skip "no fast read support"
18205
18206         # create a large file for fast read verification
18207         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
18208
18209         # make sure the file is created correctly
18210         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
18211                 { rm -f $DIR/$tfile; skip "file creation error"; }
18212
18213         echo "Test 1: verify that fast read is 4 times faster on cache read"
18214
18215         # small read with fast read enabled
18216         $LCTL set_param -n llite.*.fast_read=1
18217         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
18218                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
18219                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
18220         # small read with fast read disabled
18221         $LCTL set_param -n llite.*.fast_read=0
18222         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
18223                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
18224                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
18225
18226         # verify that fast read is 4 times faster for cache read
18227         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
18228                 error_not_in_vm "fast read was not 4 times faster: " \
18229                            "$t_fast vs $t_slow"
18230
18231         echo "Test 2: verify the performance between big and small read"
18232         $LCTL set_param -n llite.*.fast_read=1
18233
18234         # 1k non-cache read
18235         cancel_lru_locks osc
18236         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
18237                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
18238                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
18239
18240         # 1M non-cache read
18241         cancel_lru_locks osc
18242         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
18243                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
18244                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
18245
18246         # verify that big IO is not 4 times faster than small IO
18247         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
18248                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
18249
18250         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
18251         rm -f $DIR/$tfile
18252 }
18253 run_test 248a "fast read verification"
18254
18255 test_248b() {
18256         # Default short_io_bytes=16384, try both smaller and larger sizes.
18257         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
18258         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
18259         echo "bs=53248 count=113 normal buffered write"
18260         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
18261                 error "dd of initial data file failed"
18262         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
18263
18264         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
18265         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
18266                 error "dd with sync normal writes failed"
18267         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
18268
18269         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
18270         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
18271                 error "dd with sync small writes failed"
18272         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
18273
18274         cancel_lru_locks osc
18275
18276         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
18277         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
18278         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
18279         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
18280                 iflag=direct || error "dd with O_DIRECT small read failed"
18281         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
18282         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
18283                 error "compare $TMP/$tfile.1 failed"
18284
18285         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
18286         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
18287
18288         # just to see what the maximum tunable value is, and test parsing
18289         echo "test invalid parameter 2MB"
18290         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
18291                 error "too-large short_io_bytes allowed"
18292         echo "test maximum parameter 512KB"
18293         # if we can set a larger short_io_bytes, run test regardless of version
18294         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
18295                 # older clients may not allow setting it this large, that's OK
18296                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
18297                         skip "Need at least client version 2.13.50"
18298                 error "medium short_io_bytes failed"
18299         fi
18300         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
18301         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
18302
18303         echo "test large parameter 64KB"
18304         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
18305         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
18306
18307         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
18308         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
18309                 error "dd with sync large writes failed"
18310         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
18311
18312         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
18313         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
18314         num=$((113 * 4096 / PAGE_SIZE))
18315         echo "bs=$size count=$num oflag=direct large write $tfile.3"
18316         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
18317                 error "dd with O_DIRECT large writes failed"
18318         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
18319                 error "compare $DIR/$tfile.3 failed"
18320
18321         cancel_lru_locks osc
18322
18323         echo "bs=$size count=$num iflag=direct large read $tfile.2"
18324         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
18325                 error "dd with O_DIRECT large read failed"
18326         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
18327                 error "compare $TMP/$tfile.2 failed"
18328
18329         echo "bs=$size count=$num iflag=direct large read $tfile.3"
18330         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
18331                 error "dd with O_DIRECT large read failed"
18332         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
18333                 error "compare $TMP/$tfile.3 failed"
18334 }
18335 run_test 248b "test short_io read and write for both small and large sizes"
18336
18337 test_249() { # LU-7890
18338         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
18339                 skip "Need at least version 2.8.54"
18340
18341         rm -f $DIR/$tfile
18342         $LFS setstripe -c 1 $DIR/$tfile
18343         # Offset 2T == 4k * 512M
18344         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
18345                 error "dd to 2T offset failed"
18346 }
18347 run_test 249 "Write above 2T file size"
18348
18349 test_250() {
18350         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
18351          && skip "no 16TB file size limit on ZFS"
18352
18353         $LFS setstripe -c 1 $DIR/$tfile
18354         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
18355         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
18356         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
18357         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
18358                 conv=notrunc,fsync && error "append succeeded"
18359         return 0
18360 }
18361 run_test 250 "Write above 16T limit"
18362
18363 test_251() {
18364         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
18365
18366         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
18367         #Skip once - writing the first stripe will succeed
18368         $LCTL set_param fail_loc=0xa0001407 fail_val=1
18369         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
18370                 error "short write happened"
18371
18372         $LCTL set_param fail_loc=0xa0001407 fail_val=1
18373         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
18374                 error "short read happened"
18375
18376         rm -f $DIR/$tfile
18377 }
18378 run_test 251 "Handling short read and write correctly"
18379
18380 test_252() {
18381         remote_mds_nodsh && skip "remote MDS with nodsh"
18382         remote_ost_nodsh && skip "remote OST with nodsh"
18383         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
18384                 skip_env "ldiskfs only test"
18385         fi
18386
18387         local tgt
18388         local dev
18389         local out
18390         local uuid
18391         local num
18392         local gen
18393
18394         # check lr_reader on OST0000
18395         tgt=ost1
18396         dev=$(facet_device $tgt)
18397         out=$(do_facet $tgt $LR_READER $dev)
18398         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
18399         echo "$out"
18400         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
18401         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
18402                 error "Invalid uuid returned by $LR_READER on target $tgt"
18403         echo -e "uuid returned by $LR_READER is '$uuid'\n"
18404
18405         # check lr_reader -c on MDT0000
18406         tgt=mds1
18407         dev=$(facet_device $tgt)
18408         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
18409                 skip "$LR_READER does not support additional options"
18410         fi
18411         out=$(do_facet $tgt $LR_READER -c $dev)
18412         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
18413         echo "$out"
18414         num=$(echo "$out" | grep -c "mdtlov")
18415         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
18416                 error "Invalid number of mdtlov clients returned by $LR_READER"
18417         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
18418
18419         # check lr_reader -cr on MDT0000
18420         out=$(do_facet $tgt $LR_READER -cr $dev)
18421         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
18422         echo "$out"
18423         echo "$out" | grep -q "^reply_data:$" ||
18424                 error "$LR_READER should have returned 'reply_data' section"
18425         num=$(echo "$out" | grep -c "client_generation")
18426         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
18427 }
18428 run_test 252 "check lr_reader tool"
18429
18430 test_253() {
18431         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18432         remote_mds_nodsh && skip "remote MDS with nodsh"
18433         remote_mgs_nodsh && skip "remote MGS with nodsh"
18434
18435         local ostidx=0
18436         local rc=0
18437         local ost_name=$(ostname_from_index $ostidx)
18438
18439         # on the mdt's osc
18440         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
18441         do_facet $SINGLEMDS $LCTL get_param -n \
18442                 osp.$mdtosc_proc1.reserved_mb_high ||
18443                 skip  "remote MDS does not support reserved_mb_high"
18444
18445         rm -rf $DIR/$tdir
18446         wait_mds_ost_sync
18447         wait_delete_completed
18448         mkdir $DIR/$tdir
18449
18450         pool_add $TESTNAME || error "Pool creation failed"
18451         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
18452
18453         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
18454                 error "Setstripe failed"
18455
18456         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
18457
18458         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
18459                     grep "watermarks")
18460         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
18461
18462         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
18463                         osp.$mdtosc_proc1.prealloc_status)
18464         echo "prealloc_status $oa_status"
18465
18466         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
18467                 error "File creation should fail"
18468
18469         #object allocation was stopped, but we still able to append files
18470         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
18471                 oflag=append || error "Append failed"
18472
18473         rm -f $DIR/$tdir/$tfile.0
18474
18475         # For this test, we want to delete the files we created to go out of
18476         # space but leave the watermark, so we remain nearly out of space
18477         ost_watermarks_enospc_delete_files $tfile $ostidx
18478
18479         wait_delete_completed
18480
18481         sleep_maxage
18482
18483         for i in $(seq 10 12); do
18484                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
18485                         2>/dev/null || error "File creation failed after rm"
18486         done
18487
18488         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
18489                         osp.$mdtosc_proc1.prealloc_status)
18490         echo "prealloc_status $oa_status"
18491
18492         if (( oa_status != 0 )); then
18493                 error "Object allocation still disable after rm"
18494         fi
18495 }
18496 run_test 253 "Check object allocation limit"
18497
18498 test_254() {
18499         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18500         remote_mds_nodsh && skip "remote MDS with nodsh"
18501         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
18502                 skip "MDS does not support changelog_size"
18503
18504         local cl_user
18505         local MDT0=$(facet_svc $SINGLEMDS)
18506
18507         changelog_register || error "changelog_register failed"
18508
18509         changelog_clear 0 || error "changelog_clear failed"
18510
18511         local size1=$(do_facet $SINGLEMDS \
18512                       $LCTL get_param -n mdd.$MDT0.changelog_size)
18513         echo "Changelog size $size1"
18514
18515         rm -rf $DIR/$tdir
18516         $LFS mkdir -i 0 $DIR/$tdir
18517         # change something
18518         mkdir -p $DIR/$tdir/pics/2008/zachy
18519         touch $DIR/$tdir/pics/2008/zachy/timestamp
18520         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
18521         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
18522         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
18523         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
18524         rm $DIR/$tdir/pics/desktop.jpg
18525
18526         local size2=$(do_facet $SINGLEMDS \
18527                       $LCTL get_param -n mdd.$MDT0.changelog_size)
18528         echo "Changelog size after work $size2"
18529
18530         (( $size2 > $size1 )) ||
18531                 error "new Changelog size=$size2 less than old size=$size1"
18532 }
18533 run_test 254 "Check changelog size"
18534
18535 ladvise_no_type()
18536 {
18537         local type=$1
18538         local file=$2
18539
18540         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
18541                 awk -F: '{print $2}' | grep $type > /dev/null
18542         if [ $? -ne 0 ]; then
18543                 return 0
18544         fi
18545         return 1
18546 }
18547
18548 ladvise_no_ioctl()
18549 {
18550         local file=$1
18551
18552         lfs ladvise -a willread $file > /dev/null 2>&1
18553         if [ $? -eq 0 ]; then
18554                 return 1
18555         fi
18556
18557         lfs ladvise -a willread $file 2>&1 |
18558                 grep "Inappropriate ioctl for device" > /dev/null
18559         if [ $? -eq 0 ]; then
18560                 return 0
18561         fi
18562         return 1
18563 }
18564
18565 percent() {
18566         bc <<<"scale=2; ($1 - $2) * 100 / $2"
18567 }
18568
18569 # run a random read IO workload
18570 # usage: random_read_iops <filename> <filesize> <iosize>
18571 random_read_iops() {
18572         local file=$1
18573         local fsize=$2
18574         local iosize=${3:-4096}
18575
18576         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
18577                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
18578 }
18579
18580 drop_file_oss_cache() {
18581         local file="$1"
18582         local nodes="$2"
18583
18584         $LFS ladvise -a dontneed $file 2>/dev/null ||
18585                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
18586 }
18587
18588 ladvise_willread_performance()
18589 {
18590         local repeat=10
18591         local average_origin=0
18592         local average_cache=0
18593         local average_ladvise=0
18594
18595         for ((i = 1; i <= $repeat; i++)); do
18596                 echo "Iter $i/$repeat: reading without willread hint"
18597                 cancel_lru_locks osc
18598                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
18599                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
18600                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
18601                 average_origin=$(bc <<<"$average_origin + $speed_origin")
18602
18603                 cancel_lru_locks osc
18604                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
18605                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
18606                 average_cache=$(bc <<<"$average_cache + $speed_cache")
18607
18608                 cancel_lru_locks osc
18609                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
18610                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
18611                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
18612                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
18613                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
18614         done
18615         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
18616         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
18617         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
18618
18619         speedup_cache=$(percent $average_cache $average_origin)
18620         speedup_ladvise=$(percent $average_ladvise $average_origin)
18621
18622         echo "Average uncached read: $average_origin"
18623         echo "Average speedup with OSS cached read: " \
18624                 "$average_cache = +$speedup_cache%"
18625         echo "Average speedup with ladvise willread: " \
18626                 "$average_ladvise = +$speedup_ladvise%"
18627
18628         local lowest_speedup=20
18629         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
18630                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
18631                         "got $average_cache%. Skipping ladvise willread check."
18632                 return 0
18633         fi
18634
18635         # the test won't work on ZFS until it supports 'ladvise dontneed', but
18636         # it is still good to run until then to exercise 'ladvise willread'
18637         ! $LFS ladvise -a dontneed $DIR/$tfile &&
18638                 [ "$ost1_FSTYPE" = "zfs" ] &&
18639                 echo "osd-zfs does not support dontneed or drop_caches" &&
18640                 return 0
18641
18642         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
18643         [ ${average_ladvise%.*} -gt $lowest_speedup ] ||
18644                 error_not_in_vm "Speedup with willread is less than " \
18645                         "$lowest_speedup%, got $average_ladvise%"
18646 }
18647
18648 test_255a() {
18649         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
18650                 skip "lustre < 2.8.54 does not support ladvise "
18651         remote_ost_nodsh && skip "remote OST with nodsh"
18652
18653         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
18654
18655         ladvise_no_type willread $DIR/$tfile &&
18656                 skip "willread ladvise is not supported"
18657
18658         ladvise_no_ioctl $DIR/$tfile &&
18659                 skip "ladvise ioctl is not supported"
18660
18661         local size_mb=100
18662         local size=$((size_mb * 1048576))
18663         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
18664                 error "dd to $DIR/$tfile failed"
18665
18666         lfs ladvise -a willread $DIR/$tfile ||
18667                 error "Ladvise failed with no range argument"
18668
18669         lfs ladvise -a willread -s 0 $DIR/$tfile ||
18670                 error "Ladvise failed with no -l or -e argument"
18671
18672         lfs ladvise -a willread -e 1 $DIR/$tfile ||
18673                 error "Ladvise failed with only -e argument"
18674
18675         lfs ladvise -a willread -l 1 $DIR/$tfile ||
18676                 error "Ladvise failed with only -l argument"
18677
18678         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
18679                 error "End offset should not be smaller than start offset"
18680
18681         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
18682                 error "End offset should not be equal to start offset"
18683
18684         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
18685                 error "Ladvise failed with overflowing -s argument"
18686
18687         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
18688                 error "Ladvise failed with overflowing -e argument"
18689
18690         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
18691                 error "Ladvise failed with overflowing -l argument"
18692
18693         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
18694                 error "Ladvise succeeded with conflicting -l and -e arguments"
18695
18696         echo "Synchronous ladvise should wait"
18697         local delay=4
18698 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
18699         do_nodes $(comma_list $(osts_nodes)) \
18700                 $LCTL set_param fail_val=$delay fail_loc=0x237
18701
18702         local start_ts=$SECONDS
18703         lfs ladvise -a willread $DIR/$tfile ||
18704                 error "Ladvise failed with no range argument"
18705         local end_ts=$SECONDS
18706         local inteval_ts=$((end_ts - start_ts))
18707
18708         if [ $inteval_ts -lt $(($delay - 1)) ]; then
18709                 error "Synchronous advice didn't wait reply"
18710         fi
18711
18712         echo "Asynchronous ladvise shouldn't wait"
18713         local start_ts=$SECONDS
18714         lfs ladvise -a willread -b $DIR/$tfile ||
18715                 error "Ladvise failed with no range argument"
18716         local end_ts=$SECONDS
18717         local inteval_ts=$((end_ts - start_ts))
18718
18719         if [ $inteval_ts -gt $(($delay / 2)) ]; then
18720                 error "Asynchronous advice blocked"
18721         fi
18722
18723         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
18724         ladvise_willread_performance
18725 }
18726 run_test 255a "check 'lfs ladvise -a willread'"
18727
18728 facet_meminfo() {
18729         local facet=$1
18730         local info=$2
18731
18732         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
18733 }
18734
18735 test_255b() {
18736         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
18737                 skip "lustre < 2.8.54 does not support ladvise "
18738         remote_ost_nodsh && skip "remote OST with nodsh"
18739
18740         lfs setstripe -c 1 -i 0 $DIR/$tfile
18741
18742         ladvise_no_type dontneed $DIR/$tfile &&
18743                 skip "dontneed ladvise is not supported"
18744
18745         ladvise_no_ioctl $DIR/$tfile &&
18746                 skip "ladvise ioctl is not supported"
18747
18748         ! $LFS ladvise -a dontneed $DIR/$tfile &&
18749                 [ "$ost1_FSTYPE" = "zfs" ] &&
18750                 skip "zfs-osd does not support 'ladvise dontneed'"
18751
18752         local size_mb=100
18753         local size=$((size_mb * 1048576))
18754         # In order to prevent disturbance of other processes, only check 3/4
18755         # of the memory usage
18756         local kibibytes=$((size_mb * 1024 * 3 / 4))
18757
18758         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
18759                 error "dd to $DIR/$tfile failed"
18760
18761         #force write to complete before dropping OST cache & checking memory
18762         sync
18763
18764         local total=$(facet_meminfo ost1 MemTotal)
18765         echo "Total memory: $total KiB"
18766
18767         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
18768         local before_read=$(facet_meminfo ost1 Cached)
18769         echo "Cache used before read: $before_read KiB"
18770
18771         lfs ladvise -a willread $DIR/$tfile ||
18772                 error "Ladvise willread failed"
18773         local after_read=$(facet_meminfo ost1 Cached)
18774         echo "Cache used after read: $after_read KiB"
18775
18776         lfs ladvise -a dontneed $DIR/$tfile ||
18777                 error "Ladvise dontneed again failed"
18778         local no_read=$(facet_meminfo ost1 Cached)
18779         echo "Cache used after dontneed ladvise: $no_read KiB"
18780
18781         if [ $total -lt $((before_read + kibibytes)) ]; then
18782                 echo "Memory is too small, abort checking"
18783                 return 0
18784         fi
18785
18786         if [ $((before_read + kibibytes)) -gt $after_read ]; then
18787                 error "Ladvise willread should use more memory" \
18788                         "than $kibibytes KiB"
18789         fi
18790
18791         if [ $((no_read + kibibytes)) -gt $after_read ]; then
18792                 error "Ladvise dontneed should release more memory" \
18793                         "than $kibibytes KiB"
18794         fi
18795 }
18796 run_test 255b "check 'lfs ladvise -a dontneed'"
18797
18798 test_255c() {
18799         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
18800                 skip "lustre < 2.10.50 does not support lockahead"
18801
18802         local count
18803         local new_count
18804         local difference
18805         local i
18806         local rc
18807
18808         test_mkdir -p $DIR/$tdir
18809         $LFS setstripe -i 0 -c 1 $DIR/$tdir
18810
18811         #test 10 returns only success/failure
18812         i=10
18813         lockahead_test -d $DIR/$tdir -t $i -f $tfile
18814         rc=$?
18815         if [ $rc -eq 255 ]; then
18816                 error "Ladvise test${i} failed, ${rc}"
18817         fi
18818
18819         #test 11 counts lock enqueue requests, all others count new locks
18820         i=11
18821         count=$(do_facet ost1 \
18822                 $LCTL get_param -n ost.OSS.ost.stats)
18823         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
18824
18825         lockahead_test -d $DIR/$tdir -t $i -f $tfile
18826         rc=$?
18827         if [ $rc -eq 255 ]; then
18828                 error "Ladvise test${i} failed, ${rc}"
18829         fi
18830
18831         new_count=$(do_facet ost1 \
18832                 $LCTL get_param -n ost.OSS.ost.stats)
18833         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
18834                    awk '{ print $2 }')
18835
18836         difference="$((new_count - count))"
18837         if [ $difference -ne $rc ]; then
18838                 error "Ladvise test${i}, bad enqueue count, returned " \
18839                       "${rc}, actual ${difference}"
18840         fi
18841
18842         for i in $(seq 12 21); do
18843                 # If we do not do this, we run the risk of having too many
18844                 # locks and starting lock cancellation while we are checking
18845                 # lock counts.
18846                 cancel_lru_locks osc
18847
18848                 count=$($LCTL get_param -n \
18849                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
18850
18851                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
18852                 rc=$?
18853                 if [ $rc -eq 255 ]; then
18854                         error "Ladvise test ${i} failed, ${rc}"
18855                 fi
18856
18857                 new_count=$($LCTL get_param -n \
18858                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
18859                 difference="$((new_count - count))"
18860
18861                 # Test 15 output is divided by 100 to map down to valid return
18862                 if [ $i -eq 15 ]; then
18863                         rc="$((rc * 100))"
18864                 fi
18865
18866                 if [ $difference -ne $rc ]; then
18867                         error "Ladvise test ${i}, bad lock count, returned " \
18868                               "${rc}, actual ${difference}"
18869                 fi
18870         done
18871
18872         #test 22 returns only success/failure
18873         i=22
18874         lockahead_test -d $DIR/$tdir -t $i -f $tfile
18875         rc=$?
18876         if [ $rc -eq 255 ]; then
18877                 error "Ladvise test${i} failed, ${rc}"
18878         fi
18879 }
18880 run_test 255c "suite of ladvise lockahead tests"
18881
18882 test_256() {
18883         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18884         remote_mds_nodsh && skip "remote MDS with nodsh"
18885         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
18886         changelog_users $SINGLEMDS | grep "^cl" &&
18887                 skip "active changelog user"
18888
18889         local cl_user
18890         local cat_sl
18891         local mdt_dev
18892
18893         mdt_dev=$(mdsdevname 1)
18894         echo $mdt_dev
18895
18896         changelog_register || error "changelog_register failed"
18897
18898         rm -rf $DIR/$tdir
18899         mkdir -p $DIR/$tdir
18900
18901         changelog_clear 0 || error "changelog_clear failed"
18902
18903         # change something
18904         touch $DIR/$tdir/{1..10}
18905
18906         # stop the MDT
18907         stop $SINGLEMDS || error "Fail to stop MDT"
18908
18909         # remount the MDT
18910
18911         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
18912
18913         #after mount new plainllog is used
18914         touch $DIR/$tdir/{11..19}
18915         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
18916         stack_trap "rm -f $tmpfile"
18917         cat_sl=$(do_facet $SINGLEMDS "sync; \
18918                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
18919                  llog_reader $tmpfile | grep -c type=1064553b")
18920         do_facet $SINGLEMDS llog_reader $tmpfile
18921
18922         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
18923
18924         changelog_clear 0 || error "changelog_clear failed"
18925
18926         cat_sl=$(do_facet $SINGLEMDS "sync; \
18927                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
18928                  llog_reader $tmpfile | grep -c type=1064553b")
18929
18930         if (( cat_sl == 2 )); then
18931                 error "Empty plain llog was not deleted from changelog catalog"
18932         elif (( cat_sl != 1 )); then
18933                 error "Active plain llog shouldn't be deleted from catalog"
18934         fi
18935 }
18936 run_test 256 "Check llog delete for empty and not full state"
18937
18938 test_257() {
18939         remote_mds_nodsh && skip "remote MDS with nodsh"
18940         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
18941                 skip "Need MDS version at least 2.8.55"
18942
18943         test_mkdir $DIR/$tdir
18944
18945         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
18946                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
18947         stat $DIR/$tdir
18948
18949 #define OBD_FAIL_MDS_XATTR_REP                  0x161
18950         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
18951         local facet=mds$((mdtidx + 1))
18952         set_nodes_failloc $(facet_active_host $facet) 0x80000161
18953         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
18954
18955         stop $facet || error "stop MDS failed"
18956         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
18957                 error "start MDS fail"
18958         wait_recovery_complete $facet
18959 }
18960 run_test 257 "xattr locks are not lost"
18961
18962 # Verify we take the i_mutex when security requires it
18963 test_258a() {
18964 #define OBD_FAIL_IMUTEX_SEC 0x141c
18965         $LCTL set_param fail_loc=0x141c
18966         touch $DIR/$tfile
18967         chmod u+s $DIR/$tfile
18968         chmod a+rwx $DIR/$tfile
18969         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
18970         RC=$?
18971         if [ $RC -ne 0 ]; then
18972                 error "error, failed to take i_mutex, rc=$?"
18973         fi
18974         rm -f $DIR/$tfile
18975 }
18976 run_test 258a "verify i_mutex security behavior when suid attributes is set"
18977
18978 # Verify we do NOT take the i_mutex in the normal case
18979 test_258b() {
18980 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
18981         $LCTL set_param fail_loc=0x141d
18982         touch $DIR/$tfile
18983         chmod a+rwx $DIR
18984         chmod a+rw $DIR/$tfile
18985         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
18986         RC=$?
18987         if [ $RC -ne 0 ]; then
18988                 error "error, took i_mutex unnecessarily, rc=$?"
18989         fi
18990         rm -f $DIR/$tfile
18991
18992 }
18993 run_test 258b "verify i_mutex security behavior"
18994
18995 test_259() {
18996         local file=$DIR/$tfile
18997         local before
18998         local after
18999
19000         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
19001
19002         stack_trap "rm -f $file" EXIT
19003
19004         wait_delete_completed
19005         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19006         echo "before: $before"
19007
19008         $LFS setstripe -i 0 -c 1 $file
19009         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
19010         sync_all_data
19011         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19012         echo "after write: $after"
19013
19014 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
19015         do_facet ost1 $LCTL set_param fail_loc=0x2301
19016         $TRUNCATE $file 0
19017         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19018         echo "after truncate: $after"
19019
19020         stop ost1
19021         do_facet ost1 $LCTL set_param fail_loc=0
19022         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19023         sleep 2
19024         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19025         echo "after restart: $after"
19026         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
19027                 error "missing truncate?"
19028
19029         return 0
19030 }
19031 run_test 259 "crash at delayed truncate"
19032
19033 test_260() {
19034 #define OBD_FAIL_MDC_CLOSE               0x806
19035         $LCTL set_param fail_loc=0x80000806
19036         touch $DIR/$tfile
19037
19038 }
19039 run_test 260 "Check mdc_close fail"
19040
19041 ### Data-on-MDT sanity tests ###
19042 test_270a() {
19043         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19044                 skip "Need MDS version at least 2.10.55 for DoM"
19045
19046         # create DoM file
19047         local dom=$DIR/$tdir/dom_file
19048         local tmp=$DIR/$tdir/tmp_file
19049
19050         mkdir -p $DIR/$tdir
19051
19052         # basic checks for DoM component creation
19053         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
19054                 error "Can set MDT layout to non-first entry"
19055
19056         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
19057                 error "Can define multiple entries as MDT layout"
19058
19059         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
19060
19061         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
19062         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
19063         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
19064
19065         local mdtidx=$($LFS getstripe -m $dom)
19066         local mdtname=MDT$(printf %04x $mdtidx)
19067         local facet=mds$((mdtidx + 1))
19068         local space_check=1
19069
19070         # Skip free space checks with ZFS
19071         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
19072
19073         # write
19074         sync
19075         local size_tmp=$((65536 * 3))
19076         local mdtfree1=$(do_facet $facet \
19077                          lctl get_param -n osd*.*$mdtname.kbytesfree)
19078
19079         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
19080         # check also direct IO along write
19081         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
19082         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
19083         sync
19084         cmp $tmp $dom || error "file data is different"
19085         [ $(stat -c%s $dom) == $size_tmp ] ||
19086                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
19087         if [ $space_check == 1 ]; then
19088                 local mdtfree2=$(do_facet $facet \
19089                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
19090
19091                 # increase in usage from by $size_tmp
19092                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
19093                         error "MDT free space wrong after write: " \
19094                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
19095         fi
19096
19097         # truncate
19098         local size_dom=10000
19099
19100         $TRUNCATE $dom $size_dom
19101         [ $(stat -c%s $dom) == $size_dom ] ||
19102                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
19103         if [ $space_check == 1 ]; then
19104                 mdtfree1=$(do_facet $facet \
19105                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19106                 # decrease in usage from $size_tmp to new $size_dom
19107                 [ $(($mdtfree1 - $mdtfree2)) -ge \
19108                   $(((size_tmp - size_dom) / 1024)) ] ||
19109                         error "MDT free space is wrong after truncate: " \
19110                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
19111         fi
19112
19113         # append
19114         cat $tmp >> $dom
19115         sync
19116         size_dom=$((size_dom + size_tmp))
19117         [ $(stat -c%s $dom) == $size_dom ] ||
19118                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
19119         if [ $space_check == 1 ]; then
19120                 mdtfree2=$(do_facet $facet \
19121                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19122                 # increase in usage by $size_tmp from previous
19123                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
19124                         error "MDT free space is wrong after append: " \
19125                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
19126         fi
19127
19128         # delete
19129         rm $dom
19130         if [ $space_check == 1 ]; then
19131                 mdtfree1=$(do_facet $facet \
19132                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19133                 # decrease in usage by $size_dom from previous
19134                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
19135                         error "MDT free space is wrong after removal: " \
19136                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
19137         fi
19138
19139         # combined striping
19140         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
19141                 error "Can't create DoM + OST striping"
19142
19143         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
19144         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
19145         # check also direct IO along write
19146         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
19147         sync
19148         cmp $tmp $dom || error "file data is different"
19149         [ $(stat -c%s $dom) == $size_tmp ] ||
19150                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
19151         rm $dom $tmp
19152
19153         return 0
19154 }
19155 run_test 270a "DoM: basic functionality tests"
19156
19157 test_270b() {
19158         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19159                 skip "Need MDS version at least 2.10.55"
19160
19161         local dom=$DIR/$tdir/dom_file
19162         local max_size=1048576
19163
19164         mkdir -p $DIR/$tdir
19165         $LFS setstripe -E $max_size -L mdt $dom
19166
19167         # truncate over the limit
19168         $TRUNCATE $dom $(($max_size + 1)) &&
19169                 error "successful truncate over the maximum size"
19170         # write over the limit
19171         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
19172                 error "successful write over the maximum size"
19173         # append over the limit
19174         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
19175         echo "12345" >> $dom && error "successful append over the maximum size"
19176         rm $dom
19177
19178         return 0
19179 }
19180 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
19181
19182 test_270c() {
19183         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19184                 skip "Need MDS version at least 2.10.55"
19185
19186         mkdir -p $DIR/$tdir
19187         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
19188
19189         # check files inherit DoM EA
19190         touch $DIR/$tdir/first
19191         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
19192                 error "bad pattern"
19193         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
19194                 error "bad stripe count"
19195         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
19196                 error "bad stripe size"
19197
19198         # check directory inherits DoM EA and uses it as default
19199         mkdir $DIR/$tdir/subdir
19200         touch $DIR/$tdir/subdir/second
19201         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
19202                 error "bad pattern in sub-directory"
19203         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
19204                 error "bad stripe count in sub-directory"
19205         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
19206                 error "bad stripe size in sub-directory"
19207         return 0
19208 }
19209 run_test 270c "DoM: DoM EA inheritance tests"
19210
19211 test_270d() {
19212         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19213                 skip "Need MDS version at least 2.10.55"
19214
19215         mkdir -p $DIR/$tdir
19216         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
19217
19218         # inherit default DoM striping
19219         mkdir $DIR/$tdir/subdir
19220         touch $DIR/$tdir/subdir/f1
19221
19222         # change default directory striping
19223         $LFS setstripe -c 1 $DIR/$tdir/subdir
19224         touch $DIR/$tdir/subdir/f2
19225         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
19226                 error "wrong default striping in file 2"
19227         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
19228                 error "bad pattern in file 2"
19229         return 0
19230 }
19231 run_test 270d "DoM: change striping from DoM to RAID0"
19232
19233 test_270e() {
19234         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19235                 skip "Need MDS version at least 2.10.55"
19236
19237         mkdir -p $DIR/$tdir/dom
19238         mkdir -p $DIR/$tdir/norm
19239         DOMFILES=20
19240         NORMFILES=10
19241         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
19242         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
19243
19244         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
19245         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
19246
19247         # find DoM files by layout
19248         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
19249         [ $NUM -eq  $DOMFILES ] ||
19250                 error "lfs find -L: found $NUM, expected $DOMFILES"
19251         echo "Test 1: lfs find 20 DOM files by layout: OK"
19252
19253         # there should be 1 dir with default DOM striping
19254         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
19255         [ $NUM -eq  1 ] ||
19256                 error "lfs find -L: found $NUM, expected 1 dir"
19257         echo "Test 2: lfs find 1 DOM dir by layout: OK"
19258
19259         # find DoM files by stripe size
19260         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
19261         [ $NUM -eq  $DOMFILES ] ||
19262                 error "lfs find -S: found $NUM, expected $DOMFILES"
19263         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
19264
19265         # find files by stripe offset except DoM files
19266         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
19267         [ $NUM -eq  $NORMFILES ] ||
19268                 error "lfs find -i: found $NUM, expected $NORMFILES"
19269         echo "Test 5: lfs find no DOM files by stripe index: OK"
19270         return 0
19271 }
19272 run_test 270e "DoM: lfs find with DoM files test"
19273
19274 test_270f() {
19275         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19276                 skip "Need MDS version at least 2.10.55"
19277
19278         local mdtname=${FSNAME}-MDT0000-mdtlov
19279         local dom=$DIR/$tdir/dom_file
19280         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
19281                                                 lod.$mdtname.dom_stripesize)
19282         local dom_limit=131072
19283
19284         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
19285         local dom_current=$(do_facet mds1 $LCTL get_param -n \
19286                                                 lod.$mdtname.dom_stripesize)
19287         [ ${dom_limit} -eq ${dom_current} ] ||
19288                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
19289
19290         $LFS mkdir -i 0 -c 1 $DIR/$tdir
19291         $LFS setstripe -d $DIR/$tdir
19292         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
19293                 error "Can't set directory default striping"
19294
19295         # exceed maximum stripe size
19296         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
19297                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
19298         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
19299                 error "Able to create DoM component size more than LOD limit"
19300
19301         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
19302         dom_current=$(do_facet mds1 $LCTL get_param -n \
19303                                                 lod.$mdtname.dom_stripesize)
19304         [ 0 -eq ${dom_current} ] ||
19305                 error "Can't set zero DoM stripe limit"
19306         rm $dom
19307
19308         # attempt to create DoM file on server with disabled DoM should
19309         # remove DoM entry from layout and be succeed
19310         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
19311                 error "Can't create DoM file (DoM is disabled)"
19312         [ $($LFS getstripe -L $dom) == "mdt" ] &&
19313                 error "File has DoM component while DoM is disabled"
19314         rm $dom
19315
19316         # attempt to create DoM file with only DoM stripe should return error
19317         $LFS setstripe -E $dom_limit -L mdt $dom &&
19318                 error "Able to create DoM-only file while DoM is disabled"
19319
19320         # too low values to be aligned with smallest stripe size 64K
19321         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
19322         dom_current=$(do_facet mds1 $LCTL get_param -n \
19323                                                 lod.$mdtname.dom_stripesize)
19324         [ 30000 -eq ${dom_current} ] &&
19325                 error "Can set too small DoM stripe limit"
19326
19327         # 64K is a minimal stripe size in Lustre, expect limit of that size
19328         [ 65536 -eq ${dom_current} ] ||
19329                 error "Limit is not set to 64K but ${dom_current}"
19330
19331         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
19332         dom_current=$(do_facet mds1 $LCTL get_param -n \
19333                                                 lod.$mdtname.dom_stripesize)
19334         echo $dom_current
19335         [ 2147483648 -eq ${dom_current} ] &&
19336                 error "Can set too large DoM stripe limit"
19337
19338         do_facet mds1 $LCTL set_param -n \
19339                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
19340         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
19341                 error "Can't create DoM component size after limit change"
19342         do_facet mds1 $LCTL set_param -n \
19343                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
19344         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
19345                 error "Can't create DoM file after limit decrease"
19346         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
19347                 error "Can create big DoM component after limit decrease"
19348         touch ${dom}_def ||
19349                 error "Can't create file with old default layout"
19350
19351         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
19352         return 0
19353 }
19354 run_test 270f "DoM: maximum DoM stripe size checks"
19355
19356 test_270g() {
19357         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
19358                 skip "Need MDS version at least 2.13.52"
19359         local dom=$DIR/$tdir/$tfile
19360
19361         $LFS mkdir -i 0 -c 1 $DIR/$tdir
19362         local lodname=${FSNAME}-MDT0000-mdtlov
19363
19364         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
19365         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
19366         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
19367         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
19368
19369         local dom_limit=1024
19370         local dom_threshold="50%"
19371
19372         $LFS setstripe -d $DIR/$tdir
19373         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
19374                 error "Can't set directory default striping"
19375
19376         do_facet mds1 $LCTL set_param -n \
19377                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
19378         # set 0 threshold and create DOM file to change tunable stripesize
19379         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
19380         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
19381                 error "Failed to create $dom file"
19382         # now tunable dom_cur_stripesize should reach maximum
19383         local dom_current=$(do_facet mds1 $LCTL get_param -n \
19384                                         lod.${lodname}.dom_stripesize_cur_kb)
19385         [[ $dom_current == $dom_limit ]] ||
19386                 error "Current DOM stripesize is not maximum"
19387         rm $dom
19388
19389         # set threshold for further tests
19390         do_facet mds1 $LCTL set_param -n \
19391                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
19392         echo "DOM threshold is $dom_threshold free space"
19393         local dom_def
19394         local dom_set
19395         # Spoof bfree to exceed threshold
19396         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
19397         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
19398         for spfree in 40 20 0 15 30 55; do
19399                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
19400                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
19401                         error "Failed to create $dom file"
19402                 dom_def=$(do_facet mds1 $LCTL get_param -n \
19403                                         lod.${lodname}.dom_stripesize_cur_kb)
19404                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
19405                 [[ $dom_def != $dom_current ]] ||
19406                         error "Default stripe size was not changed"
19407                 if [[ $spfree > 0 ]] ; then
19408                         dom_set=$($LFS getstripe -S $dom)
19409                         [[ $dom_set == $((dom_def * 1024)) ]] ||
19410                                 error "DOM component size is still old"
19411                 else
19412                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
19413                                 error "DoM component is set with no free space"
19414                 fi
19415                 rm $dom
19416                 dom_current=$dom_def
19417         done
19418 }
19419 run_test 270g "DoM: default DoM stripe size depends on free space"
19420
19421 test_271a() {
19422         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19423                 skip "Need MDS version at least 2.10.55"
19424
19425         local dom=$DIR/$tdir/dom
19426
19427         mkdir -p $DIR/$tdir
19428
19429         $LFS setstripe -E 1024K -L mdt $dom
19430
19431         lctl set_param -n mdc.*.stats=clear
19432         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
19433         cat $dom > /dev/null
19434         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
19435         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
19436         ls $dom
19437         rm -f $dom
19438 }
19439 run_test 271a "DoM: data is cached for read after write"
19440
19441 test_271b() {
19442         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19443                 skip "Need MDS version at least 2.10.55"
19444
19445         local dom=$DIR/$tdir/dom
19446
19447         mkdir -p $DIR/$tdir
19448
19449         $LFS setstripe -E 1024K -L mdt -E EOF $dom
19450
19451         lctl set_param -n mdc.*.stats=clear
19452         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
19453         cancel_lru_locks mdc
19454         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
19455         # second stat to check size is cached on client
19456         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
19457         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
19458         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
19459         rm -f $dom
19460 }
19461 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
19462
19463 test_271ba() {
19464         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19465                 skip "Need MDS version at least 2.10.55"
19466
19467         local dom=$DIR/$tdir/dom
19468
19469         mkdir -p $DIR/$tdir
19470
19471         $LFS setstripe -E 1024K -L mdt -E EOF $dom
19472
19473         lctl set_param -n mdc.*.stats=clear
19474         lctl set_param -n osc.*.stats=clear
19475         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
19476         cancel_lru_locks mdc
19477         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
19478         # second stat to check size is cached on client
19479         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
19480         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
19481         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
19482         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
19483         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
19484         rm -f $dom
19485 }
19486 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
19487
19488
19489 get_mdc_stats() {
19490         local mdtidx=$1
19491         local param=$2
19492         local mdt=MDT$(printf %04x $mdtidx)
19493
19494         if [ -z $param ]; then
19495                 lctl get_param -n mdc.*$mdt*.stats
19496         else
19497                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
19498         fi
19499 }
19500
19501 test_271c() {
19502         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19503                 skip "Need MDS version at least 2.10.55"
19504
19505         local dom=$DIR/$tdir/dom
19506
19507         mkdir -p $DIR/$tdir
19508
19509         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
19510
19511         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
19512         local facet=mds$((mdtidx + 1))
19513
19514         cancel_lru_locks mdc
19515         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
19516         createmany -o $dom 1000
19517         lctl set_param -n mdc.*.stats=clear
19518         smalliomany -w $dom 1000 200
19519         get_mdc_stats $mdtidx
19520         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
19521         # Each file has 1 open, 1 IO enqueues, total 2000
19522         # but now we have also +1 getxattr for security.capability, total 3000
19523         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
19524         unlinkmany $dom 1000
19525
19526         cancel_lru_locks mdc
19527         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
19528         createmany -o $dom 1000
19529         lctl set_param -n mdc.*.stats=clear
19530         smalliomany -w $dom 1000 200
19531         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
19532         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
19533         # for OPEN and IO lock.
19534         [ $((enq - enq_2)) -ge 1000 ] ||
19535                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
19536         unlinkmany $dom 1000
19537         return 0
19538 }
19539 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
19540
19541 cleanup_271def_tests() {
19542         trap 0
19543         rm -f $1
19544 }
19545
19546 test_271d() {
19547         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
19548                 skip "Need MDS version at least 2.10.57"
19549
19550         local dom=$DIR/$tdir/dom
19551         local tmp=$TMP/$tfile
19552         trap "cleanup_271def_tests $tmp" EXIT
19553
19554         mkdir -p $DIR/$tdir
19555
19556         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
19557
19558         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
19559
19560         cancel_lru_locks mdc
19561         dd if=/dev/urandom of=$tmp bs=1000 count=1
19562         dd if=$tmp of=$dom bs=1000 count=1
19563         cancel_lru_locks mdc
19564
19565         cat /etc/hosts >> $tmp
19566         lctl set_param -n mdc.*.stats=clear
19567
19568         # append data to the same file it should update local page
19569         echo "Append to the same page"
19570         cat /etc/hosts >> $dom
19571         local num=$(get_mdc_stats $mdtidx ost_read)
19572         local ra=$(get_mdc_stats $mdtidx req_active)
19573         local rw=$(get_mdc_stats $mdtidx req_waittime)
19574
19575         [ -z $num ] || error "$num READ RPC occured"
19576         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
19577         echo "... DONE"
19578
19579         # compare content
19580         cmp $tmp $dom || error "file miscompare"
19581
19582         cancel_lru_locks mdc
19583         lctl set_param -n mdc.*.stats=clear
19584
19585         echo "Open and read file"
19586         cat $dom > /dev/null
19587         local num=$(get_mdc_stats $mdtidx ost_read)
19588         local ra=$(get_mdc_stats $mdtidx req_active)
19589         local rw=$(get_mdc_stats $mdtidx req_waittime)
19590
19591         [ -z $num ] || error "$num READ RPC occured"
19592         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
19593         echo "... DONE"
19594
19595         # compare content
19596         cmp $tmp $dom || error "file miscompare"
19597
19598         return 0
19599 }
19600 run_test 271d "DoM: read on open (1K file in reply buffer)"
19601
19602 test_271f() {
19603         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
19604                 skip "Need MDS version at least 2.10.57"
19605
19606         local dom=$DIR/$tdir/dom
19607         local tmp=$TMP/$tfile
19608         trap "cleanup_271def_tests $tmp" EXIT
19609
19610         mkdir -p $DIR/$tdir
19611
19612         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
19613
19614         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
19615
19616         cancel_lru_locks mdc
19617         dd if=/dev/urandom of=$tmp bs=265000 count=1
19618         dd if=$tmp of=$dom bs=265000 count=1
19619         cancel_lru_locks mdc
19620         cat /etc/hosts >> $tmp
19621         lctl set_param -n mdc.*.stats=clear
19622
19623         echo "Append to the same page"
19624         cat /etc/hosts >> $dom
19625         local num=$(get_mdc_stats $mdtidx ost_read)
19626         local ra=$(get_mdc_stats $mdtidx req_active)
19627         local rw=$(get_mdc_stats $mdtidx req_waittime)
19628
19629         [ -z $num ] || error "$num READ RPC occured"
19630         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
19631         echo "... DONE"
19632
19633         # compare content
19634         cmp $tmp $dom || error "file miscompare"
19635
19636         cancel_lru_locks mdc
19637         lctl set_param -n mdc.*.stats=clear
19638
19639         echo "Open and read file"
19640         cat $dom > /dev/null
19641         local num=$(get_mdc_stats $mdtidx ost_read)
19642         local ra=$(get_mdc_stats $mdtidx req_active)
19643         local rw=$(get_mdc_stats $mdtidx req_waittime)
19644
19645         [ -z $num ] && num=0
19646         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
19647         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
19648         echo "... DONE"
19649
19650         # compare content
19651         cmp $tmp $dom || error "file miscompare"
19652
19653         return 0
19654 }
19655 run_test 271f "DoM: read on open (200K file and read tail)"
19656
19657 test_271g() {
19658         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
19659                 skip "Skipping due to old client or server version"
19660
19661         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
19662         # to get layout
19663         $CHECKSTAT -t file $DIR1/$tfile
19664
19665         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
19666         MULTIOP_PID=$!
19667         sleep 1
19668         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
19669         $LCTL set_param fail_loc=0x80000314
19670         rm $DIR1/$tfile || error "Unlink fails"
19671         RC=$?
19672         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
19673         [ $RC -eq 0 ] || error "Failed write to stale object"
19674 }
19675 run_test 271g "Discard DoM data vs client flush race"
19676
19677 test_272a() {
19678         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
19679                 skip "Need MDS version at least 2.11.50"
19680
19681         local dom=$DIR/$tdir/dom
19682         mkdir -p $DIR/$tdir
19683
19684         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
19685         dd if=/dev/urandom of=$dom bs=512K count=1 ||
19686                 error "failed to write data into $dom"
19687         local old_md5=$(md5sum $dom)
19688
19689         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
19690                 error "failed to migrate to the same DoM component"
19691
19692         local new_md5=$(md5sum $dom)
19693
19694         [ "$old_md5" == "$new_md5" ] ||
19695                 error "md5sum differ: $old_md5, $new_md5"
19696
19697         [ $($LFS getstripe -c $dom) -eq 2 ] ||
19698                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
19699 }
19700 run_test 272a "DoM migration: new layout with the same DOM component"
19701
19702 test_272b() {
19703         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
19704                 skip "Need MDS version at least 2.11.50"
19705
19706         local dom=$DIR/$tdir/dom
19707         mkdir -p $DIR/$tdir
19708         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
19709
19710         local mdtidx=$($LFS getstripe -m $dom)
19711         local mdtname=MDT$(printf %04x $mdtidx)
19712         local facet=mds$((mdtidx + 1))
19713
19714         local mdtfree1=$(do_facet $facet \
19715                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19716         dd if=/dev/urandom of=$dom bs=2M count=1 ||
19717                 error "failed to write data into $dom"
19718         local old_md5=$(md5sum $dom)
19719         cancel_lru_locks mdc
19720         local mdtfree1=$(do_facet $facet \
19721                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19722
19723         $LFS migrate -c2 $dom ||
19724                 error "failed to migrate to the new composite layout"
19725         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
19726                 error "MDT stripe was not removed"
19727
19728         cancel_lru_locks mdc
19729         local new_md5=$(md5sum $dom)
19730         [ "$old_md5" == "$new_md5" ] ||
19731                 error "$old_md5 != $new_md5"
19732
19733         # Skip free space checks with ZFS
19734         if [ "$(facet_fstype $facet)" != "zfs" ]; then
19735                 local mdtfree2=$(do_facet $facet \
19736                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19737                 [ $mdtfree2 -gt $mdtfree1 ] ||
19738                         error "MDT space is not freed after migration"
19739         fi
19740         return 0
19741 }
19742 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
19743
19744 test_272c() {
19745         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
19746                 skip "Need MDS version at least 2.11.50"
19747
19748         local dom=$DIR/$tdir/$tfile
19749         mkdir -p $DIR/$tdir
19750         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
19751
19752         local mdtidx=$($LFS getstripe -m $dom)
19753         local mdtname=MDT$(printf %04x $mdtidx)
19754         local facet=mds$((mdtidx + 1))
19755
19756         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
19757                 error "failed to write data into $dom"
19758         local old_md5=$(md5sum $dom)
19759         cancel_lru_locks mdc
19760         local mdtfree1=$(do_facet $facet \
19761                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19762
19763         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
19764                 error "failed to migrate to the new composite layout"
19765         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
19766                 error "MDT stripe was not removed"
19767
19768         cancel_lru_locks mdc
19769         local new_md5=$(md5sum $dom)
19770         [ "$old_md5" == "$new_md5" ] ||
19771                 error "$old_md5 != $new_md5"
19772
19773         # Skip free space checks with ZFS
19774         if [ "$(facet_fstype $facet)" != "zfs" ]; then
19775                 local mdtfree2=$(do_facet $facet \
19776                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19777                 [ $mdtfree2 -gt $mdtfree1 ] ||
19778                         error "MDS space is not freed after migration"
19779         fi
19780         return 0
19781 }
19782 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
19783
19784 test_272d() {
19785         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
19786                 skip "Need MDS version at least 2.12.55"
19787
19788         local dom=$DIR/$tdir/$tfile
19789         mkdir -p $DIR/$tdir
19790         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
19791
19792         local mdtidx=$($LFS getstripe -m $dom)
19793         local mdtname=MDT$(printf %04x $mdtidx)
19794         local facet=mds$((mdtidx + 1))
19795
19796         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
19797                 error "failed to write data into $dom"
19798         local old_md5=$(md5sum $dom)
19799         cancel_lru_locks mdc
19800         local mdtfree1=$(do_facet $facet \
19801                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19802
19803         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
19804                 error "failed mirroring to the new composite layout"
19805         $LFS mirror resync $dom ||
19806                 error "failed mirror resync"
19807         $LFS mirror split --mirror-id 1 -d $dom ||
19808                 error "failed mirror split"
19809
19810         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
19811                 error "MDT stripe was not removed"
19812
19813         cancel_lru_locks mdc
19814         local new_md5=$(md5sum $dom)
19815         [ "$old_md5" == "$new_md5" ] ||
19816                 error "$old_md5 != $new_md5"
19817
19818         # Skip free space checks with ZFS
19819         if [ "$(facet_fstype $facet)" != "zfs" ]; then
19820                 local mdtfree2=$(do_facet $facet \
19821                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19822                 [ $mdtfree2 -gt $mdtfree1 ] ||
19823                         error "MDS space is not freed after DOM mirror deletion"
19824         fi
19825         return 0
19826 }
19827 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
19828
19829 test_272e() {
19830         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
19831                 skip "Need MDS version at least 2.12.55"
19832
19833         local dom=$DIR/$tdir/$tfile
19834         mkdir -p $DIR/$tdir
19835         $LFS setstripe -c 2 $dom
19836
19837         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
19838                 error "failed to write data into $dom"
19839         local old_md5=$(md5sum $dom)
19840         cancel_lru_locks mdc
19841
19842         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
19843                 error "failed mirroring to the DOM layout"
19844         $LFS mirror resync $dom ||
19845                 error "failed mirror resync"
19846         $LFS mirror split --mirror-id 1 -d $dom ||
19847                 error "failed mirror split"
19848
19849         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
19850                 error "MDT stripe was not removed"
19851
19852         cancel_lru_locks mdc
19853         local new_md5=$(md5sum $dom)
19854         [ "$old_md5" == "$new_md5" ] ||
19855                 error "$old_md5 != $new_md5"
19856
19857         return 0
19858 }
19859 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
19860
19861 test_272f() {
19862         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
19863                 skip "Need MDS version at least 2.12.55"
19864
19865         local dom=$DIR/$tdir/$tfile
19866         mkdir -p $DIR/$tdir
19867         $LFS setstripe -c 2 $dom
19868
19869         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
19870                 error "failed to write data into $dom"
19871         local old_md5=$(md5sum $dom)
19872         cancel_lru_locks mdc
19873
19874         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
19875                 error "failed migrating to the DOM file"
19876
19877         cancel_lru_locks mdc
19878         local new_md5=$(md5sum $dom)
19879         [ "$old_md5" != "$new_md5" ] &&
19880                 error "$old_md5 != $new_md5"
19881
19882         return 0
19883 }
19884 run_test 272f "DoM migration: OST-striped file to DOM file"
19885
19886 test_273a() {
19887         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
19888                 skip "Need MDS version at least 2.11.50"
19889
19890         # Layout swap cannot be done if either file has DOM component,
19891         # this will never be supported, migration should be used instead
19892
19893         local dom=$DIR/$tdir/$tfile
19894         mkdir -p $DIR/$tdir
19895
19896         $LFS setstripe -c2 ${dom}_plain
19897         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
19898         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
19899                 error "can swap layout with DoM component"
19900         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
19901                 error "can swap layout with DoM component"
19902
19903         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
19904         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
19905                 error "can swap layout with DoM component"
19906         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
19907                 error "can swap layout with DoM component"
19908         return 0
19909 }
19910 run_test 273a "DoM: layout swapping should fail with DOM"
19911
19912 test_275() {
19913         remote_ost_nodsh && skip "remote OST with nodsh"
19914         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
19915                 skip "Need OST version >= 2.10.57"
19916
19917         local file=$DIR/$tfile
19918         local oss
19919
19920         oss=$(comma_list $(osts_nodes))
19921
19922         dd if=/dev/urandom of=$file bs=1M count=2 ||
19923                 error "failed to create a file"
19924         cancel_lru_locks osc
19925
19926         #lock 1
19927         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
19928                 error "failed to read a file"
19929
19930 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
19931         $LCTL set_param fail_loc=0x8000031f
19932
19933         cancel_lru_locks osc &
19934         sleep 1
19935
19936 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
19937         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
19938         #IO takes another lock, but matches the PENDING one
19939         #and places it to the IO RPC
19940         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
19941                 error "failed to read a file with PENDING lock"
19942 }
19943 run_test 275 "Read on a canceled duplicate lock"
19944
19945 test_276() {
19946         remote_ost_nodsh && skip "remote OST with nodsh"
19947         local pid
19948
19949         do_facet ost1 "(while true; do \
19950                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
19951                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
19952         pid=$!
19953
19954         for LOOP in $(seq 20); do
19955                 stop ost1
19956                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
19957         done
19958         kill -9 $pid
19959         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
19960                 rm $TMP/sanity_276_pid"
19961 }
19962 run_test 276 "Race between mount and obd_statfs"
19963
19964 test_277() {
19965         $LCTL set_param ldlm.namespaces.*.lru_size=0
19966         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
19967         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
19968                         grep ^used_mb | awk '{print $2}')
19969         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
19970         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
19971                 oflag=direct conv=notrunc
19972         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
19973                         grep ^used_mb | awk '{print $2}')
19974         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
19975 }
19976 run_test 277 "Direct IO shall drop page cache"
19977
19978 test_278() {
19979         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
19980         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
19981         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
19982                 skip "needs the same host for mdt1 mdt2" && return
19983
19984         local pid1
19985         local pid2
19986
19987 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
19988         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
19989         stop mds2 &
19990         pid2=$!
19991
19992         stop mds1
19993
19994         echo "Starting MDTs"
19995         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
19996         wait $pid2
19997 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
19998 #will return NULL
19999         do_facet mds2 $LCTL set_param fail_loc=0
20000
20001         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
20002         wait_recovery_complete mds2
20003 }
20004 run_test 278 "Race starting MDS between MDTs stop/start"
20005
20006 test_280() {
20007         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
20008                 skip "Need MGS version at least 2.13.52"
20009         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20010         combined_mgs_mds || skip "needs combined MGS/MDT"
20011
20012         umount_client $MOUNT
20013 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
20014         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
20015
20016         mount_client $MOUNT &
20017         sleep 1
20018         stop mgs || error "stop mgs failed"
20019         #for a race mgs would crash
20020         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
20021         mount_client $MOUNT || error "mount client failed"
20022 }
20023 run_test 280 "Race between MGS umount and client llog processing"
20024
20025 cleanup_test_300() {
20026         trap 0
20027         umask $SAVE_UMASK
20028 }
20029 test_striped_dir() {
20030         local mdt_index=$1
20031         local stripe_count
20032         local stripe_index
20033
20034         mkdir -p $DIR/$tdir
20035
20036         SAVE_UMASK=$(umask)
20037         trap cleanup_test_300 RETURN EXIT
20038
20039         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
20040                                                 $DIR/$tdir/striped_dir ||
20041                 error "set striped dir error"
20042
20043         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
20044         [ "$mode" = "755" ] || error "expect 755 got $mode"
20045
20046         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
20047                 error "getdirstripe failed"
20048         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
20049         if [ "$stripe_count" != "2" ]; then
20050                 error "1:stripe_count is $stripe_count, expect 2"
20051         fi
20052         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
20053         if [ "$stripe_count" != "2" ]; then
20054                 error "2:stripe_count is $stripe_count, expect 2"
20055         fi
20056
20057         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
20058         if [ "$stripe_index" != "$mdt_index" ]; then
20059                 error "stripe_index is $stripe_index, expect $mdt_index"
20060         fi
20061
20062         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
20063                 error "nlink error after create striped dir"
20064
20065         mkdir $DIR/$tdir/striped_dir/a
20066         mkdir $DIR/$tdir/striped_dir/b
20067
20068         stat $DIR/$tdir/striped_dir/a ||
20069                 error "create dir under striped dir failed"
20070         stat $DIR/$tdir/striped_dir/b ||
20071                 error "create dir under striped dir failed"
20072
20073         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
20074                 error "nlink error after mkdir"
20075
20076         rmdir $DIR/$tdir/striped_dir/a
20077         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
20078                 error "nlink error after rmdir"
20079
20080         rmdir $DIR/$tdir/striped_dir/b
20081         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
20082                 error "nlink error after rmdir"
20083
20084         chattr +i $DIR/$tdir/striped_dir
20085         createmany -o $DIR/$tdir/striped_dir/f 10 &&
20086                 error "immutable flags not working under striped dir!"
20087         chattr -i $DIR/$tdir/striped_dir
20088
20089         rmdir $DIR/$tdir/striped_dir ||
20090                 error "rmdir striped dir error"
20091
20092         cleanup_test_300
20093
20094         true
20095 }
20096
20097 test_300a() {
20098         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20099                 skip "skipped for lustre < 2.7.0"
20100         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20101         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20102
20103         test_striped_dir 0 || error "failed on striped dir on MDT0"
20104         test_striped_dir 1 || error "failed on striped dir on MDT0"
20105 }
20106 run_test 300a "basic striped dir sanity test"
20107
20108 test_300b() {
20109         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20110                 skip "skipped for lustre < 2.7.0"
20111         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20112         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20113
20114         local i
20115         local mtime1
20116         local mtime2
20117         local mtime3
20118
20119         test_mkdir $DIR/$tdir || error "mkdir fail"
20120         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
20121                 error "set striped dir error"
20122         for i in {0..9}; do
20123                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
20124                 sleep 1
20125                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
20126                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
20127                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
20128                 sleep 1
20129                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
20130                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
20131                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
20132         done
20133         true
20134 }
20135 run_test 300b "check ctime/mtime for striped dir"
20136
20137 test_300c() {
20138         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20139                 skip "skipped for lustre < 2.7.0"
20140         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20141         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20142
20143         local file_count
20144
20145         mkdir -p $DIR/$tdir
20146         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
20147                 error "set striped dir error"
20148
20149         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
20150                 error "chown striped dir failed"
20151
20152         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
20153                 error "create 5k files failed"
20154
20155         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
20156
20157         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
20158
20159         rm -rf $DIR/$tdir
20160 }
20161 run_test 300c "chown && check ls under striped directory"
20162
20163 test_300d() {
20164         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20165                 skip "skipped for lustre < 2.7.0"
20166         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20167         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20168
20169         local stripe_count
20170         local file
20171
20172         mkdir -p $DIR/$tdir
20173         $LFS setstripe -c 2 $DIR/$tdir
20174
20175         #local striped directory
20176         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
20177                 error "set striped dir error"
20178         #look at the directories for debug purposes
20179         ls -l $DIR/$tdir
20180         $LFS getdirstripe $DIR/$tdir
20181         ls -l $DIR/$tdir/striped_dir
20182         $LFS getdirstripe $DIR/$tdir/striped_dir
20183         createmany -o $DIR/$tdir/striped_dir/f 10 ||
20184                 error "create 10 files failed"
20185
20186         #remote striped directory
20187         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
20188                 error "set striped dir error"
20189         #look at the directories for debug purposes
20190         ls -l $DIR/$tdir
20191         $LFS getdirstripe $DIR/$tdir
20192         ls -l $DIR/$tdir/remote_striped_dir
20193         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
20194         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
20195                 error "create 10 files failed"
20196
20197         for file in $(find $DIR/$tdir); do
20198                 stripe_count=$($LFS getstripe -c $file)
20199                 [ $stripe_count -eq 2 ] ||
20200                         error "wrong stripe $stripe_count for $file"
20201         done
20202
20203         rm -rf $DIR/$tdir
20204 }
20205 run_test 300d "check default stripe under striped directory"
20206
20207 test_300e() {
20208         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20209                 skip "Need MDS version at least 2.7.55"
20210         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20211         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20212
20213         local stripe_count
20214         local file
20215
20216         mkdir -p $DIR/$tdir
20217
20218         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
20219                 error "set striped dir error"
20220
20221         touch $DIR/$tdir/striped_dir/a
20222         touch $DIR/$tdir/striped_dir/b
20223         touch $DIR/$tdir/striped_dir/c
20224
20225         mkdir $DIR/$tdir/striped_dir/dir_a
20226         mkdir $DIR/$tdir/striped_dir/dir_b
20227         mkdir $DIR/$tdir/striped_dir/dir_c
20228
20229         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
20230                 error "set striped adir under striped dir error"
20231
20232         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
20233                 error "set striped bdir under striped dir error"
20234
20235         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
20236                 error "set striped cdir under striped dir error"
20237
20238         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
20239                 error "rename dir under striped dir fails"
20240
20241         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
20242                 error "rename dir under different stripes fails"
20243
20244         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
20245                 error "rename file under striped dir should succeed"
20246
20247         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
20248                 error "rename dir under striped dir should succeed"
20249
20250         rm -rf $DIR/$tdir
20251 }
20252 run_test 300e "check rename under striped directory"
20253
20254 test_300f() {
20255         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20256         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20257         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20258                 skip "Need MDS version at least 2.7.55"
20259
20260         local stripe_count
20261         local file
20262
20263         rm -rf $DIR/$tdir
20264         mkdir -p $DIR/$tdir
20265
20266         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
20267                 error "set striped dir error"
20268
20269         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
20270                 error "set striped dir error"
20271
20272         touch $DIR/$tdir/striped_dir/a
20273         mkdir $DIR/$tdir/striped_dir/dir_a
20274         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
20275                 error "create striped dir under striped dir fails"
20276
20277         touch $DIR/$tdir/striped_dir1/b
20278         mkdir $DIR/$tdir/striped_dir1/dir_b
20279         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
20280                 error "create striped dir under striped dir fails"
20281
20282         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
20283                 error "rename dir under different striped dir should fail"
20284
20285         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
20286                 error "rename striped dir under diff striped dir should fail"
20287
20288         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
20289                 error "rename file under diff striped dirs fails"
20290
20291         rm -rf $DIR/$tdir
20292 }
20293 run_test 300f "check rename cross striped directory"
20294
20295 test_300_check_default_striped_dir()
20296 {
20297         local dirname=$1
20298         local default_count=$2
20299         local default_index=$3
20300         local stripe_count
20301         local stripe_index
20302         local dir_stripe_index
20303         local dir
20304
20305         echo "checking $dirname $default_count $default_index"
20306         $LFS setdirstripe -D -c $default_count -i $default_index \
20307                                 -t all_char $DIR/$tdir/$dirname ||
20308                 error "set default stripe on striped dir error"
20309         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
20310         [ $stripe_count -eq $default_count ] ||
20311                 error "expect $default_count get $stripe_count for $dirname"
20312
20313         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
20314         [ $stripe_index -eq $default_index ] ||
20315                 error "expect $default_index get $stripe_index for $dirname"
20316
20317         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
20318                                                 error "create dirs failed"
20319
20320         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
20321         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
20322         for dir in $(find $DIR/$tdir/$dirname/*); do
20323                 stripe_count=$($LFS getdirstripe -c $dir)
20324                 [ $stripe_count -eq $default_count ] ||
20325                 [ $stripe_count -eq 0 ] || [ $default_count -eq 1 ] ||
20326                 error "stripe count $default_count != $stripe_count for $dir"
20327
20328                 stripe_index=$($LFS getdirstripe -i $dir)
20329                 [ $default_index -eq -1 ] ||
20330                         [ $stripe_index -eq $default_index ] ||
20331                         error "$stripe_index != $default_index for $dir"
20332
20333                 #check default stripe
20334                 stripe_count=$($LFS getdirstripe -D -c $dir)
20335                 [ $stripe_count -eq $default_count ] ||
20336                 error "default count $default_count != $stripe_count for $dir"
20337
20338                 stripe_index=$($LFS getdirstripe -D -i $dir)
20339                 [ $stripe_index -eq $default_index ] ||
20340                 error "default index $default_index != $stripe_index for $dir"
20341         done
20342         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
20343 }
20344
20345 test_300g() {
20346         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20347         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20348                 skip "Need MDS version at least 2.7.55"
20349
20350         local dir
20351         local stripe_count
20352         local stripe_index
20353
20354         mkdir $DIR/$tdir
20355         mkdir $DIR/$tdir/normal_dir
20356
20357         #Checking when client cache stripe index
20358         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
20359         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
20360                 error "create striped_dir failed"
20361
20362         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
20363                 error "create dir0 fails"
20364         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
20365         [ $stripe_index -eq 0 ] ||
20366                 error "dir0 expect index 0 got $stripe_index"
20367
20368         mkdir $DIR/$tdir/striped_dir/dir1 ||
20369                 error "create dir1 fails"
20370         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
20371         [ $stripe_index -eq 1 ] ||
20372                 error "dir1 expect index 1 got $stripe_index"
20373
20374         #check default stripe count/stripe index
20375         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
20376         test_300_check_default_striped_dir normal_dir 1 0
20377         test_300_check_default_striped_dir normal_dir 2 1
20378         test_300_check_default_striped_dir normal_dir 2 -1
20379
20380         #delete default stripe information
20381         echo "delete default stripeEA"
20382         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
20383                 error "set default stripe on striped dir error"
20384
20385         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
20386         for dir in $(find $DIR/$tdir/normal_dir/*); do
20387                 stripe_count=$($LFS getdirstripe -c $dir)
20388                 [ $stripe_count -eq 0 ] ||
20389                         error "expect 1 get $stripe_count for $dir"
20390                 stripe_index=$($LFS getdirstripe -i $dir)
20391                 [ $stripe_index -eq 0 ] ||
20392                         error "expect 0 get $stripe_index for $dir"
20393         done
20394 }
20395 run_test 300g "check default striped directory for normal directory"
20396
20397 test_300h() {
20398         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20399         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20400                 skip "Need MDS version at least 2.7.55"
20401
20402         local dir
20403         local stripe_count
20404
20405         mkdir $DIR/$tdir
20406         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
20407                 error "set striped dir error"
20408
20409         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
20410         test_300_check_default_striped_dir striped_dir 1 0
20411         test_300_check_default_striped_dir striped_dir 2 1
20412         test_300_check_default_striped_dir striped_dir 2 -1
20413
20414         #delete default stripe information
20415         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
20416                 error "set default stripe on striped dir error"
20417
20418         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
20419         for dir in $(find $DIR/$tdir/striped_dir/*); do
20420                 stripe_count=$($LFS getdirstripe -c $dir)
20421                 [ $stripe_count -eq 0 ] ||
20422                         error "expect 1 get $stripe_count for $dir"
20423         done
20424 }
20425 run_test 300h "check default striped directory for striped directory"
20426
20427 test_300i() {
20428         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20429         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20430         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20431                 skip "Need MDS version at least 2.7.55"
20432
20433         local stripe_count
20434         local file
20435
20436         mkdir $DIR/$tdir
20437
20438         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
20439                 error "set striped dir error"
20440
20441         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
20442                 error "create files under striped dir failed"
20443
20444         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
20445                 error "set striped hashdir error"
20446
20447         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
20448                 error "create dir0 under hash dir failed"
20449         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
20450                 error "create dir1 under hash dir failed"
20451
20452         # unfortunately, we need to umount to clear dir layout cache for now
20453         # once we fully implement dir layout, we can drop this
20454         umount_client $MOUNT || error "umount failed"
20455         mount_client $MOUNT || error "mount failed"
20456
20457         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
20458         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
20459         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
20460
20461         #set the stripe to be unknown hash type
20462         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
20463         $LCTL set_param fail_loc=0x1901
20464         for ((i = 0; i < 10; i++)); do
20465                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
20466                         error "stat f-$i failed"
20467                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
20468         done
20469
20470         touch $DIR/$tdir/striped_dir/f0 &&
20471                 error "create under striped dir with unknown hash should fail"
20472
20473         $LCTL set_param fail_loc=0
20474
20475         umount_client $MOUNT || error "umount failed"
20476         mount_client $MOUNT || error "mount failed"
20477
20478         return 0
20479 }
20480 run_test 300i "client handle unknown hash type striped directory"
20481
20482 test_300j() {
20483         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20484         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20485         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20486                 skip "Need MDS version at least 2.7.55"
20487
20488         local stripe_count
20489         local file
20490
20491         mkdir $DIR/$tdir
20492
20493         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
20494         $LCTL set_param fail_loc=0x1702
20495         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
20496                 error "set striped dir error"
20497
20498         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
20499                 error "create files under striped dir failed"
20500
20501         $LCTL set_param fail_loc=0
20502
20503         rm -rf $DIR/$tdir || error "unlink striped dir fails"
20504
20505         return 0
20506 }
20507 run_test 300j "test large update record"
20508
20509 test_300k() {
20510         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20511         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20512         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20513                 skip "Need MDS version at least 2.7.55"
20514
20515         # this test needs a huge transaction
20516         local kb
20517         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
20518              osd*.$FSNAME-MDT0000.kbytestotal")
20519         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
20520
20521         local stripe_count
20522         local file
20523
20524         mkdir $DIR/$tdir
20525
20526         #define OBD_FAIL_LARGE_STRIPE   0x1703
20527         $LCTL set_param fail_loc=0x1703
20528         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
20529                 error "set striped dir error"
20530         $LCTL set_param fail_loc=0
20531
20532         $LFS getdirstripe $DIR/$tdir/striped_dir ||
20533                 error "getstripeddir fails"
20534         rm -rf $DIR/$tdir/striped_dir ||
20535                 error "unlink striped dir fails"
20536
20537         return 0
20538 }
20539 run_test 300k "test large striped directory"
20540
20541 test_300l() {
20542         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20543         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20544         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20545                 skip "Need MDS version at least 2.7.55"
20546
20547         local stripe_index
20548
20549         test_mkdir -p $DIR/$tdir/striped_dir
20550         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
20551                         error "chown $RUNAS_ID failed"
20552         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
20553                 error "set default striped dir failed"
20554
20555         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
20556         $LCTL set_param fail_loc=0x80000158
20557         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
20558
20559         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
20560         [ $stripe_index -eq 1 ] ||
20561                 error "expect 1 get $stripe_index for $dir"
20562 }
20563 run_test 300l "non-root user to create dir under striped dir with stale layout"
20564
20565 test_300m() {
20566         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20567         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
20568         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20569                 skip "Need MDS version at least 2.7.55"
20570
20571         mkdir -p $DIR/$tdir/striped_dir
20572         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
20573                 error "set default stripes dir error"
20574
20575         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
20576
20577         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
20578         [ $stripe_count -eq 0 ] ||
20579                         error "expect 0 get $stripe_count for a"
20580
20581         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
20582                 error "set default stripes dir error"
20583
20584         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
20585
20586         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
20587         [ $stripe_count -eq 0 ] ||
20588                         error "expect 0 get $stripe_count for b"
20589
20590         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
20591                 error "set default stripes dir error"
20592
20593         mkdir $DIR/$tdir/striped_dir/c &&
20594                 error "default stripe_index is invalid, mkdir c should fails"
20595
20596         rm -rf $DIR/$tdir || error "rmdir fails"
20597 }
20598 run_test 300m "setstriped directory on single MDT FS"
20599
20600 cleanup_300n() {
20601         local list=$(comma_list $(mdts_nodes))
20602
20603         trap 0
20604         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
20605 }
20606
20607 test_300n() {
20608         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20609         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20610         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20611                 skip "Need MDS version at least 2.7.55"
20612         remote_mds_nodsh && skip "remote MDS with nodsh"
20613
20614         local stripe_index
20615         local list=$(comma_list $(mdts_nodes))
20616
20617         trap cleanup_300n RETURN EXIT
20618         mkdir -p $DIR/$tdir
20619         chmod 777 $DIR/$tdir
20620         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
20621                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
20622                 error "create striped dir succeeds with gid=0"
20623
20624         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
20625         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
20626                 error "create striped dir fails with gid=-1"
20627
20628         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
20629         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
20630                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
20631                 error "set default striped dir succeeds with gid=0"
20632
20633
20634         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
20635         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
20636                 error "set default striped dir fails with gid=-1"
20637
20638
20639         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
20640         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
20641                                         error "create test_dir fails"
20642         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
20643                                         error "create test_dir1 fails"
20644         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
20645                                         error "create test_dir2 fails"
20646         cleanup_300n
20647 }
20648 run_test 300n "non-root user to create dir under striped dir with default EA"
20649
20650 test_300o() {
20651         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20652         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20653         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20654                 skip "Need MDS version at least 2.7.55"
20655
20656         local numfree1
20657         local numfree2
20658
20659         mkdir -p $DIR/$tdir
20660
20661         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
20662         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
20663         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
20664                 skip "not enough free inodes $numfree1 $numfree2"
20665         fi
20666
20667         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
20668         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
20669         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
20670                 skip "not enough free space $numfree1 $numfree2"
20671         fi
20672
20673         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
20674                 error "setdirstripe fails"
20675
20676         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
20677                 error "create dirs fails"
20678
20679         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
20680         ls $DIR/$tdir/striped_dir > /dev/null ||
20681                 error "ls striped dir fails"
20682         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
20683                 error "unlink big striped dir fails"
20684 }
20685 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
20686
20687 test_300p() {
20688         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20689         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20690         remote_mds_nodsh && skip "remote MDS with nodsh"
20691
20692         mkdir -p $DIR/$tdir
20693
20694         #define OBD_FAIL_OUT_ENOSPC     0x1704
20695         do_facet mds2 lctl set_param fail_loc=0x80001704
20696         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
20697                  && error "create striped directory should fail"
20698
20699         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
20700
20701         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
20702         true
20703 }
20704 run_test 300p "create striped directory without space"
20705
20706 test_300q() {
20707         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20708         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20709
20710         local fd=$(free_fd)
20711         local cmd="exec $fd<$tdir"
20712         cd $DIR
20713         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
20714         eval $cmd
20715         cmd="exec $fd<&-"
20716         trap "eval $cmd" EXIT
20717         cd $tdir || error "cd $tdir fails"
20718         rmdir  ../$tdir || error "rmdir $tdir fails"
20719         mkdir local_dir && error "create dir succeeds"
20720         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
20721         eval $cmd
20722         return 0
20723 }
20724 run_test 300q "create remote directory under orphan directory"
20725
20726 test_300r() {
20727         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20728                 skip "Need MDS version at least 2.7.55" && return
20729         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
20730
20731         mkdir $DIR/$tdir
20732
20733         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
20734                 error "set striped dir error"
20735
20736         $LFS getdirstripe $DIR/$tdir/striped_dir ||
20737                 error "getstripeddir fails"
20738
20739         local stripe_count
20740         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
20741                       awk '/lmv_stripe_count:/ { print $2 }')
20742
20743         [ $MDSCOUNT -ne $stripe_count ] &&
20744                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
20745
20746         rm -rf $DIR/$tdir/striped_dir ||
20747                 error "unlink striped dir fails"
20748 }
20749 run_test 300r "test -1 striped directory"
20750
20751 prepare_remote_file() {
20752         mkdir $DIR/$tdir/src_dir ||
20753                 error "create remote source failed"
20754
20755         cp /etc/hosts $DIR/$tdir/src_dir/a ||
20756                  error "cp to remote source failed"
20757         touch $DIR/$tdir/src_dir/a
20758
20759         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
20760                 error "create remote target dir failed"
20761
20762         touch $DIR/$tdir/tgt_dir/b
20763
20764         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
20765                 error "rename dir cross MDT failed!"
20766
20767         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
20768                 error "src_child still exists after rename"
20769
20770         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
20771                 error "missing file(a) after rename"
20772
20773         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
20774                 error "diff after rename"
20775 }
20776
20777 test_310a() {
20778         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
20779         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20780
20781         local remote_file=$DIR/$tdir/tgt_dir/b
20782
20783         mkdir -p $DIR/$tdir
20784
20785         prepare_remote_file || error "prepare remote file failed"
20786
20787         #open-unlink file
20788         $OPENUNLINK $remote_file $remote_file ||
20789                 error "openunlink $remote_file failed"
20790         $CHECKSTAT -a $remote_file || error "$remote_file exists"
20791 }
20792 run_test 310a "open unlink remote file"
20793
20794 test_310b() {
20795         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
20796         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20797
20798         local remote_file=$DIR/$tdir/tgt_dir/b
20799
20800         mkdir -p $DIR/$tdir
20801
20802         prepare_remote_file || error "prepare remote file failed"
20803
20804         ln $remote_file $DIR/$tfile || error "link failed for remote file"
20805         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
20806         $CHECKSTAT -t file $remote_file || error "check file failed"
20807 }
20808 run_test 310b "unlink remote file with multiple links while open"
20809
20810 test_310c() {
20811         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20812         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
20813
20814         local remote_file=$DIR/$tdir/tgt_dir/b
20815
20816         mkdir -p $DIR/$tdir
20817
20818         prepare_remote_file || error "prepare remote file failed"
20819
20820         ln $remote_file $DIR/$tfile || error "link failed for remote file"
20821         multiop_bg_pause $remote_file O_uc ||
20822                         error "mulitop failed for remote file"
20823         MULTIPID=$!
20824         $MULTIOP $DIR/$tfile Ouc
20825         kill -USR1 $MULTIPID
20826         wait $MULTIPID
20827 }
20828 run_test 310c "open-unlink remote file with multiple links"
20829
20830 #LU-4825
20831 test_311() {
20832         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20833         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
20834         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
20835                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
20836         remote_mds_nodsh && skip "remote MDS with nodsh"
20837
20838         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
20839         local mdts=$(comma_list $(mdts_nodes))
20840
20841         mkdir -p $DIR/$tdir
20842         $LFS setstripe -i 0 -c 1 $DIR/$tdir
20843         createmany -o $DIR/$tdir/$tfile. 1000
20844
20845         # statfs data is not real time, let's just calculate it
20846         old_iused=$((old_iused + 1000))
20847
20848         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
20849                         osp.*OST0000*MDT0000.create_count")
20850         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
20851                                 osp.*OST0000*MDT0000.max_create_count")
20852         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
20853
20854         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
20855         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
20856         [ $index -ne 0 ] || error "$tfile stripe index is 0"
20857
20858         unlinkmany $DIR/$tdir/$tfile. 1000
20859
20860         do_nodes $mdts "$LCTL set_param -n \
20861                         osp.*OST0000*.max_create_count=$max_count"
20862         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
20863                 do_nodes $mdts "$LCTL set_param -n \
20864                                 osp.*OST0000*.create_count=$count"
20865         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
20866                         grep "=0" && error "create_count is zero"
20867
20868         local new_iused
20869         for i in $(seq 120); do
20870                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
20871                 # system may be too busy to destroy all objs in time, use
20872                 # a somewhat small value to not fail autotest
20873                 [ $((old_iused - new_iused)) -gt 400 ] && break
20874                 sleep 1
20875         done
20876
20877         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
20878         [ $((old_iused - new_iused)) -gt 400 ] ||
20879                 error "objs not destroyed after unlink"
20880 }
20881 run_test 311 "disable OSP precreate, and unlink should destroy objs"
20882
20883 zfs_oid_to_objid()
20884 {
20885         local ost=$1
20886         local objid=$2
20887
20888         local vdevdir=$(dirname $(facet_vdevice $ost))
20889         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
20890         local zfs_zapid=$(do_facet $ost $cmd |
20891                           grep -w "/O/0/d$((objid%32))" -C 5 |
20892                           awk '/Object/{getline; print $1}')
20893         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
20894                           awk "/$objid = /"'{printf $3}')
20895
20896         echo $zfs_objid
20897 }
20898
20899 zfs_object_blksz() {
20900         local ost=$1
20901         local objid=$2
20902
20903         local vdevdir=$(dirname $(facet_vdevice $ost))
20904         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
20905         local blksz=$(do_facet $ost $cmd $objid |
20906                       awk '/dblk/{getline; printf $4}')
20907
20908         case "${blksz: -1}" in
20909                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
20910                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
20911                 *) ;;
20912         esac
20913
20914         echo $blksz
20915 }
20916
20917 test_312() { # LU-4856
20918         remote_ost_nodsh && skip "remote OST with nodsh"
20919         [ "$ost1_FSTYPE" = "zfs" ] ||
20920                 skip_env "the test only applies to zfs"
20921
20922         local max_blksz=$(do_facet ost1 \
20923                           $ZFS get -p recordsize $(facet_device ost1) |
20924                           awk '!/VALUE/{print $3}')
20925
20926         # to make life a little bit easier
20927         $LFS mkdir -c 1 -i 0 $DIR/$tdir
20928         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20929
20930         local tf=$DIR/$tdir/$tfile
20931         touch $tf
20932         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
20933
20934         # Get ZFS object id
20935         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
20936         # block size change by sequential overwrite
20937         local bs
20938
20939         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
20940                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
20941
20942                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
20943                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
20944         done
20945         rm -f $tf
20946
20947         # block size change by sequential append write
20948         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
20949         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
20950         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
20951         local count
20952
20953         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
20954                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
20955                         oflag=sync conv=notrunc
20956
20957                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
20958                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
20959                         error "blksz error, actual $blksz, " \
20960                                 "expected: 2 * $count * $PAGE_SIZE"
20961         done
20962         rm -f $tf
20963
20964         # random write
20965         touch $tf
20966         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
20967         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
20968
20969         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
20970         blksz=$(zfs_object_blksz ost1 $zfs_objid)
20971         [ $blksz -eq $PAGE_SIZE ] ||
20972                 error "blksz error: $blksz, expected: $PAGE_SIZE"
20973
20974         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
20975         blksz=$(zfs_object_blksz ost1 $zfs_objid)
20976         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
20977
20978         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
20979         blksz=$(zfs_object_blksz ost1 $zfs_objid)
20980         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
20981 }
20982 run_test 312 "make sure ZFS adjusts its block size by write pattern"
20983
20984 test_313() {
20985         remote_ost_nodsh && skip "remote OST with nodsh"
20986
20987         local file=$DIR/$tfile
20988
20989         rm -f $file
20990         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
20991
20992         # define OBD_FAIL_TGT_RCVD_EIO           0x720
20993         do_facet ost1 "$LCTL set_param fail_loc=0x720"
20994         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
20995                 error "write should failed"
20996         do_facet ost1 "$LCTL set_param fail_loc=0"
20997         rm -f $file
20998 }
20999 run_test 313 "io should fail after last_rcvd update fail"
21000
21001 test_314() {
21002         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
21003
21004         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
21005         do_facet ost1 "$LCTL set_param fail_loc=0x720"
21006         rm -f $DIR/$tfile
21007         wait_delete_completed
21008         do_facet ost1 "$LCTL set_param fail_loc=0"
21009 }
21010 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
21011
21012 test_315() { # LU-618
21013         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
21014
21015         local file=$DIR/$tfile
21016         rm -f $file
21017
21018         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
21019                 error "multiop file write failed"
21020         $MULTIOP $file oO_RDONLY:r4063232_c &
21021         PID=$!
21022
21023         sleep 2
21024
21025         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
21026         kill -USR1 $PID
21027
21028         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
21029         rm -f $file
21030 }
21031 run_test 315 "read should be accounted"
21032
21033 test_316() {
21034         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21035         large_xattr_enabled || skip_env "ea_inode feature disabled"
21036
21037         rm -rf $DIR/$tdir/d
21038         mkdir -p $DIR/$tdir/d
21039         chown nobody $DIR/$tdir/d
21040         touch $DIR/$tdir/d/file
21041
21042         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
21043 }
21044 run_test 316 "lfs mv"
21045
21046 test_317() {
21047         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
21048                 skip "Need MDS version at least 2.11.53"
21049         if [ "$ost1_FSTYPE" == "zfs" ]; then
21050                 skip "LU-10370: no implementation for ZFS"
21051         fi
21052
21053         local trunc_sz
21054         local grant_blk_size
21055
21056         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
21057                         awk '/grant_block_size:/ { print $2; exit; }')
21058         #
21059         # Create File of size 5M. Truncate it to below size's and verify
21060         # blocks count.
21061         #
21062         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
21063                 error "Create file $DIR/$tfile failed"
21064         stack_trap "rm -f $DIR/$tfile" EXIT
21065
21066         for trunc_sz in 2097152 4097 4000 509 0; do
21067                 $TRUNCATE $DIR/$tfile $trunc_sz ||
21068                         error "truncate $tfile to $trunc_sz failed"
21069                 local sz=$(stat --format=%s $DIR/$tfile)
21070                 local blk=$(stat --format=%b $DIR/$tfile)
21071                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
21072                                      grant_blk_size) * 8))
21073
21074                 if [[ $blk -ne $trunc_blk ]]; then
21075                         $(which stat) $DIR/$tfile
21076                         error "Expected Block $trunc_blk got $blk for $tfile"
21077                 fi
21078
21079                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
21080                         error "Expected Size $trunc_sz got $sz for $tfile"
21081         done
21082
21083         #
21084         # sparse file test
21085         # Create file with a hole and write actual two blocks. Block count
21086         # must be 16.
21087         #
21088         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
21089                 conv=fsync || error "Create file : $DIR/$tfile"
21090
21091         # Calculate the final truncate size.
21092         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
21093
21094         #
21095         # truncate to size $trunc_sz bytes. Strip the last block
21096         # The block count must drop to 8
21097         #
21098         $TRUNCATE $DIR/$tfile $trunc_sz ||
21099                 error "truncate $tfile to $trunc_sz failed"
21100
21101         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
21102         sz=$(stat --format=%s $DIR/$tfile)
21103         blk=$(stat --format=%b $DIR/$tfile)
21104
21105         if [[ $blk -ne $trunc_bsz ]]; then
21106                 $(which stat) $DIR/$tfile
21107                 error "Expected Block $trunc_bsz got $blk for $tfile"
21108         fi
21109
21110         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
21111                 error "Expected Size $trunc_sz got $sz for $tfile"
21112 }
21113 run_test 317 "Verify blocks get correctly update after truncate"
21114
21115 test_318() {
21116         local old_max_active=$($LCTL get_param -n \
21117                             llite.*.max_read_ahead_async_active 2>/dev/null)
21118
21119         $LCTL set_param llite.*.max_read_ahead_async_active=256
21120         local max_active=$($LCTL get_param -n \
21121                            llite.*.max_read_ahead_async_active 2>/dev/null)
21122         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
21123
21124         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
21125                 error "set max_read_ahead_async_active should succeed"
21126
21127         $LCTL set_param llite.*.max_read_ahead_async_active=512
21128         max_active=$($LCTL get_param -n \
21129                      llite.*.max_read_ahead_async_active 2>/dev/null)
21130         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
21131
21132         # restore @max_active
21133         [ $old_max_active -ne 0 ] && $LCTL set_param \
21134                 llite.*.max_read_ahead_async_active=$old_max_active
21135
21136         local old_threshold=$($LCTL get_param -n \
21137                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
21138         local max_per_file_mb=$($LCTL get_param -n \
21139                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
21140
21141         local invalid=$(($max_per_file_mb + 1))
21142         $LCTL set_param \
21143                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
21144                         && error "set $invalid should fail"
21145
21146         local valid=$(($invalid - 1))
21147         $LCTL set_param \
21148                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
21149                         error "set $valid should succeed"
21150         local threshold=$($LCTL get_param -n \
21151                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
21152         [ $threshold -eq $valid ] || error \
21153                 "expect threshold $valid got $threshold"
21154         $LCTL set_param \
21155                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
21156 }
21157 run_test 318 "Verify async readahead tunables"
21158
21159 test_319() {
21160         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
21161
21162         local before=$(date +%s)
21163         local evict
21164         local mdir=$DIR/$tdir
21165         local file=$mdir/xxx
21166
21167         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
21168         touch $file
21169
21170 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
21171         $LCTL set_param fail_val=5 fail_loc=0x8000032c
21172         $LFS mv -m1 $file &
21173
21174         sleep 1
21175         dd if=$file of=/dev/null
21176         wait
21177         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
21178           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
21179
21180         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
21181 }
21182 run_test 319 "lost lease lock on migrate error"
21183
21184 test_398a() { # LU-4198
21185         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21186         $LCTL set_param ldlm.namespaces.*.lru_size=clear
21187
21188         # request a new lock on client
21189         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
21190
21191         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
21192         local lock_count=$($LCTL get_param -n \
21193                            ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
21194         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
21195
21196         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
21197
21198         # no lock cached, should use lockless IO and not enqueue new lock
21199         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
21200         lock_count=$($LCTL get_param -n \
21201                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
21202         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
21203 }
21204 run_test 398a "direct IO should cancel lock otherwise lockless"
21205
21206 test_398b() { # LU-4198
21207         which fio || skip_env "no fio installed"
21208         $LFS setstripe -c -1 $DIR/$tfile
21209
21210         local size=12
21211         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
21212
21213         local njobs=4
21214         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
21215         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
21216                 --numjobs=$njobs --fallocate=none \
21217                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
21218                 --filename=$DIR/$tfile &
21219         bg_pid=$!
21220
21221         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
21222         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
21223                 --numjobs=$njobs --fallocate=none \
21224                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
21225                 --filename=$DIR/$tfile || true
21226         wait $bg_pid
21227
21228         rm -rf $DIR/$tfile
21229 }
21230 run_test 398b "DIO and buffer IO race"
21231
21232 test_398c() { # LU-4198
21233         which fio || skip_env "no fio installed"
21234
21235         saved_debug=$($LCTL get_param -n debug)
21236         $LCTL set_param debug=0
21237
21238         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
21239         ((size /= 1024)) # by megabytes
21240         ((size /= 2)) # write half of the OST at most
21241         [ $size -gt 40 ] && size=40 #reduce test time anyway
21242
21243         $LFS setstripe -c 1 $DIR/$tfile
21244
21245         # it seems like ldiskfs reserves more space than necessary if the
21246         # writing blocks are not mapped, so it extends the file firstly
21247         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
21248         cancel_lru_locks osc
21249
21250         # clear and verify rpc_stats later
21251         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
21252
21253         local njobs=4
21254         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
21255         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
21256                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
21257                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
21258                 --filename=$DIR/$tfile
21259         [ $? -eq 0 ] || error "fio write error"
21260
21261         [ $($LCTL get_param -n \
21262          ldlm.namespaces.${FSNAME}-OST0000-osc-ffff*.lock_count) -eq 0 ] ||
21263                 error "Locks were requested while doing AIO"
21264
21265         # get the percentage of 1-page I/O
21266         pct=$($LCTL get_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats |
21267                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
21268                 awk '{print $7}')
21269         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
21270
21271         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
21272         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
21273                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
21274                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
21275                 --filename=$DIR/$tfile
21276         [ $? -eq 0 ] || error "fio mixed read write error"
21277
21278         rm -rf $DIR/$tfile
21279         $LCTL set_param debug="$saved_debug"
21280 }
21281 run_test 398c "run fio to test AIO"
21282
21283 test_fake_rw() {
21284         local read_write=$1
21285         if [ "$read_write" = "write" ]; then
21286                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
21287         elif [ "$read_write" = "read" ]; then
21288                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
21289         else
21290                 error "argument error"
21291         fi
21292
21293         # turn off debug for performance testing
21294         local saved_debug=$($LCTL get_param -n debug)
21295         $LCTL set_param debug=0
21296
21297         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21298
21299         # get ost1 size - $FSNAME-OST0000
21300         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
21301         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
21302         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
21303
21304         if [ "$read_write" = "read" ]; then
21305                 truncate -s $(expr 1048576 \* $blocks) $DIR/$tfile
21306         fi
21307
21308         local start_time=$(date +%s.%N)
21309         $dd_cmd bs=1M count=$blocks oflag=sync ||
21310                 error "real dd $read_write error"
21311         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
21312
21313         if [ "$read_write" = "write" ]; then
21314                 rm -f $DIR/$tfile
21315         fi
21316
21317         # define OBD_FAIL_OST_FAKE_RW           0x238
21318         do_facet ost1 $LCTL set_param fail_loc=0x238
21319
21320         local start_time=$(date +%s.%N)
21321         $dd_cmd bs=1M count=$blocks oflag=sync ||
21322                 error "fake dd $read_write error"
21323         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
21324
21325         if [ "$read_write" = "write" ]; then
21326                 # verify file size
21327                 cancel_lru_locks osc
21328                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
21329                         error "$tfile size not $blocks MB"
21330         fi
21331         do_facet ost1 $LCTL set_param fail_loc=0
21332
21333         echo "fake $read_write $duration_fake vs. normal $read_write" \
21334                 "$duration in seconds"
21335         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
21336                 error_not_in_vm "fake write is slower"
21337
21338         $LCTL set_param -n debug="$saved_debug"
21339         rm -f $DIR/$tfile
21340 }
21341 test_399a() { # LU-7655 for OST fake write
21342         remote_ost_nodsh && skip "remote OST with nodsh"
21343
21344         test_fake_rw write
21345 }
21346 run_test 399a "fake write should not be slower than normal write"
21347
21348 test_399b() { # LU-8726 for OST fake read
21349         remote_ost_nodsh && skip "remote OST with nodsh"
21350         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
21351                 skip_env "ldiskfs only test"
21352         fi
21353
21354         test_fake_rw read
21355 }
21356 run_test 399b "fake read should not be slower than normal read"
21357
21358 test_400a() { # LU-1606, was conf-sanity test_74
21359         if ! which $CC > /dev/null 2>&1; then
21360                 skip_env "$CC is not installed"
21361         fi
21362
21363         local extra_flags=''
21364         local out=$TMP/$tfile
21365         local prefix=/usr/include/lustre
21366         local prog
21367
21368         # Oleg removes c files in his test rig so test if any c files exist
21369         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
21370                 skip_env "Needed c test files are missing"
21371
21372         if ! [[ -d $prefix ]]; then
21373                 # Assume we're running in tree and fixup the include path.
21374                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
21375                 extra_flags+=" -L$LUSTRE/utils/.lib"
21376         fi
21377
21378         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
21379                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
21380                         error "client api broken"
21381         done
21382         rm -f $out
21383 }
21384 run_test 400a "Lustre client api program can compile and link"
21385
21386 test_400b() { # LU-1606, LU-5011
21387         local header
21388         local out=$TMP/$tfile
21389         local prefix=/usr/include/linux/lustre
21390
21391         # We use a hard coded prefix so that this test will not fail
21392         # when run in tree. There are headers in lustre/include/lustre/
21393         # that are not packaged (like lustre_idl.h) and have more
21394         # complicated include dependencies (like config.h and lnet/types.h).
21395         # Since this test about correct packaging we just skip them when
21396         # they don't exist (see below) rather than try to fixup cppflags.
21397
21398         if ! which $CC > /dev/null 2>&1; then
21399                 skip_env "$CC is not installed"
21400         fi
21401
21402         for header in $prefix/*.h; do
21403                 if ! [[ -f "$header" ]]; then
21404                         continue
21405                 fi
21406
21407                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
21408                         continue # lustre_ioctl.h is internal header
21409                 fi
21410
21411                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
21412                         error "cannot compile '$header'"
21413         done
21414         rm -f $out
21415 }
21416 run_test 400b "packaged headers can be compiled"
21417
21418 test_401a() { #LU-7437
21419         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
21420         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
21421
21422         #count the number of parameters by "list_param -R"
21423         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
21424         #count the number of parameters by listing proc files
21425         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
21426         echo "proc_dirs='$proc_dirs'"
21427         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
21428         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
21429                       sort -u | wc -l)
21430
21431         [ $params -eq $procs ] ||
21432                 error "found $params parameters vs. $procs proc files"
21433
21434         # test the list_param -D option only returns directories
21435         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
21436         #count the number of parameters by listing proc directories
21437         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
21438                 sort -u | wc -l)
21439
21440         [ $params -eq $procs ] ||
21441                 error "found $params parameters vs. $procs proc files"
21442 }
21443 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
21444
21445 test_401b() {
21446         local save=$($LCTL get_param -n jobid_var)
21447         local tmp=testing
21448
21449         $LCTL set_param foo=bar jobid_var=$tmp bar=baz &&
21450                 error "no error returned when setting bad parameters"
21451
21452         local jobid_new=$($LCTL get_param -n foe jobid_var baz)
21453         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
21454
21455         $LCTL set_param -n fog=bam jobid_var=$save bat=fog
21456         local jobid_old=$($LCTL get_param -n foe jobid_var bag)
21457         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
21458 }
21459 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
21460
21461 test_401c() {
21462         local jobid_var_old=$($LCTL get_param -n jobid_var)
21463         local jobid_var_new
21464
21465         $LCTL set_param jobid_var= &&
21466                 error "no error returned for 'set_param a='"
21467
21468         jobid_var_new=$($LCTL get_param -n jobid_var)
21469         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
21470                 error "jobid_var was changed by setting without value"
21471
21472         $LCTL set_param jobid_var &&
21473                 error "no error returned for 'set_param a'"
21474
21475         jobid_var_new=$($LCTL get_param -n jobid_var)
21476         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
21477                 error "jobid_var was changed by setting without value"
21478 }
21479 run_test 401c "Verify 'lctl set_param' without value fails in either format."
21480
21481 test_401d() {
21482         local jobid_var_old=$($LCTL get_param -n jobid_var)
21483         local jobid_var_new
21484         local new_value="foo=bar"
21485
21486         $LCTL set_param jobid_var=$new_value ||
21487                 error "'set_param a=b' did not accept a value containing '='"
21488
21489         jobid_var_new=$($LCTL get_param -n jobid_var)
21490         [[ "$jobid_var_new" == "$new_value" ]] ||
21491                 error "'set_param a=b' failed on a value containing '='"
21492
21493         # Reset the jobid_var to test the other format
21494         $LCTL set_param jobid_var=$jobid_var_old
21495         jobid_var_new=$($LCTL get_param -n jobid_var)
21496         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
21497                 error "failed to reset jobid_var"
21498
21499         $LCTL set_param jobid_var $new_value ||
21500                 error "'set_param a b' did not accept a value containing '='"
21501
21502         jobid_var_new=$($LCTL get_param -n jobid_var)
21503         [[ "$jobid_var_new" == "$new_value" ]] ||
21504                 error "'set_param a b' failed on a value containing '='"
21505
21506         $LCTL set_param jobid_var $jobid_var_old
21507         jobid_var_new=$($LCTL get_param -n jobid_var)
21508         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
21509                 error "failed to reset jobid_var"
21510 }
21511 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
21512
21513 test_402() {
21514         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
21515         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
21516                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
21517         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
21518                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
21519                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
21520         remote_mds_nodsh && skip "remote MDS with nodsh"
21521
21522         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
21523 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
21524         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
21525         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
21526                 echo "Touch failed - OK"
21527 }
21528 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
21529
21530 test_403() {
21531         local file1=$DIR/$tfile.1
21532         local file2=$DIR/$tfile.2
21533         local tfile=$TMP/$tfile
21534
21535         rm -f $file1 $file2 $tfile
21536
21537         touch $file1
21538         ln $file1 $file2
21539
21540         # 30 sec OBD_TIMEOUT in ll_getattr()
21541         # right before populating st_nlink
21542         $LCTL set_param fail_loc=0x80001409
21543         stat -c %h $file1 > $tfile &
21544
21545         # create an alias, drop all locks and reclaim the dentry
21546         < $file2
21547         cancel_lru_locks mdc
21548         cancel_lru_locks osc
21549         sysctl -w vm.drop_caches=2
21550
21551         wait
21552
21553         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
21554
21555         rm -f $tfile $file1 $file2
21556 }
21557 run_test 403 "i_nlink should not drop to zero due to aliasing"
21558
21559 test_404() { # LU-6601
21560         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
21561                 skip "Need server version newer than 2.8.52"
21562         remote_mds_nodsh && skip "remote MDS with nodsh"
21563
21564         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
21565                 awk '/osp .*-osc-MDT/ { print $4}')
21566
21567         local osp
21568         for osp in $mosps; do
21569                 echo "Deactivate: " $osp
21570                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
21571                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
21572                         awk -vp=$osp '$4 == p { print $2 }')
21573                 [ $stat = IN ] || {
21574                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
21575                         error "deactivate error"
21576                 }
21577                 echo "Activate: " $osp
21578                 do_facet $SINGLEMDS $LCTL --device %$osp activate
21579                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
21580                         awk -vp=$osp '$4 == p { print $2 }')
21581                 [ $stat = UP ] || {
21582                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
21583                         error "activate error"
21584                 }
21585         done
21586 }
21587 run_test 404 "validate manual {de}activated works properly for OSPs"
21588
21589 test_405() {
21590         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
21591         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
21592                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
21593                         skip "Layout swap lock is not supported"
21594
21595         check_swap_layouts_support
21596
21597         test_mkdir $DIR/$tdir
21598         swap_lock_test -d $DIR/$tdir ||
21599                 error "One layout swap locked test failed"
21600 }
21601 run_test 405 "Various layout swap lock tests"
21602
21603 test_406() {
21604         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21605         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
21606         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
21607         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21608         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
21609                 skip "Need MDS version at least 2.8.50"
21610
21611         local def_stripe_size=$($LFS getstripe -S $MOUNT)
21612         local test_pool=$TESTNAME
21613
21614         pool_add $test_pool || error "pool_add failed"
21615         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
21616                 error "pool_add_targets failed"
21617
21618         save_layout_restore_at_exit $MOUNT
21619
21620         # parent set default stripe count only, child will stripe from both
21621         # parent and fs default
21622         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
21623                 error "setstripe $MOUNT failed"
21624         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
21625         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
21626         for i in $(seq 10); do
21627                 local f=$DIR/$tdir/$tfile.$i
21628                 touch $f || error "touch failed"
21629                 local count=$($LFS getstripe -c $f)
21630                 [ $count -eq $OSTCOUNT ] ||
21631                         error "$f stripe count $count != $OSTCOUNT"
21632                 local offset=$($LFS getstripe -i $f)
21633                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
21634                 local size=$($LFS getstripe -S $f)
21635                 [ $size -eq $((def_stripe_size * 2)) ] ||
21636                         error "$f stripe size $size != $((def_stripe_size * 2))"
21637                 local pool=$($LFS getstripe -p $f)
21638                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
21639         done
21640
21641         # change fs default striping, delete parent default striping, now child
21642         # will stripe from new fs default striping only
21643         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
21644                 error "change $MOUNT default stripe failed"
21645         $LFS setstripe -c 0 $DIR/$tdir ||
21646                 error "delete $tdir default stripe failed"
21647         for i in $(seq 11 20); do
21648                 local f=$DIR/$tdir/$tfile.$i
21649                 touch $f || error "touch $f failed"
21650                 local count=$($LFS getstripe -c $f)
21651                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
21652                 local offset=$($LFS getstripe -i $f)
21653                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
21654                 local size=$($LFS getstripe -S $f)
21655                 [ $size -eq $def_stripe_size ] ||
21656                         error "$f stripe size $size != $def_stripe_size"
21657                 local pool=$($LFS getstripe -p $f)
21658                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
21659         done
21660
21661         unlinkmany $DIR/$tdir/$tfile. 1 20
21662
21663         local f=$DIR/$tdir/$tfile
21664         pool_remove_all_targets $test_pool $f
21665         pool_remove $test_pool $f
21666 }
21667 run_test 406 "DNE support fs default striping"
21668
21669 test_407() {
21670         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21671         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
21672                 skip "Need MDS version at least 2.8.55"
21673         remote_mds_nodsh && skip "remote MDS with nodsh"
21674
21675         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
21676                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
21677         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
21678                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
21679         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
21680
21681         #define OBD_FAIL_DT_TXN_STOP    0x2019
21682         for idx in $(seq $MDSCOUNT); do
21683                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
21684         done
21685         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
21686         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
21687                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
21688         true
21689 }
21690 run_test 407 "transaction fail should cause operation fail"
21691
21692 test_408() {
21693         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
21694
21695         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
21696         lctl set_param fail_loc=0x8000040a
21697         # let ll_prepare_partial_page() fail
21698         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
21699
21700         rm -f $DIR/$tfile
21701
21702         # create at least 100 unused inodes so that
21703         # shrink_icache_memory(0) should not return 0
21704         touch $DIR/$tfile-{0..100}
21705         rm -f $DIR/$tfile-{0..100}
21706         sync
21707
21708         echo 2 > /proc/sys/vm/drop_caches
21709 }
21710 run_test 408 "drop_caches should not hang due to page leaks"
21711
21712 test_409()
21713 {
21714         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21715
21716         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
21717         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
21718         touch $DIR/$tdir/guard || error "(2) Fail to create"
21719
21720         local PREFIX=$(str_repeat 'A' 128)
21721         echo "Create 1K hard links start at $(date)"
21722         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
21723                 error "(3) Fail to hard link"
21724
21725         echo "Links count should be right although linkEA overflow"
21726         stat $DIR/$tdir/guard || error "(4) Fail to stat"
21727         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
21728         [ $linkcount -eq 1001 ] ||
21729                 error "(5) Unexpected hard links count: $linkcount"
21730
21731         echo "List all links start at $(date)"
21732         ls -l $DIR/$tdir/foo > /dev/null ||
21733                 error "(6) Fail to list $DIR/$tdir/foo"
21734
21735         echo "Unlink hard links start at $(date)"
21736         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
21737                 error "(7) Fail to unlink"
21738         echo "Unlink hard links finished at $(date)"
21739 }
21740 run_test 409 "Large amount of cross-MDTs hard links on the same file"
21741
21742 test_410()
21743 {
21744         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
21745                 skip "Need client version at least 2.9.59"
21746
21747         # Create a file, and stat it from the kernel
21748         local testfile=$DIR/$tfile
21749         touch $testfile
21750
21751         local run_id=$RANDOM
21752         local my_ino=$(stat --format "%i" $testfile)
21753
21754         # Try to insert the module. This will always fail as the
21755         # module is designed to not be inserted.
21756         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
21757             &> /dev/null
21758
21759         # Anything but success is a test failure
21760         dmesg | grep -q \
21761             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
21762             error "no inode match"
21763 }
21764 run_test 410 "Test inode number returned from kernel thread"
21765
21766 cleanup_test411_cgroup() {
21767         trap 0
21768         rmdir "$1"
21769 }
21770
21771 test_411() {
21772         local cg_basedir=/sys/fs/cgroup/memory
21773         # LU-9966
21774         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
21775                 skip "no setup for cgroup"
21776
21777         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
21778                 error "test file creation failed"
21779         cancel_lru_locks osc
21780
21781         # Create a very small memory cgroup to force a slab allocation error
21782         local cgdir=$cg_basedir/osc_slab_alloc
21783         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
21784         trap "cleanup_test411_cgroup $cgdir" EXIT
21785         echo 2M > $cgdir/memory.kmem.limit_in_bytes
21786         echo 1M > $cgdir/memory.limit_in_bytes
21787
21788         # Should not LBUG, just be killed by oom-killer
21789         # dd will return 0 even allocation failure in some environment.
21790         # So don't check return value
21791         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
21792         cleanup_test411_cgroup $cgdir
21793
21794         return 0
21795 }
21796 run_test 411 "Slab allocation error with cgroup does not LBUG"
21797
21798 test_412() {
21799         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21800         if [ $MDS1_VERSION -lt $(version_code 2.10.55) ]; then
21801                 skip "Need server version at least 2.10.55"
21802         fi
21803
21804         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
21805                 error "mkdir failed"
21806         $LFS getdirstripe $DIR/$tdir
21807         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
21808         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
21809                 error "expect $((MDSCOUT - 1)) get $stripe_index"
21810         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
21811         [ $stripe_count -eq 2 ] ||
21812                 error "expect 2 get $stripe_count"
21813 }
21814 run_test 412 "mkdir on specific MDTs"
21815
21816 test_qos_mkdir() {
21817         local mkdir_cmd=$1
21818         local stripe_count=$2
21819         local mdts=$(comma_list $(mdts_nodes))
21820
21821         local testdir
21822         local lmv_qos_prio_free
21823         local lmv_qos_threshold_rr
21824         local lmv_qos_maxage
21825         local lod_qos_prio_free
21826         local lod_qos_threshold_rr
21827         local lod_qos_maxage
21828         local count
21829         local i
21830
21831         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
21832         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
21833         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
21834                 head -n1)
21835         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
21836         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
21837         stack_trap "$LCTL set_param \
21838                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null" EXIT
21839         stack_trap "$LCTL set_param \
21840                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
21841         stack_trap "$LCTL set_param \
21842                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" EXIT
21843
21844         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
21845                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
21846         lod_qos_prio_free=${lod_qos_prio_free%%%}
21847         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
21848                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
21849         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
21850         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
21851                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
21852         stack_trap "do_nodes $mdts $LCTL set_param \
21853                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null" EXIT
21854         stack_trap "do_nodes $mdts $LCTL set_param \
21855                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null" \
21856                 EXIT
21857         stack_trap "do_nodes $mdts $LCTL set_param \
21858                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" EXIT
21859
21860         echo
21861         echo "Mkdir (stripe_count $stripe_count) roundrobin:"
21862
21863         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
21864         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
21865
21866         testdir=$DIR/$tdir-s$stripe_count/rr
21867
21868         for i in $(seq $((100 * MDSCOUNT))); do
21869                 eval $mkdir_cmd $testdir/subdir$i ||
21870                         error "$mkdir_cmd subdir$i failed"
21871         done
21872
21873         for i in $(seq $MDSCOUNT); do
21874                 count=$($LFS getdirstripe -i $testdir/* |
21875                                 grep ^$((i - 1))$ | wc -l)
21876                 echo "$count directories created on MDT$((i - 1))"
21877                 [ $count -eq 100 ] || error "subdirs are not evenly distributed"
21878
21879                 if [ $stripe_count -gt 1 ]; then
21880                         count=$($LFS getdirstripe $testdir/* |
21881                                 grep -P "^\s+$((i - 1))\t" | wc -l)
21882                         echo "$count stripes created on MDT$((i - 1))"
21883                         # deviation should < 5% of average
21884                         [ $count -lt $((95 * stripe_count)) ] ||
21885                         [ $count -gt $((105 * stripe_count)) ] &&
21886                                 error "stripes are not evenly distributed"
21887                 fi
21888         done
21889
21890         $LCTL set_param lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null
21891         do_nodes $mdts $LCTL set_param \
21892                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null
21893
21894         echo
21895         echo "Check for uneven MDTs: "
21896
21897         local ffree
21898         local bavail
21899         local max
21900         local min
21901         local max_index
21902         local min_index
21903         local tmp
21904
21905         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
21906         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
21907         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
21908
21909         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
21910         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
21911         max_index=0
21912         min_index=0
21913         for ((i = 1; i < ${#ffree[@]}; i++)); do
21914                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
21915                 if [ $tmp -gt $max ]; then
21916                         max=$tmp
21917                         max_index=$i
21918                 fi
21919                 if [ $tmp -lt $min ]; then
21920                         min=$tmp
21921                         min_index=$i
21922                 fi
21923         done
21924
21925         [ ${ffree[min_index]} -eq 0 ] &&
21926                 skip "no free files in MDT$min_index"
21927         [ ${ffree[min_index]} -gt 100000000 ] &&
21928                 skip "too much free files in MDT$min_index"
21929
21930         # Check if we need to generate uneven MDTs
21931         local threshold=50
21932         local diff=$(((max - min) * 100 / min))
21933         local value="$(generate_string 1024)"
21934
21935         while [ $diff -lt $threshold ]; do
21936                 # generate uneven MDTs, create till $threshold% diff
21937                 echo -n "weight diff=$diff% must be > $threshold% ..."
21938                 count=$((${ffree[min_index]} / 10))
21939                 # 50 sec per 10000 files in vm
21940                 [ $count -gt 40000 ] && [ "$SLOW" = "no" ] &&
21941                         skip "$count files to create"
21942                 echo "Fill MDT$min_index with $count files"
21943                 [ -d $DIR/$tdir-MDT$min_index ] ||
21944                         $LFS mkdir -i $min_index $DIR/$tdir-MDT$min_index ||
21945                         error "mkdir $tdir-MDT$min_index failed"
21946                 for i in $(seq $count); do
21947                         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE \
21948                                 $DIR/$tdir-MDT$min_index/f$j_$i > /dev/null ||
21949                                 error "create f$j_$i failed"
21950                         setfattr -n user.413b -v $value \
21951                                 $DIR/$tdir-MDT$min_index/f$j_$i ||
21952                                 error "setfattr f$j_$i failed"
21953                 done
21954
21955                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
21956                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
21957                 max=$(((${ffree[max_index]} >> 8) * \
21958                         (${bavail[max_index]} * bsize >> 16)))
21959                 min=$(((${ffree[min_index]} >> 8) * \
21960                         (${bavail[min_index]} * bsize >> 16)))
21961                 diff=$(((max - min) * 100 / min))
21962         done
21963
21964         echo "MDT filesfree available: ${ffree[@]}"
21965         echo "MDT blocks available: ${bavail[@]}"
21966         echo "weight diff=$diff%"
21967
21968         echo
21969         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
21970
21971         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
21972         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
21973         # decrease statfs age, so that it can be updated in time
21974         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
21975         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
21976
21977         sleep 1
21978
21979         testdir=$DIR/$tdir-s$stripe_count/qos
21980
21981         for i in $(seq $((100 * MDSCOUNT))); do
21982                 eval $mkdir_cmd $testdir/subdir$i ||
21983                         error "$mkdir_cmd subdir$i failed"
21984         done
21985
21986         for i in $(seq $MDSCOUNT); do
21987                 count=$($LFS getdirstripe -i $testdir/* | grep ^$((i - 1))$ |
21988                         wc -l)
21989                 echo "$count directories created on MDT$((i - 1))"
21990
21991                 if [ $stripe_count -gt 1 ]; then
21992                         count=$($LFS getdirstripe $testdir/* |
21993                                 grep -P "^\s+$((i - 1))\t" | wc -l)
21994                         echo "$count stripes created on MDT$((i - 1))"
21995                 fi
21996         done
21997
21998         max=$($LFS getdirstripe -i $testdir/* | grep ^$max_index$ | wc -l)
21999         min=$($LFS getdirstripe -i $testdir/* | grep ^$min_index$ | wc -l)
22000
22001         # D-value should > 10% of averge
22002         [ $((max - min)) -lt 10 ] &&
22003                 error "subdirs shouldn't be evenly distributed"
22004
22005         # ditto
22006         if [ $stripe_count -gt 1 ]; then
22007                 max=$($LFS getdirstripe $testdir/* |
22008                         grep -P "^\s+$max_index\t" | wc -l)
22009                 min=$($LFS getdirstripe $testdir/* |
22010                         grep -P "^\s+$min_index\t" | wc -l)
22011                 [ $((max - min)) -le $((10 * stripe_count)) ] &&
22012                         error "stripes shouldn't be evenly distributed"|| true
22013         fi
22014 }
22015
22016 test_413a() {
22017         [ $MDSCOUNT -lt 2 ] &&
22018                 skip "We need at least 2 MDTs for this test"
22019
22020         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
22021                 skip "Need server version at least 2.12.52"
22022
22023         local stripe_count
22024
22025         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
22026                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
22027                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
22028                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
22029                 test_qos_mkdir "$LFS mkdir -c $stripe_count" $stripe_count
22030         done
22031 }
22032 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
22033
22034 test_413b() {
22035         [ $MDSCOUNT -lt 2 ] &&
22036                 skip "We need at least 2 MDTs for this test"
22037
22038         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
22039                 skip "Need server version at least 2.12.52"
22040
22041         local stripe_count
22042
22043         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
22044                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
22045                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
22046                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
22047                 $LFS setdirstripe -D -c $stripe_count \
22048                         $DIR/$tdir-s$stripe_count/rr ||
22049                         error "setdirstripe failed"
22050                 $LFS setdirstripe -D -c $stripe_count \
22051                         $DIR/$tdir-s$stripe_count/qos ||
22052                         error "setdirstripe failed"
22053                 test_qos_mkdir "mkdir" $stripe_count
22054         done
22055 }
22056 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
22057
22058 test_414() {
22059 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
22060         $LCTL set_param fail_loc=0x80000521
22061         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
22062         rm -f $DIR/$tfile
22063 }
22064 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
22065
22066 test_415() {
22067         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22068         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22069                 skip "Need server version at least 2.11.52"
22070
22071         # LU-11102
22072         local total
22073         local setattr_pid
22074         local start_time
22075         local end_time
22076         local duration
22077
22078         total=500
22079         # this test may be slow on ZFS
22080         [ "$mds1_FSTYPE" == "zfs" ] && total=100
22081
22082         # though this test is designed for striped directory, let's test normal
22083         # directory too since lock is always saved as CoS lock.
22084         test_mkdir $DIR/$tdir || error "mkdir $tdir"
22085         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
22086
22087         (
22088                 while true; do
22089                         touch $DIR/$tdir
22090                 done
22091         ) &
22092         setattr_pid=$!
22093
22094         start_time=$(date +%s)
22095         for i in $(seq $total); do
22096                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
22097                         > /dev/null
22098         done
22099         end_time=$(date +%s)
22100         duration=$((end_time - start_time))
22101
22102         kill -9 $setattr_pid
22103
22104         echo "rename $total files took $duration sec"
22105         [ $duration -lt 100 ] || error "rename took $duration sec"
22106 }
22107 run_test 415 "lock revoke is not missing"
22108
22109 test_416() {
22110         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
22111                 skip "Need server version at least 2.11.55"
22112
22113         # define OBD_FAIL_OSD_TXN_START    0x19a
22114         do_facet mds1 lctl set_param fail_loc=0x19a
22115
22116         lfs mkdir -c $MDSCOUNT $DIR/$tdir
22117
22118         true
22119 }
22120 run_test 416 "transaction start failure won't cause system hung"
22121
22122 cleanup_417() {
22123         trap 0
22124         do_nodes $(comma_list $(mdts_nodes)) \
22125                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
22126         do_nodes $(comma_list $(mdts_nodes)) \
22127                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
22128         do_nodes $(comma_list $(mdts_nodes)) \
22129                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
22130 }
22131
22132 test_417() {
22133         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22134         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
22135                 skip "Need MDS version at least 2.11.56"
22136
22137         trap cleanup_417 RETURN EXIT
22138
22139         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
22140         do_nodes $(comma_list $(mdts_nodes)) \
22141                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
22142         $LFS migrate -m 0 $DIR/$tdir.1 &&
22143                 error "migrate dir $tdir.1 should fail"
22144
22145         do_nodes $(comma_list $(mdts_nodes)) \
22146                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
22147         $LFS mkdir -i 1 $DIR/$tdir.2 &&
22148                 error "create remote dir $tdir.2 should fail"
22149
22150         do_nodes $(comma_list $(mdts_nodes)) \
22151                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
22152         $LFS mkdir -c 2 $DIR/$tdir.3 &&
22153                 error "create striped dir $tdir.3 should fail"
22154         true
22155 }
22156 run_test 417 "disable remote dir, striped dir and dir migration"
22157
22158 # Checks that the outputs of df [-i] and lfs df [-i] match
22159 #
22160 # usage: check_lfs_df <blocks | inodes> <mountpoint>
22161 check_lfs_df() {
22162         local dir=$2
22163         local inodes
22164         local df_out
22165         local lfs_df_out
22166         local count
22167         local passed=false
22168
22169         # blocks or inodes
22170         [ "$1" == "blocks" ] && inodes= || inodes="-i"
22171
22172         for count in {1..100}; do
22173                 cancel_lru_locks
22174                 sync; sleep 0.2
22175
22176                 # read the lines of interest
22177                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
22178                         error "df $inodes $dir | tail -n +2 failed"
22179                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
22180                         error "lfs df $inodes $dir | grep summary: failed"
22181
22182                 # skip first substrings of each output as they are different
22183                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
22184                 # compare the two outputs
22185                 passed=true
22186                 for i in {1..5}; do
22187                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
22188                 done
22189                 $passed && break
22190         done
22191
22192         if ! $passed; then
22193                 df -P $inodes $dir
22194                 echo
22195                 lfs df $inodes $dir
22196                 error "df and lfs df $1 output mismatch: "      \
22197                       "df ${inodes}: ${df_out[*]}, "            \
22198                       "lfs df ${inodes}: ${lfs_df_out[*]}"
22199         fi
22200 }
22201
22202 test_418() {
22203         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22204
22205         local dir=$DIR/$tdir
22206         local numfiles=$((RANDOM % 4096 + 2))
22207         local numblocks=$((RANDOM % 256 + 1))
22208
22209         wait_delete_completed
22210         test_mkdir $dir
22211
22212         # check block output
22213         check_lfs_df blocks $dir
22214         # check inode output
22215         check_lfs_df inodes $dir
22216
22217         # create a single file and retest
22218         echo "Creating a single file and testing"
22219         createmany -o $dir/$tfile- 1 &>/dev/null ||
22220                 error "creating 1 file in $dir failed"
22221         check_lfs_df blocks $dir
22222         check_lfs_df inodes $dir
22223
22224         # create a random number of files
22225         echo "Creating $((numfiles - 1)) files and testing"
22226         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
22227                 error "creating $((numfiles - 1)) files in $dir failed"
22228
22229         # write a random number of blocks to the first test file
22230         echo "Writing $numblocks 4K blocks and testing"
22231         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
22232                 count=$numblocks &>/dev/null ||
22233                 error "dd to $dir/${tfile}-0 failed"
22234
22235         # retest
22236         check_lfs_df blocks $dir
22237         check_lfs_df inodes $dir
22238
22239         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
22240                 error "unlinking $numfiles files in $dir failed"
22241 }
22242 run_test 418 "df and lfs df outputs match"
22243
22244 test_419()
22245 {
22246         local dir=$DIR/$tdir
22247
22248         mkdir -p $dir
22249         touch $dir/file
22250
22251         cancel_lru_locks mdc
22252
22253         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
22254         $LCTL set_param fail_loc=0x1410
22255         cat $dir/file
22256         $LCTL set_param fail_loc=0
22257         rm -rf $dir
22258 }
22259 run_test 419 "Verify open file by name doesn't crash kernel"
22260
22261 test_420()
22262 {
22263         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
22264                 skip "Need MDS version at least 2.12.53"
22265
22266         local SAVE_UMASK=$(umask)
22267         local dir=$DIR/$tdir
22268         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
22269
22270         mkdir -p $dir
22271         umask 0000
22272         mkdir -m03777 $dir/testdir
22273         ls -dn $dir/testdir
22274         # Need to remove trailing '.' when SELinux is enabled
22275         local dirperms=$(ls -dn $dir/testdir |
22276                          awk '{ sub(/\.$/, "", $1); print $1}')
22277         [ $dirperms == "drwxrwsrwt" ] ||
22278                 error "incorrect perms on $dir/testdir"
22279
22280         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
22281                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
22282         ls -n $dir/testdir/testfile
22283         local fileperms=$(ls -n $dir/testdir/testfile |
22284                           awk '{ sub(/\.$/, "", $1); print $1}')
22285         [ $fileperms == "-rwxr-xr-x" ] ||
22286                 error "incorrect perms on $dir/testdir/testfile"
22287
22288         umask $SAVE_UMASK
22289 }
22290 run_test 420 "clear SGID bit on non-directories for non-members"
22291
22292 test_421a() {
22293         local cnt
22294         local fid1
22295         local fid2
22296
22297         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
22298                 skip "Need MDS version at least 2.12.54"
22299
22300         test_mkdir $DIR/$tdir
22301         createmany -o $DIR/$tdir/f 3
22302         cnt=$(ls -1 $DIR/$tdir | wc -l)
22303         [ $cnt != 3 ] && error "unexpected #files: $cnt"
22304
22305         fid1=$(lfs path2fid $DIR/$tdir/f1)
22306         fid2=$(lfs path2fid $DIR/$tdir/f2)
22307         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
22308
22309         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
22310         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
22311
22312         cnt=$(ls -1 $DIR/$tdir | wc -l)
22313         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
22314
22315         rm -f $DIR/$tdir/f3 || error "can't remove f3"
22316         createmany -o $DIR/$tdir/f 3
22317         cnt=$(ls -1 $DIR/$tdir | wc -l)
22318         [ $cnt != 3 ] && error "unexpected #files: $cnt"
22319
22320         fid1=$(lfs path2fid $DIR/$tdir/f1)
22321         fid2=$(lfs path2fid $DIR/$tdir/f2)
22322         echo "remove using fsname $FSNAME"
22323         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
22324
22325         cnt=$(ls -1 $DIR/$tdir | wc -l)
22326         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
22327 }
22328 run_test 421a "simple rm by fid"
22329
22330 test_421b() {
22331         local cnt
22332         local FID1
22333         local FID2
22334
22335         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
22336                 skip "Need MDS version at least 2.12.54"
22337
22338         test_mkdir $DIR/$tdir
22339         createmany -o $DIR/$tdir/f 3
22340         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
22341         MULTIPID=$!
22342
22343         FID1=$(lfs path2fid $DIR/$tdir/f1)
22344         FID2=$(lfs path2fid $DIR/$tdir/f2)
22345         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
22346
22347         kill -USR1 $MULTIPID
22348         wait
22349
22350         cnt=$(ls $DIR/$tdir | wc -l)
22351         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
22352 }
22353 run_test 421b "rm by fid on open file"
22354
22355 test_421c() {
22356         local cnt
22357         local FIDS
22358
22359         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
22360                 skip "Need MDS version at least 2.12.54"
22361
22362         test_mkdir $DIR/$tdir
22363         createmany -o $DIR/$tdir/f 3
22364         touch $DIR/$tdir/$tfile
22365         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
22366         cnt=$(ls -1 $DIR/$tdir | wc -l)
22367         [ $cnt != 184 ] && error "unexpected #files: $cnt"
22368
22369         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
22370         $LFS rmfid $DIR $FID1 || error "rmfid failed"
22371
22372         cnt=$(ls $DIR/$tdir | wc -l)
22373         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
22374 }
22375 run_test 421c "rm by fid against hardlinked files"
22376
22377 test_421d() {
22378         local cnt
22379         local FIDS
22380
22381         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
22382                 skip "Need MDS version at least 2.12.54"
22383
22384         test_mkdir $DIR/$tdir
22385         createmany -o $DIR/$tdir/f 4097
22386         cnt=$(ls -1 $DIR/$tdir | wc -l)
22387         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
22388
22389         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
22390         $LFS rmfid $DIR $FIDS || error "rmfid failed"
22391
22392         cnt=$(ls $DIR/$tdir | wc -l)
22393         rm -rf $DIR/$tdir
22394         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
22395 }
22396 run_test 421d "rmfid en masse"
22397
22398 test_421e() {
22399         local cnt
22400         local FID
22401
22402         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22403         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
22404                 skip "Need MDS version at least 2.12.54"
22405
22406         mkdir -p $DIR/$tdir
22407         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
22408         createmany -o $DIR/$tdir/striped_dir/f 512
22409         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
22410         [ $cnt != 512 ] && error "unexpected #files: $cnt"
22411
22412         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
22413                 sed "s/[/][^:]*://g")
22414         $LFS rmfid $DIR $FIDS || error "rmfid failed"
22415
22416         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
22417         rm -rf $DIR/$tdir
22418         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
22419 }
22420 run_test 421e "rmfid in DNE"
22421
22422 test_421f() {
22423         local cnt
22424         local FID
22425
22426         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
22427                 skip "Need MDS version at least 2.12.54"
22428
22429         test_mkdir $DIR/$tdir
22430         touch $DIR/$tdir/f
22431         cnt=$(ls -1 $DIR/$tdir | wc -l)
22432         [ $cnt != 1 ] && error "unexpected #files: $cnt"
22433
22434         FID=$(lfs path2fid $DIR/$tdir/f)
22435         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
22436         # rmfid should fail
22437         cnt=$(ls -1 $DIR/$tdir | wc -l)
22438         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
22439
22440         chmod a+rw $DIR/$tdir
22441         ls -la $DIR/$tdir
22442         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
22443         # rmfid should fail
22444         cnt=$(ls -1 $DIR/$tdir | wc -l)
22445         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
22446
22447         rm -f $DIR/$tdir/f
22448         $RUNAS touch $DIR/$tdir/f
22449         FID=$(lfs path2fid $DIR/$tdir/f)
22450         echo "rmfid as root"
22451         $LFS rmfid $DIR $FID || error "rmfid as root failed"
22452         cnt=$(ls -1 $DIR/$tdir | wc -l)
22453         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
22454
22455         rm -f $DIR/$tdir/f
22456         $RUNAS touch $DIR/$tdir/f
22457         cnt=$(ls -1 $DIR/$tdir | wc -l)
22458         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
22459         FID=$(lfs path2fid $DIR/$tdir/f)
22460         # rmfid w/o user_fid2path mount option should fail
22461         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
22462         cnt=$(ls -1 $DIR/$tdir | wc -l)
22463         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
22464
22465         umount_client $MOUNT || error "failed to umount client"
22466         mount_client $MOUNT "$MOUNT_OPTS,user_fid2path" ||
22467                 error "failed to mount client'"
22468
22469         $RUNAS $LFS rmfid $DIR $FID || error "rmfid failed"
22470         # rmfid should succeed
22471         cnt=$(ls -1 $DIR/$tdir | wc -l)
22472         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
22473
22474         # rmfid shouldn't allow to remove files due to dir's permission
22475         chmod a+rwx $DIR/$tdir
22476         touch $DIR/$tdir/f
22477         ls -la $DIR/$tdir
22478         FID=$(lfs path2fid $DIR/$tdir/f)
22479         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail"
22480
22481         umount_client $MOUNT || error "failed to umount client"
22482         mount_client $MOUNT "$MOUNT_OPTS" ||
22483                 error "failed to mount client'"
22484
22485 }
22486 run_test 421f "rmfid checks permissions"
22487
22488 test_421g() {
22489         local cnt
22490         local FIDS
22491
22492         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22493         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
22494                 skip "Need MDS version at least 2.12.54"
22495
22496         mkdir -p $DIR/$tdir
22497         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
22498         createmany -o $DIR/$tdir/striped_dir/f 512
22499         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
22500         [ $cnt != 512 ] && error "unexpected #files: $cnt"
22501
22502         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
22503                 sed "s/[/][^:]*://g")
22504
22505         rm -f $DIR/$tdir/striped_dir/f1*
22506         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
22507         removed=$((512 - cnt))
22508
22509         # few files have been just removed, so we expect
22510         # rmfid to fail on their fids
22511         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
22512         [ $removed != $errors ] && error "$errors != $removed"
22513
22514         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
22515         rm -rf $DIR/$tdir
22516         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
22517 }
22518 run_test 421g "rmfid to return errors properly"
22519
22520 test_422() {
22521         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
22522         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
22523         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
22524         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
22525         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
22526
22527         local amc=$(at_max_get client)
22528         local amo=$(at_max_get mds1)
22529         local timeout=`lctl get_param -n timeout`
22530
22531         at_max_set 0 client
22532         at_max_set 0 mds1
22533
22534 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
22535         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
22536                         fail_val=$(((2*timeout + 10)*1000))
22537         touch $DIR/$tdir/d3/file &
22538         sleep 2
22539 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
22540         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
22541                         fail_val=$((2*timeout + 5))
22542         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
22543         local pid=$!
22544         sleep 1
22545         kill -9 $pid
22546         sleep $((2 * timeout))
22547         echo kill $pid
22548         kill -9 $pid
22549         lctl mark touch
22550         touch $DIR/$tdir/d2/file3
22551         touch $DIR/$tdir/d2/file4
22552         touch $DIR/$tdir/d2/file5
22553
22554         wait
22555         at_max_set $amc client
22556         at_max_set $amo mds1
22557
22558         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
22559         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
22560                 error "Watchdog is always throttled"
22561 }
22562 run_test 422 "kill a process with RPC in progress"
22563
22564 stat_test() {
22565     df -h $MOUNT &
22566     df -h $MOUNT &
22567     df -h $MOUNT &
22568     df -h $MOUNT &
22569     df -h $MOUNT &
22570     df -h $MOUNT &
22571 }
22572
22573 test_423() {
22574     local _stats
22575     # ensure statfs cache is expired
22576     sleep 2;
22577
22578     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
22579     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
22580
22581     return 0
22582 }
22583 run_test 423 "statfs should return a right data"
22584
22585 prep_801() {
22586         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
22587         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
22588                 skip "Need server version at least 2.9.55"
22589
22590         start_full_debug_logging
22591 }
22592
22593 post_801() {
22594         stop_full_debug_logging
22595 }
22596
22597 barrier_stat() {
22598         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
22599                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
22600                            awk '/The barrier for/ { print $7 }')
22601                 echo $st
22602         else
22603                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
22604                 echo \'$st\'
22605         fi
22606 }
22607
22608 barrier_expired() {
22609         local expired
22610
22611         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
22612                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
22613                           awk '/will be expired/ { print $7 }')
22614         else
22615                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
22616         fi
22617
22618         echo $expired
22619 }
22620
22621 test_801a() {
22622         prep_801
22623
22624         echo "Start barrier_freeze at: $(date)"
22625         #define OBD_FAIL_BARRIER_DELAY          0x2202
22626         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
22627         # Do not reduce barrier time - See LU-11873
22628         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
22629
22630         sleep 2
22631         local b_status=$(barrier_stat)
22632         echo "Got barrier status at: $(date)"
22633         [ "$b_status" = "'freezing_p1'" ] ||
22634                 error "(1) unexpected barrier status $b_status"
22635
22636         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
22637         wait
22638         b_status=$(barrier_stat)
22639         [ "$b_status" = "'frozen'" ] ||
22640                 error "(2) unexpected barrier status $b_status"
22641
22642         local expired=$(barrier_expired)
22643         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
22644         sleep $((expired + 3))
22645
22646         b_status=$(barrier_stat)
22647         [ "$b_status" = "'expired'" ] ||
22648                 error "(3) unexpected barrier status $b_status"
22649
22650         # Do not reduce barrier time - See LU-11873
22651         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
22652                 error "(4) fail to freeze barrier"
22653
22654         b_status=$(barrier_stat)
22655         [ "$b_status" = "'frozen'" ] ||
22656                 error "(5) unexpected barrier status $b_status"
22657
22658         echo "Start barrier_thaw at: $(date)"
22659         #define OBD_FAIL_BARRIER_DELAY          0x2202
22660         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
22661         do_facet mgs $LCTL barrier_thaw $FSNAME &
22662
22663         sleep 2
22664         b_status=$(barrier_stat)
22665         echo "Got barrier status at: $(date)"
22666         [ "$b_status" = "'thawing'" ] ||
22667                 error "(6) unexpected barrier status $b_status"
22668
22669         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
22670         wait
22671         b_status=$(barrier_stat)
22672         [ "$b_status" = "'thawed'" ] ||
22673                 error "(7) unexpected barrier status $b_status"
22674
22675         #define OBD_FAIL_BARRIER_FAILURE        0x2203
22676         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
22677         do_facet mgs $LCTL barrier_freeze $FSNAME
22678
22679         b_status=$(barrier_stat)
22680         [ "$b_status" = "'failed'" ] ||
22681                 error "(8) unexpected barrier status $b_status"
22682
22683         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
22684         do_facet mgs $LCTL barrier_thaw $FSNAME
22685
22686         post_801
22687 }
22688 run_test 801a "write barrier user interfaces and stat machine"
22689
22690 test_801b() {
22691         prep_801
22692
22693         mkdir $DIR/$tdir || error "(1) fail to mkdir"
22694         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
22695         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
22696         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
22697         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
22698
22699         cancel_lru_locks mdc
22700
22701         # 180 seconds should be long enough
22702         do_facet mgs $LCTL barrier_freeze $FSNAME 180
22703
22704         local b_status=$(barrier_stat)
22705         [ "$b_status" = "'frozen'" ] ||
22706                 error "(6) unexpected barrier status $b_status"
22707
22708         mkdir $DIR/$tdir/d0/d10 &
22709         mkdir_pid=$!
22710
22711         touch $DIR/$tdir/d1/f13 &
22712         touch_pid=$!
22713
22714         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
22715         ln_pid=$!
22716
22717         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
22718         mv_pid=$!
22719
22720         rm -f $DIR/$tdir/d4/f12 &
22721         rm_pid=$!
22722
22723         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
22724
22725         # To guarantee taht the 'stat' is not blocked
22726         b_status=$(barrier_stat)
22727         [ "$b_status" = "'frozen'" ] ||
22728                 error "(8) unexpected barrier status $b_status"
22729
22730         # let above commands to run at background
22731         sleep 5
22732
22733         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
22734         ps -p $touch_pid || error "(10) touch should be blocked"
22735         ps -p $ln_pid || error "(11) link should be blocked"
22736         ps -p $mv_pid || error "(12) rename should be blocked"
22737         ps -p $rm_pid || error "(13) unlink should be blocked"
22738
22739         b_status=$(barrier_stat)
22740         [ "$b_status" = "'frozen'" ] ||
22741                 error "(14) unexpected barrier status $b_status"
22742
22743         do_facet mgs $LCTL barrier_thaw $FSNAME
22744         b_status=$(barrier_stat)
22745         [ "$b_status" = "'thawed'" ] ||
22746                 error "(15) unexpected barrier status $b_status"
22747
22748         wait $mkdir_pid || error "(16) mkdir should succeed"
22749         wait $touch_pid || error "(17) touch should succeed"
22750         wait $ln_pid || error "(18) link should succeed"
22751         wait $mv_pid || error "(19) rename should succeed"
22752         wait $rm_pid || error "(20) unlink should succeed"
22753
22754         post_801
22755 }
22756 run_test 801b "modification will be blocked by write barrier"
22757
22758 test_801c() {
22759         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
22760
22761         prep_801
22762
22763         stop mds2 || error "(1) Fail to stop mds2"
22764
22765         do_facet mgs $LCTL barrier_freeze $FSNAME 30
22766
22767         local b_status=$(barrier_stat)
22768         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
22769                 do_facet mgs $LCTL barrier_thaw $FSNAME
22770                 error "(2) unexpected barrier status $b_status"
22771         }
22772
22773         do_facet mgs $LCTL barrier_rescan $FSNAME ||
22774                 error "(3) Fail to rescan barrier bitmap"
22775
22776         # Do not reduce barrier time - See LU-11873
22777         do_facet mgs $LCTL barrier_freeze $FSNAME 20
22778
22779         b_status=$(barrier_stat)
22780         [ "$b_status" = "'frozen'" ] ||
22781                 error "(4) unexpected barrier status $b_status"
22782
22783         do_facet mgs $LCTL barrier_thaw $FSNAME
22784         b_status=$(barrier_stat)
22785         [ "$b_status" = "'thawed'" ] ||
22786                 error "(5) unexpected barrier status $b_status"
22787
22788         local devname=$(mdsdevname 2)
22789
22790         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
22791
22792         do_facet mgs $LCTL barrier_rescan $FSNAME ||
22793                 error "(7) Fail to rescan barrier bitmap"
22794
22795         post_801
22796 }
22797 run_test 801c "rescan barrier bitmap"
22798
22799 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
22800 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
22801 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
22802 saved_MOUNT_OPTS=$MOUNT_OPTS
22803
22804 cleanup_802a() {
22805         trap 0
22806
22807         stopall
22808         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
22809         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
22810         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
22811         MOUNT_OPTS=$saved_MOUNT_OPTS
22812         setupall
22813 }
22814
22815 test_802a() {
22816         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
22817         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
22818         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
22819                 skip "Need server version at least 2.9.55"
22820
22821         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
22822
22823         mkdir $DIR/$tdir || error "(1) fail to mkdir"
22824
22825         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
22826                 error "(2) Fail to copy"
22827
22828         trap cleanup_802a EXIT
22829
22830         # sync by force before remount as readonly
22831         sync; sync_all_data; sleep 3; sync_all_data
22832
22833         stopall
22834
22835         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
22836         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
22837         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
22838
22839         echo "Mount the server as read only"
22840         setupall server_only || error "(3) Fail to start servers"
22841
22842         echo "Mount client without ro should fail"
22843         mount_client $MOUNT &&
22844                 error "(4) Mount client without 'ro' should fail"
22845
22846         echo "Mount client with ro should succeed"
22847         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
22848         mount_client $MOUNT ||
22849                 error "(5) Mount client with 'ro' should succeed"
22850
22851         echo "Modify should be refused"
22852         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
22853
22854         echo "Read should be allowed"
22855         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
22856                 error "(7) Read should succeed under ro mode"
22857
22858         cleanup_802a
22859 }
22860 run_test 802a "simulate readonly device"
22861
22862 test_802b() {
22863         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22864         remote_mds_nodsh && skip "remote MDS with nodsh"
22865
22866         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
22867                 skip "readonly option not available"
22868
22869         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
22870
22871         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
22872                 error "(2) Fail to copy"
22873
22874         # write back all cached data before setting MDT to readonly
22875         cancel_lru_locks
22876         sync_all_data
22877
22878         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
22879         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
22880
22881         echo "Modify should be refused"
22882         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
22883
22884         echo "Read should be allowed"
22885         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
22886                 error "(7) Read should succeed under ro mode"
22887
22888         # disable readonly
22889         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
22890 }
22891 run_test 802b "be able to set MDTs to readonly"
22892
22893 test_803() {
22894         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
22895         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
22896                 skip "MDS needs to be newer than 2.10.54"
22897
22898         mkdir -p $DIR/$tdir
22899         # Create some objects on all MDTs to trigger related logs objects
22900         for idx in $(seq $MDSCOUNT); do
22901                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
22902                         $DIR/$tdir/dir${idx} ||
22903                         error "Fail to create $DIR/$tdir/dir${idx}"
22904         done
22905
22906         sync; sleep 3
22907         wait_delete_completed # ensure old test cleanups are finished
22908         echo "before create:"
22909         $LFS df -i $MOUNT
22910         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
22911
22912         for i in {1..10}; do
22913                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
22914                         error "Fail to create $DIR/$tdir/foo$i"
22915         done
22916
22917         sync; sleep 3
22918         echo "after create:"
22919         $LFS df -i $MOUNT
22920         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
22921
22922         # allow for an llog to be cleaned up during the test
22923         [ $after_used -ge $((before_used + 10 - 1)) ] ||
22924                 error "before ($before_used) + 10 > after ($after_used)"
22925
22926         for i in {1..10}; do
22927                 rm -rf $DIR/$tdir/foo$i ||
22928                         error "Fail to remove $DIR/$tdir/foo$i"
22929         done
22930
22931         sleep 3 # avoid MDT return cached statfs
22932         wait_delete_completed
22933         echo "after unlink:"
22934         $LFS df -i $MOUNT
22935         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
22936
22937         # allow for an llog to be created during the test
22938         [ $after_used -le $((before_used + 1)) ] ||
22939                 error "after ($after_used) > before ($before_used) + 1"
22940 }
22941 run_test 803 "verify agent object for remote object"
22942
22943 test_804() {
22944         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
22945         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
22946                 skip "MDS needs to be newer than 2.10.54"
22947         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
22948
22949         mkdir -p $DIR/$tdir
22950         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
22951                 error "Fail to create $DIR/$tdir/dir0"
22952
22953         local fid=$($LFS path2fid $DIR/$tdir/dir0)
22954         local dev=$(mdsdevname 2)
22955
22956         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
22957                 grep ${fid} || error "NOT found agent entry for dir0"
22958
22959         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
22960                 error "Fail to create $DIR/$tdir/dir1"
22961
22962         touch $DIR/$tdir/dir1/foo0 ||
22963                 error "Fail to create $DIR/$tdir/dir1/foo0"
22964         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
22965         local rc=0
22966
22967         for idx in $(seq $MDSCOUNT); do
22968                 dev=$(mdsdevname $idx)
22969                 do_facet mds${idx} \
22970                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
22971                         grep ${fid} && rc=$idx
22972         done
22973
22974         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
22975                 error "Fail to rename foo0 to foo1"
22976         if [ $rc -eq 0 ]; then
22977                 for idx in $(seq $MDSCOUNT); do
22978                         dev=$(mdsdevname $idx)
22979                         do_facet mds${idx} \
22980                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
22981                         grep ${fid} && rc=$idx
22982                 done
22983         fi
22984
22985         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
22986                 error "Fail to rename foo1 to foo2"
22987         if [ $rc -eq 0 ]; then
22988                 for idx in $(seq $MDSCOUNT); do
22989                         dev=$(mdsdevname $idx)
22990                         do_facet mds${idx} \
22991                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
22992                         grep ${fid} && rc=$idx
22993                 done
22994         fi
22995
22996         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
22997
22998         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
22999                 error "Fail to link to $DIR/$tdir/dir1/foo2"
23000         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
23001                 error "Fail to rename foo2 to foo0"
23002         unlink $DIR/$tdir/dir1/foo0 ||
23003                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
23004         rm -rf $DIR/$tdir/dir0 ||
23005                 error "Fail to rm $DIR/$tdir/dir0"
23006
23007         for idx in $(seq $MDSCOUNT); do
23008                 dev=$(mdsdevname $idx)
23009                 rc=0
23010
23011                 stop mds${idx}
23012                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
23013                         rc=$?
23014                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
23015                         error "mount mds$idx failed"
23016                 df $MOUNT > /dev/null 2>&1
23017
23018                 # e2fsck should not return error
23019                 [ $rc -eq 0 ] ||
23020                         error "e2fsck detected error on MDT${idx}: rc=$rc"
23021         done
23022 }
23023 run_test 804 "verify agent entry for remote entry"
23024
23025 cleanup_805() {
23026         do_facet $SINGLEMDS zfs set quota=$old $fsset
23027         unlinkmany $DIR/$tdir/f- 1000000
23028         trap 0
23029 }
23030
23031 test_805() {
23032         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
23033         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
23034         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
23035                 skip "netfree not implemented before 0.7"
23036         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
23037                 skip "Need MDS version at least 2.10.57"
23038
23039         local fsset
23040         local freekb
23041         local usedkb
23042         local old
23043         local quota
23044         local pref="osd-zfs.$FSNAME-MDT0000."
23045
23046         # limit available space on MDS dataset to meet nospace issue
23047         # quickly. then ZFS 0.7.2 can use reserved space if asked
23048         # properly (using netfree flag in osd_declare_destroy()
23049         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
23050         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
23051                 gawk '{print $3}')
23052         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
23053         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
23054         let "usedkb=usedkb-freekb"
23055         let "freekb=freekb/2"
23056         if let "freekb > 5000"; then
23057                 let "freekb=5000"
23058         fi
23059         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
23060         trap cleanup_805 EXIT
23061         mkdir $DIR/$tdir
23062         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
23063                 error "Can't set PFL layout"
23064         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
23065         rm -rf $DIR/$tdir || error "not able to remove"
23066         do_facet $SINGLEMDS zfs set quota=$old $fsset
23067         trap 0
23068 }
23069 run_test 805 "ZFS can remove from full fs"
23070
23071 # Size-on-MDS test
23072 check_lsom_data()
23073 {
23074         local file=$1
23075         local size=$($LFS getsom -s $file)
23076         local expect=$(stat -c %s $file)
23077
23078         [[ $size == $expect ]] ||
23079                 error "$file expected size: $expect, got: $size"
23080
23081         local blocks=$($LFS getsom -b $file)
23082         expect=$(stat -c %b $file)
23083         [[ $blocks == $expect ]] ||
23084                 error "$file expected blocks: $expect, got: $blocks"
23085 }
23086
23087 check_lsom_size()
23088 {
23089         local size=$($LFS getsom -s $1)
23090         local expect=$2
23091
23092         [[ $size == $expect ]] ||
23093                 error "$file expected size: $expect, got: $size"
23094 }
23095
23096 test_806() {
23097         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
23098                 skip "Need MDS version at least 2.11.52"
23099
23100         local bs=1048576
23101
23102         touch $DIR/$tfile || error "touch $tfile failed"
23103
23104         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23105         save_lustre_params client "llite.*.xattr_cache" > $save
23106         lctl set_param llite.*.xattr_cache=0
23107         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23108
23109         # single-threaded write
23110         echo "Test SOM for single-threaded write"
23111         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
23112                 error "write $tfile failed"
23113         check_lsom_size $DIR/$tfile $bs
23114
23115         local num=32
23116         local size=$(($num * $bs))
23117         local offset=0
23118         local i
23119
23120         echo "Test SOM for single client multi-threaded($num) write"
23121         $TRUNCATE $DIR/$tfile 0
23122         for ((i = 0; i < $num; i++)); do
23123                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
23124                 local pids[$i]=$!
23125                 offset=$((offset + $bs))
23126         done
23127         for (( i=0; i < $num; i++ )); do
23128                 wait ${pids[$i]}
23129         done
23130         check_lsom_size $DIR/$tfile $size
23131
23132         $TRUNCATE $DIR/$tfile 0
23133         for ((i = 0; i < $num; i++)); do
23134                 offset=$((offset - $bs))
23135                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
23136                 local pids[$i]=$!
23137         done
23138         for (( i=0; i < $num; i++ )); do
23139                 wait ${pids[$i]}
23140         done
23141         check_lsom_size $DIR/$tfile $size
23142
23143         # multi-client writes
23144         num=$(get_node_count ${CLIENTS//,/ })
23145         size=$(($num * $bs))
23146         offset=0
23147         i=0
23148
23149         echo "Test SOM for multi-client ($num) writes"
23150         $TRUNCATE $DIR/$tfile 0
23151         for client in ${CLIENTS//,/ }; do
23152                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
23153                 local pids[$i]=$!
23154                 i=$((i + 1))
23155                 offset=$((offset + $bs))
23156         done
23157         for (( i=0; i < $num; i++ )); do
23158                 wait ${pids[$i]}
23159         done
23160         check_lsom_size $DIR/$tfile $offset
23161
23162         i=0
23163         $TRUNCATE $DIR/$tfile 0
23164         for client in ${CLIENTS//,/ }; do
23165                 offset=$((offset - $bs))
23166                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
23167                 local pids[$i]=$!
23168                 i=$((i + 1))
23169         done
23170         for (( i=0; i < $num; i++ )); do
23171                 wait ${pids[$i]}
23172         done
23173         check_lsom_size $DIR/$tfile $size
23174
23175         # verify truncate
23176         echo "Test SOM for truncate"
23177         $TRUNCATE $DIR/$tfile 1048576
23178         check_lsom_size $DIR/$tfile 1048576
23179         $TRUNCATE $DIR/$tfile 1234
23180         check_lsom_size $DIR/$tfile 1234
23181
23182         # verify SOM blocks count
23183         echo "Verify SOM block count"
23184         $TRUNCATE $DIR/$tfile 0
23185         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
23186                 error "failed to write file $tfile"
23187         check_lsom_data $DIR/$tfile
23188 }
23189 run_test 806 "Verify Lazy Size on MDS"
23190
23191 test_807() {
23192         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
23193         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
23194                 skip "Need MDS version at least 2.11.52"
23195
23196         # Registration step
23197         changelog_register || error "changelog_register failed"
23198         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
23199         changelog_users $SINGLEMDS | grep -q $cl_user ||
23200                 error "User $cl_user not found in changelog_users"
23201
23202         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23203         save_lustre_params client "llite.*.xattr_cache" > $save
23204         lctl set_param llite.*.xattr_cache=0
23205         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23206
23207         rm -rf $DIR/$tdir || error "rm $tdir failed"
23208         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
23209         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
23210         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
23211         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
23212                 error "truncate $tdir/trunc failed"
23213
23214         local bs=1048576
23215         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
23216                 error "write $tfile failed"
23217
23218         # multi-client wirtes
23219         local num=$(get_node_count ${CLIENTS//,/ })
23220         local offset=0
23221         local i=0
23222
23223         echo "Test SOM for multi-client ($num) writes"
23224         touch $DIR/$tfile || error "touch $tfile failed"
23225         $TRUNCATE $DIR/$tfile 0
23226         for client in ${CLIENTS//,/ }; do
23227                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
23228                 local pids[$i]=$!
23229                 i=$((i + 1))
23230                 offset=$((offset + $bs))
23231         done
23232         for (( i=0; i < $num; i++ )); do
23233                 wait ${pids[$i]}
23234         done
23235
23236         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
23237         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
23238         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
23239         check_lsom_data $DIR/$tdir/trunc
23240         check_lsom_data $DIR/$tdir/single_dd
23241         check_lsom_data $DIR/$tfile
23242
23243         rm -rf $DIR/$tdir
23244         # Deregistration step
23245         changelog_deregister || error "changelog_deregister failed"
23246 }
23247 run_test 807 "verify LSOM syncing tool"
23248
23249 check_som_nologged()
23250 {
23251         local lines=$($LFS changelog $FSNAME-MDT0000 |
23252                 grep 'x=trusted.som' | wc -l)
23253         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
23254 }
23255
23256 test_808() {
23257         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
23258                 skip "Need MDS version at least 2.11.55"
23259
23260         # Registration step
23261         changelog_register || error "changelog_register failed"
23262
23263         touch $DIR/$tfile || error "touch $tfile failed"
23264         check_som_nologged
23265
23266         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
23267                 error "write $tfile failed"
23268         check_som_nologged
23269
23270         $TRUNCATE $DIR/$tfile 1234
23271         check_som_nologged
23272
23273         $TRUNCATE $DIR/$tfile 1048576
23274         check_som_nologged
23275
23276         # Deregistration step
23277         changelog_deregister || error "changelog_deregister failed"
23278 }
23279 run_test 808 "Check trusted.som xattr not logged in Changelogs"
23280
23281 check_som_nodata()
23282 {
23283         $LFS getsom $1
23284         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
23285 }
23286
23287 test_809() {
23288         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
23289                 skip "Need MDS version at least 2.11.56"
23290
23291         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
23292                 error "failed to create DoM-only file $DIR/$tfile"
23293         touch $DIR/$tfile || error "touch $tfile failed"
23294         check_som_nodata $DIR/$tfile
23295
23296         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
23297                 error "write $tfile failed"
23298         check_som_nodata $DIR/$tfile
23299
23300         $TRUNCATE $DIR/$tfile 1234
23301         check_som_nodata $DIR/$tfile
23302
23303         $TRUNCATE $DIR/$tfile 4097
23304         check_som_nodata $DIR/$file
23305 }
23306 run_test 809 "Verify no SOM xattr store for DoM-only files"
23307
23308 test_810() {
23309         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23310         $GSS && skip_env "could not run with gss"
23311         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
23312                 skip "OST < 2.12.58 doesn't align checksum"
23313
23314         set_checksums 1
23315         stack_trap "set_checksums $ORIG_CSUM" EXIT
23316         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
23317
23318         local csum
23319         local before
23320         local after
23321         for csum in $CKSUM_TYPES; do
23322                 #define OBD_FAIL_OSC_NO_GRANT   0x411
23323                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
23324                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
23325                         eval set -- $i
23326                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
23327                         before=$(md5sum $DIR/$tfile)
23328                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
23329                         after=$(md5sum $DIR/$tfile)
23330                         [ "$before" == "$after" ] ||
23331                                 error "$csum: $before != $after bs=$1 seek=$2"
23332                 done
23333         done
23334 }
23335 run_test 810 "partial page writes on ZFS (LU-11663)"
23336
23337 test_812a() {
23338         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
23339                 skip "OST < 2.12.51 doesn't support this fail_loc"
23340         [ "$SHARED_KEY" = true ] &&
23341                 skip "OSC connections never go IDLE with Shared-Keys enabled"
23342
23343         $LFS setstripe -c 1 -i 0 $DIR/$tfile
23344         # ensure ost1 is connected
23345         stat $DIR/$tfile >/dev/null || error "can't stat"
23346         wait_osc_import_state client ost1 FULL
23347         # no locks, no reqs to let the connection idle
23348         cancel_lru_locks osc
23349
23350         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
23351 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
23352         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
23353         wait_osc_import_state client ost1 CONNECTING
23354         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
23355
23356         stat $DIR/$tfile >/dev/null || error "can't stat file"
23357 }
23358 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
23359
23360 test_812b() { # LU-12378
23361         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
23362                 skip "OST < 2.12.51 doesn't support this fail_loc"
23363         [ "$SHARED_KEY" = true ] &&
23364                 skip "OSC connections never go IDLE with Shared-Keys enabled"
23365
23366         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
23367         # ensure ost1 is connected
23368         stat $DIR/$tfile >/dev/null || error "can't stat"
23369         wait_osc_import_state client ost1 FULL
23370         # no locks, no reqs to let the connection idle
23371         cancel_lru_locks osc
23372
23373         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
23374 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
23375         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
23376         wait_osc_import_state client ost1 CONNECTING
23377         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
23378
23379         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
23380         wait_osc_import_state client ost1 IDLE
23381 }
23382 run_test 812b "do not drop no resend request for idle connect"
23383
23384 test_813() {
23385         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
23386         [ -z "$file_heat_sav" ] && skip "no file heat support"
23387
23388         local readsample
23389         local writesample
23390         local readbyte
23391         local writebyte
23392         local readsample1
23393         local writesample1
23394         local readbyte1
23395         local writebyte1
23396
23397         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
23398         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
23399
23400         $LCTL set_param -n llite.*.file_heat=1
23401         echo "Turn on file heat"
23402         echo "Period second: $period_second, Decay percentage: $decay_pct"
23403
23404         echo "QQQQ" > $DIR/$tfile
23405         echo "QQQQ" > $DIR/$tfile
23406         echo "QQQQ" > $DIR/$tfile
23407         cat $DIR/$tfile > /dev/null
23408         cat $DIR/$tfile > /dev/null
23409         cat $DIR/$tfile > /dev/null
23410         cat $DIR/$tfile > /dev/null
23411
23412         local out=$($LFS heat_get $DIR/$tfile)
23413
23414         $LFS heat_get $DIR/$tfile
23415         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
23416         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
23417         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
23418         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
23419
23420         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
23421         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
23422         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
23423         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
23424
23425         sleep $((period_second + 3))
23426         echo "Sleep $((period_second + 3)) seconds..."
23427         # The recursion formula to calculate the heat of the file f is as
23428         # follow:
23429         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
23430         # Where Hi is the heat value in the period between time points i*I and
23431         # (i+1)*I; Ci is the access count in the period; the symbol P refers
23432         # to the weight of Ci.
23433         out=$($LFS heat_get $DIR/$tfile)
23434         $LFS heat_get $DIR/$tfile
23435         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
23436         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
23437         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
23438         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
23439
23440         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
23441                 error "read sample ($readsample) is wrong"
23442         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
23443                 error "write sample ($writesample) is wrong"
23444         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
23445                 error "read bytes ($readbyte) is wrong"
23446         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
23447                 error "write bytes ($writebyte) is wrong"
23448
23449         echo "QQQQ" > $DIR/$tfile
23450         echo "QQQQ" > $DIR/$tfile
23451         echo "QQQQ" > $DIR/$tfile
23452         cat $DIR/$tfile > /dev/null
23453         cat $DIR/$tfile > /dev/null
23454         cat $DIR/$tfile > /dev/null
23455         cat $DIR/$tfile > /dev/null
23456
23457         sleep $((period_second + 3))
23458         echo "Sleep $((period_second + 3)) seconds..."
23459
23460         out=$($LFS heat_get $DIR/$tfile)
23461         $LFS heat_get $DIR/$tfile
23462         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
23463         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
23464         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
23465         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
23466
23467         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
23468                 4 * $decay_pct) / 100") -eq 1 ] ||
23469                 error "read sample ($readsample1) is wrong"
23470         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
23471                 3 * $decay_pct) / 100") -eq 1 ] ||
23472                 error "write sample ($writesample1) is wrong"
23473         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
23474                 20 * $decay_pct) / 100") -eq 1 ] ||
23475                 error "read bytes ($readbyte1) is wrong"
23476         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
23477                 15 * $decay_pct) / 100") -eq 1 ] ||
23478                 error "write bytes ($writebyte1) is wrong"
23479
23480         echo "Turn off file heat for the file $DIR/$tfile"
23481         $LFS heat_set -o $DIR/$tfile
23482
23483         echo "QQQQ" > $DIR/$tfile
23484         echo "QQQQ" > $DIR/$tfile
23485         echo "QQQQ" > $DIR/$tfile
23486         cat $DIR/$tfile > /dev/null
23487         cat $DIR/$tfile > /dev/null
23488         cat $DIR/$tfile > /dev/null
23489         cat $DIR/$tfile > /dev/null
23490
23491         out=$($LFS heat_get $DIR/$tfile)
23492         $LFS heat_get $DIR/$tfile
23493         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
23494         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
23495         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
23496         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
23497
23498         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
23499         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
23500         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
23501         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
23502
23503         echo "Trun on file heat for the file $DIR/$tfile"
23504         $LFS heat_set -O $DIR/$tfile
23505
23506         echo "QQQQ" > $DIR/$tfile
23507         echo "QQQQ" > $DIR/$tfile
23508         echo "QQQQ" > $DIR/$tfile
23509         cat $DIR/$tfile > /dev/null
23510         cat $DIR/$tfile > /dev/null
23511         cat $DIR/$tfile > /dev/null
23512         cat $DIR/$tfile > /dev/null
23513
23514         out=$($LFS heat_get $DIR/$tfile)
23515         $LFS heat_get $DIR/$tfile
23516         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
23517         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
23518         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
23519         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
23520
23521         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
23522         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
23523         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
23524         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
23525
23526         $LFS heat_set -c $DIR/$tfile
23527         $LCTL set_param -n llite.*.file_heat=0
23528         echo "Turn off file heat support for the Lustre filesystem"
23529
23530         echo "QQQQ" > $DIR/$tfile
23531         echo "QQQQ" > $DIR/$tfile
23532         echo "QQQQ" > $DIR/$tfile
23533         cat $DIR/$tfile > /dev/null
23534         cat $DIR/$tfile > /dev/null
23535         cat $DIR/$tfile > /dev/null
23536         cat $DIR/$tfile > /dev/null
23537
23538         out=$($LFS heat_get $DIR/$tfile)
23539         $LFS heat_get $DIR/$tfile
23540         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
23541         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
23542         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
23543         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
23544
23545         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
23546         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
23547         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
23548         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
23549
23550         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
23551         rm -f $DIR/$tfile
23552 }
23553 run_test 813 "File heat verfication"
23554
23555 test_814()
23556 {
23557         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
23558         echo -n y >> $DIR/$tfile
23559         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
23560         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
23561 }
23562 run_test 814 "sparse cp works as expected (LU-12361)"
23563
23564 test_815()
23565 {
23566         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
23567         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
23568 }
23569 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
23570
23571 test_816() {
23572         [ "$SHARED_KEY" = true ] &&
23573                 skip "OSC connections never go IDLE with Shared-Keys enabled"
23574
23575         $LFS setstripe -c 1 -i 0 $DIR/$tfile
23576         # ensure ost1 is connected
23577         stat $DIR/$tfile >/dev/null || error "can't stat"
23578         wait_osc_import_state client ost1 FULL
23579         # no locks, no reqs to let the connection idle
23580         cancel_lru_locks osc
23581         lru_resize_disable osc
23582         local before
23583         local now
23584         before=$($LCTL get_param -n \
23585                  ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
23586
23587         wait_osc_import_state client ost1 IDLE
23588         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
23589         now=$($LCTL get_param -n \
23590               ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
23591         [ $before == $now ] || error "lru_size changed $before != $now"
23592 }
23593 run_test 816 "do not reset lru_resize on idle reconnect"
23594
23595 cleanup_817() {
23596         umount $tmpdir
23597         exportfs -u localhost:$DIR/nfsexp
23598         rm -rf $DIR/nfsexp
23599 }
23600
23601 test_817() {
23602         systemctl restart nfs-server.service || skip "failed to restart nfsd"
23603
23604         mkdir -p $DIR/nfsexp
23605         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
23606                 error "failed to export nfs"
23607
23608         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
23609         stack_trap cleanup_817 EXIT
23610
23611         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
23612                 error "failed to mount nfs to $tmpdir"
23613
23614         cp /bin/true $tmpdir
23615         $DIR/nfsexp/true || error "failed to execute 'true' command"
23616 }
23617 run_test 817 "nfsd won't cache write lock for exec file"
23618
23619 test_818() {
23620         mkdir $DIR/$tdir
23621         $LFS setstripe -c1 -i0 $DIR/$tfile
23622         $LFS setstripe -c1 -i1 $DIR/$tfile
23623         stop $SINGLEMDS
23624         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
23625         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
23626         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
23627                 error "start $SINGLEMDS failed"
23628         rm -rf $DIR/$tdir
23629 }
23630 run_test 818 "unlink with failed llog"
23631
23632 test_819a() {
23633         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23634         cancel_lru_locks osc
23635         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
23636         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
23637         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
23638         rm -f $TDIR/$tfile
23639 }
23640 run_test 819a "too big niobuf in read"
23641
23642 test_819b() {
23643         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
23644         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
23645         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23646         cancel_lru_locks osc
23647         sleep 1
23648         rm -f $TDIR/$tfile
23649 }
23650 run_test 819b "too big niobuf in write"
23651
23652
23653 function test_820_start_ost() {
23654         sleep 5
23655
23656         for num in $(seq $OSTCOUNT); do
23657                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
23658         done
23659 }
23660
23661 test_820() {
23662         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
23663
23664         mkdir $DIR/$tdir
23665         umount_client $MOUNT || error "umount failed"
23666         for num in $(seq $OSTCOUNT); do
23667                 stop ost$num
23668         done
23669
23670         # mount client with no active OSTs
23671         # so that the client can't initialize max LOV EA size
23672         # from OSC notifications
23673         mount_client $MOUNT || error "mount failed"
23674         # delay OST starting to keep this 0 max EA size for a while
23675         test_820_start_ost &
23676
23677         # create a directory on MDS2
23678         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
23679                 error "Failed to create directory"
23680         # open intent should update default EA size
23681         # see mdc_update_max_ea_from_body()
23682         # notice this is the very first RPC to MDS2
23683         cp /etc/services $DIR/$tdir/mds2 ||
23684                 error "Failed to copy files to mds$n"
23685 }
23686 run_test 820 "update max EA from open intent"
23687
23688 #
23689 # tests that do cleanup/setup should be run at the end
23690 #
23691
23692 test_900() {
23693         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23694         local ls
23695
23696         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
23697         $LCTL set_param fail_loc=0x903
23698
23699         cancel_lru_locks MGC
23700
23701         FAIL_ON_ERROR=true cleanup
23702         FAIL_ON_ERROR=true setup
23703 }
23704 run_test 900 "umount should not race with any mgc requeue thread"
23705
23706 # LUS-6253/LU-11185
23707 test_901() {
23708         local oldc
23709         local newc
23710         local olds
23711         local news
23712         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23713
23714         # some get_param have a bug to handle dot in param name
23715         cancel_lru_locks MGC
23716         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
23717         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
23718         umount_client $MOUNT || error "umount failed"
23719         mount_client $MOUNT || error "mount failed"
23720         cancel_lru_locks MGC
23721         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
23722         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
23723
23724         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
23725         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
23726
23727         return 0
23728 }
23729 run_test 901 "don't leak a mgc lock on client umount"
23730
23731 # LU-13377
23732 test_902() {
23733         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
23734                 skip "client does not have LU-13377 fix"
23735         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
23736         $LCTL set_param fail_loc=0x1415
23737         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23738         cancel_lru_locks osc
23739         rm -f $DIR/$tfile
23740 }
23741 run_test 902 "test short write doesn't hang lustre"
23742
23743 complete $SECONDS
23744 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
23745 check_and_cleanup_lustre
23746 if [ "$I_MOUNTED" != "yes" ]; then
23747         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
23748 fi
23749 exit_status