Whamcloud - gitweb
b4d2cea6b97c6541412fd1c6b0a7b1391da56717
[fs/lustre-release.git] / lustre / tests / sanity.sh
1 #!/bin/bash
2 #
3 # Run select tests by setting ONLY, or as arguments to the script.
4 # Skip specific tests by setting EXCEPT.
5 #
6 # e.g. ONLY="22 23" or ONLY="`seq 32 39`" or EXCEPT="31"
7 set -e
8
9 ONLY=${ONLY:-"$*"}
10
11 # Check Grants after these tests
12 GRANT_CHECK_LIST="$GRANT_CHECK_LIST 42a 42b 42c 42d 42e 63a 63b 64a 64b 64c 64d"
13
14 OSC=${OSC:-"osc"}
15
16 CC=${CC:-cc}
17 CREATETEST=${CREATETEST:-createtest}
18 LVERIFY=${LVERIFY:-ll_dirstripe_verify}
19 OPENFILE=${OPENFILE:-openfile}
20 OPENUNLINK=${OPENUNLINK:-openunlink}
21 READS=${READS:-"reads"}
22 MUNLINK=${MUNLINK:-munlink}
23 SOCKETSERVER=${SOCKETSERVER:-socketserver}
24 SOCKETCLIENT=${SOCKETCLIENT:-socketclient}
25 MEMHOG=${MEMHOG:-memhog}
26 DIRECTIO=${DIRECTIO:-directio}
27 ACCEPTOR_PORT=${ACCEPTOR_PORT:-988}
28 DEF_STRIPE_COUNT=-1
29 CHECK_GRANT=${CHECK_GRANT:-"yes"}
30 GRANT_CHECK_LIST=${GRANT_CHECK_LIST:-""}
31 export PARALLEL=${PARALLEL:-"no"}
32
33 TRACE=${TRACE:-""}
34 LUSTRE=${LUSTRE:-$(dirname $0)/..}
35 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
36 . $LUSTRE/tests/test-framework.sh
37 init_test_env $@
38
39 init_logging
40
41 ALWAYS_EXCEPT="$SANITY_EXCEPT "
42 # bug number for skipped test: LU-9693 LU-6493 LU-9693
43 ALWAYS_EXCEPT+="               42a     42b     42c "
44 # bug number:    LU-8411 LU-9054 LU-13314
45 ALWAYS_EXCEPT+=" 407     312     56ob"
46
47 if $SHARED_KEY; then
48         # bug number:    LU-9795 LU-9795 LU-9795 LU-9795
49         ALWAYS_EXCEPT+=" 17n     60a     133g    300f"
50 fi
51
52 selinux_status=$(getenforce)
53 if [ "$selinux_status" != "Disabled" ]; then
54         # bug number:
55         ALWAYS_EXCEPT+=""
56 fi
57
58 # skip the grant tests for ARM until they are fixed
59 if [[ $(uname -m) = aarch64 ]]; then
60         # bug number:    LU-11596
61         ALWAYS_EXCEPT+=" $GRANT_CHECK_LIST"
62         # bug number:    LU-11671 LU-11667
63         ALWAYS_EXCEPT+=" 45       317"
64 fi
65
66 # skip nfs tests on kernels >= 4.14.0 until they are fixed
67 if [ $LINUX_VERSION_CODE -ge $(version_code 4.14.0) ]; then
68         # bug number:   LU-12661
69         ALWAYS_EXCEPT+=" 817"
70 fi
71 # skip cgroup tests on RHEL8.1 kernels until they are fixed
72 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
73       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
74         # bug number:   LU-13063
75         ALWAYS_EXCEPT+=" 411"
76 fi
77
78 #                                  5          12     8   12  (min)"
79 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 64b 68 71 115 135 136 300o"
80
81 if [ "$mds1_FSTYPE" = "zfs" ]; then
82         # bug number for skipped test:
83         ALWAYS_EXCEPT="$ALWAYS_EXCEPT  "
84         #                                               13    (min)"
85         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
86 fi
87
88 # Get the SLES distro version
89 #
90 # Returns a version string that should only be used in comparing
91 # strings returned by version_code()
92 sles_version_code()
93 {
94         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
95
96         # All SuSE Linux versions have one decimal. version_code expects two
97         local sles_version=$version.0
98         version_code $sles_version
99 }
100
101 # Check if we are running on Ubuntu or SLES so we can make decisions on
102 # what tests to run
103 if [ -r /etc/SuSE-release ]; then
104         sles_version=$(sles_version_code)
105         [ $sles_version -lt $(version_code 11.4.0) ] &&
106                 # bug number for skipped test: LU-4341
107                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  170"
108         [ $sles_version -lt $(version_code 12.0.0) ] &&
109                 # bug number for skipped test: LU-3703
110                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  234"
111 elif [ -r /etc/os-release ]; then
112         if grep -qi ubuntu /etc/os-release; then
113                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
114                                                 -e 's/^VERSION=//p' \
115                                                 /etc/os-release |
116                                                 awk '{ print $1 }'))
117
118                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
119                         # bug number for skipped test:
120                         #                LU-10334 LU-10366
121                         ALWAYS_EXCEPT+=" 103a     410"
122                 fi
123         fi
124 fi
125
126 build_test_filter
127 FAIL_ON_ERROR=false
128
129 cleanup() {
130         echo -n "cln.."
131         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
132         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
133 }
134 setup() {
135         echo -n "mnt.."
136         load_modules
137         setupall || exit 10
138         echo "done"
139 }
140
141 check_swap_layouts_support()
142 {
143         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
144                 skip "Does not support layout lock."
145 }
146
147 check_and_setup_lustre
148 DIR=${DIR:-$MOUNT}
149 assert_DIR
150
151 MAXFREE=${MAXFREE:-$((200000 * $OSTCOUNT))}
152
153 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
154 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
155 rm -rf $DIR/[Rdfs][0-9]*
156
157 # $RUNAS_ID may get set incorrectly somewhere else
158 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
159         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
160
161 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
162
163 if [ "${ONLY}" = "MOUNT" ] ; then
164         echo "Lustre is up, please go on"
165         exit
166 fi
167
168 echo "preparing for tests involving mounts"
169 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
170 touch $EXT2_DEV
171 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
172 echo # add a newline after mke2fs.
173
174 umask 077
175
176 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
177 lctl set_param debug=-1 2> /dev/null || true
178 test_0a() {
179         touch $DIR/$tfile
180         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
181         rm $DIR/$tfile
182         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
183 }
184 run_test 0a "touch; rm ====================="
185
186 test_0b() {
187         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
188         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
189 }
190 run_test 0b "chmod 0755 $DIR ============================="
191
192 test_0c() {
193         $LCTL get_param mdc.*.import | grep "state: FULL" ||
194                 error "import not FULL"
195         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
196                 error "bad target"
197 }
198 run_test 0c "check import proc"
199
200 test_0d() { # LU-3397
201         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
202                 skip "proc exports not supported before 2.10.57"
203
204         local mgs_exp="mgs.MGS.exports"
205         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
206         local exp_client_nid
207         local exp_client_version
208         local exp_val
209         local imp_val
210         local temp_imp=$DIR/$tfile.import
211         local temp_exp=$DIR/$tfile.export
212
213         # save mgc import file to $temp_imp
214         $LCTL get_param mgc.*.import | tee $temp_imp
215         # Check if client uuid is found in MGS export
216         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
217                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
218                         $client_uuid ] &&
219                         break;
220         done
221         # save mgs export file to $temp_exp
222         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
223
224         # Compare the value of field "connect_flags"
225         imp_val=$(grep "connect_flags" $temp_imp)
226         exp_val=$(grep "connect_flags" $temp_exp)
227         [ "$exp_val" == "$imp_val" ] ||
228                 error "export flags '$exp_val' != import flags '$imp_val'"
229
230         # Compare the value of client version
231         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
232         exp_val=$(version_code $exp_client_version)
233         imp_val=$CLIENT_VERSION
234         [ "$exp_val" == "$imp_val" ] ||
235                 error "export client version '$exp_val' != '$imp_val'"
236 }
237 run_test 0d "check export proc ============================="
238
239 test_1() {
240         test_mkdir $DIR/$tdir
241         test_mkdir $DIR/$tdir/d2
242         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
243         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
244         rmdir $DIR/$tdir/d2
245         rmdir $DIR/$tdir
246         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
247 }
248 run_test 1 "mkdir; remkdir; rmdir"
249
250 test_2() {
251         test_mkdir $DIR/$tdir
252         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
253         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
254         rm -r $DIR/$tdir
255         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
256 }
257 run_test 2 "mkdir; touch; rmdir; check file"
258
259 test_3() {
260         test_mkdir $DIR/$tdir
261         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
262         touch $DIR/$tdir/$tfile
263         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
264         rm -r $DIR/$tdir
265         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
266 }
267 run_test 3 "mkdir; touch; rmdir; check dir"
268
269 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
270 test_4() {
271         test_mkdir -i 1 $DIR/$tdir
272
273         touch $DIR/$tdir/$tfile ||
274                 error "Create file under remote directory failed"
275
276         rmdir $DIR/$tdir &&
277                 error "Expect error removing in-use dir $DIR/$tdir"
278
279         test -d $DIR/$tdir || error "Remote directory disappeared"
280
281         rm -rf $DIR/$tdir || error "remove remote dir error"
282 }
283 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
284
285 test_5() {
286         test_mkdir $DIR/$tdir
287         test_mkdir $DIR/$tdir/d2
288         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
289         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
290         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
291 }
292 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
293
294 test_6a() {
295         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
296         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
297         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
298                 error "$tfile does not have perm 0666 or UID $UID"
299         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
300         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
301                 error "$tfile should be 0666 and owned by UID $UID"
302 }
303 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
304
305 test_6c() {
306         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
307
308         touch $DIR/$tfile
309         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
310         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
311                 error "$tfile should be owned by UID $RUNAS_ID"
312         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
313         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
314                 error "$tfile should be owned by UID $RUNAS_ID"
315 }
316 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
317
318 test_6e() {
319         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
320
321         touch $DIR/$tfile
322         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
323         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
324                 error "$tfile should be owned by GID $UID"
325         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
326         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
327                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
328 }
329 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
330
331 test_6g() {
332         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
333
334         test_mkdir $DIR/$tdir
335         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
336         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
337         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
338         test_mkdir $DIR/$tdir/d/subdir
339         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
340                 error "$tdir/d/subdir should be GID $RUNAS_GID"
341         if [[ $MDSCOUNT -gt 1 ]]; then
342                 # check remote dir sgid inherite
343                 $LFS mkdir -i 0 $DIR/$tdir.local ||
344                         error "mkdir $tdir.local failed"
345                 chmod g+s $DIR/$tdir.local ||
346                         error "chmod $tdir.local failed"
347                 chgrp $RUNAS_GID $DIR/$tdir.local ||
348                         error "chgrp $tdir.local failed"
349                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
350                         error "mkdir $tdir.remote failed"
351                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
352                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
353                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
354                         error "$tdir.remote should be mode 02755"
355         fi
356 }
357 run_test 6g "verify new dir in sgid dir inherits group"
358
359 test_6h() { # bug 7331
360         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
361
362         touch $DIR/$tfile || error "touch failed"
363         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
364         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
365                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
366         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
367                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
368 }
369 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
370
371 test_7a() {
372         test_mkdir $DIR/$tdir
373         $MCREATE $DIR/$tdir/$tfile
374         chmod 0666 $DIR/$tdir/$tfile
375         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
376                 error "$tdir/$tfile should be mode 0666"
377 }
378 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
379
380 test_7b() {
381         if [ ! -d $DIR/$tdir ]; then
382                 test_mkdir $DIR/$tdir
383         fi
384         $MCREATE $DIR/$tdir/$tfile
385         echo -n foo > $DIR/$tdir/$tfile
386         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
387         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
388 }
389 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
390
391 test_8() {
392         test_mkdir $DIR/$tdir
393         touch $DIR/$tdir/$tfile
394         chmod 0666 $DIR/$tdir/$tfile
395         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
396                 error "$tfile mode not 0666"
397 }
398 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
399
400 test_9() {
401         test_mkdir $DIR/$tdir
402         test_mkdir $DIR/$tdir/d2
403         test_mkdir $DIR/$tdir/d2/d3
404         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
405 }
406 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
407
408 test_10() {
409         test_mkdir $DIR/$tdir
410         test_mkdir $DIR/$tdir/d2
411         touch $DIR/$tdir/d2/$tfile
412         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
413                 error "$tdir/d2/$tfile not a file"
414 }
415 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
416
417 test_11() {
418         test_mkdir $DIR/$tdir
419         test_mkdir $DIR/$tdir/d2
420         chmod 0666 $DIR/$tdir/d2
421         chmod 0705 $DIR/$tdir/d2
422         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
423                 error "$tdir/d2 mode not 0705"
424 }
425 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
426
427 test_12() {
428         test_mkdir $DIR/$tdir
429         touch $DIR/$tdir/$tfile
430         chmod 0666 $DIR/$tdir/$tfile
431         chmod 0654 $DIR/$tdir/$tfile
432         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
433                 error "$tdir/d2 mode not 0654"
434 }
435 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
436
437 test_13() {
438         test_mkdir $DIR/$tdir
439         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
440         >  $DIR/$tdir/$tfile
441         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
442                 error "$tdir/$tfile size not 0 after truncate"
443 }
444 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
445
446 test_14() {
447         test_mkdir $DIR/$tdir
448         touch $DIR/$tdir/$tfile
449         rm $DIR/$tdir/$tfile
450         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
451 }
452 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
453
454 test_15() {
455         test_mkdir $DIR/$tdir
456         touch $DIR/$tdir/$tfile
457         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
458         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
459                 error "$tdir/${tfile_2} not a file after rename"
460         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
461 }
462 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
463
464 test_16() {
465         test_mkdir $DIR/$tdir
466         touch $DIR/$tdir/$tfile
467         rm -rf $DIR/$tdir/$tfile
468         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
469 }
470 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
471
472 test_17a() {
473         test_mkdir $DIR/$tdir
474         touch $DIR/$tdir/$tfile
475         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
476         ls -l $DIR/$tdir
477         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
478                 error "$tdir/l-exist not a symlink"
479         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
480                 error "$tdir/l-exist not referencing a file"
481         rm -f $DIR/$tdir/l-exist
482         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
483 }
484 run_test 17a "symlinks: create, remove (real)"
485
486 test_17b() {
487         test_mkdir $DIR/$tdir
488         ln -s no-such-file $DIR/$tdir/l-dangle
489         ls -l $DIR/$tdir
490         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
491                 error "$tdir/l-dangle not referencing no-such-file"
492         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
493                 error "$tdir/l-dangle not referencing non-existent file"
494         rm -f $DIR/$tdir/l-dangle
495         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
496 }
497 run_test 17b "symlinks: create, remove (dangling)"
498
499 test_17c() { # bug 3440 - don't save failed open RPC for replay
500         test_mkdir $DIR/$tdir
501         ln -s foo $DIR/$tdir/$tfile
502         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
503 }
504 run_test 17c "symlinks: open dangling (should return error)"
505
506 test_17d() {
507         test_mkdir $DIR/$tdir
508         ln -s foo $DIR/$tdir/$tfile
509         touch $DIR/$tdir/$tfile || error "creating to new symlink"
510 }
511 run_test 17d "symlinks: create dangling"
512
513 test_17e() {
514         test_mkdir $DIR/$tdir
515         local foo=$DIR/$tdir/$tfile
516         ln -s $foo $foo || error "create symlink failed"
517         ls -l $foo || error "ls -l failed"
518         ls $foo && error "ls not failed" || true
519 }
520 run_test 17e "symlinks: create recursive symlink (should return error)"
521
522 test_17f() {
523         test_mkdir $DIR/$tdir
524         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
525         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
526         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
527         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
528         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
529         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890/aaaaaaaaaa/bbbbbbbbbb/cccccccccc/dddddddddd/eeeeeeeeee/ffffffffff/ $DIR/$tdir/666
530         ls -l  $DIR/$tdir
531 }
532 run_test 17f "symlinks: long and very long symlink name"
533
534 # str_repeat(S, N) generate a string that is string S repeated N times
535 str_repeat() {
536         local s=$1
537         local n=$2
538         local ret=''
539         while [ $((n -= 1)) -ge 0 ]; do
540                 ret=$ret$s
541         done
542         echo $ret
543 }
544
545 # Long symlinks and LU-2241
546 test_17g() {
547         test_mkdir $DIR/$tdir
548         local TESTS="59 60 61 4094 4095"
549
550         # Fix for inode size boundary in 2.1.4
551         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
552                 TESTS="4094 4095"
553
554         # Patch not applied to 2.2 or 2.3 branches
555         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
556         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
557                 TESTS="4094 4095"
558
559         for i in $TESTS; do
560                 local SYMNAME=$(str_repeat 'x' $i)
561                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
562                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
563         done
564 }
565 run_test 17g "symlinks: really long symlink name and inode boundaries"
566
567 test_17h() { #bug 17378
568         [ $PARALLEL == "yes" ] && skip "skip parallel run"
569         remote_mds_nodsh && skip "remote MDS with nodsh"
570
571         local mdt_idx
572
573         test_mkdir $DIR/$tdir
574         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
575         $LFS setstripe -c -1 $DIR/$tdir
576         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
577         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
578         touch $DIR/$tdir/$tfile || true
579 }
580 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
581
582 test_17i() { #bug 20018
583         [ $PARALLEL == "yes" ] && skip "skip parallel run"
584         remote_mds_nodsh && skip "remote MDS with nodsh"
585
586         local foo=$DIR/$tdir/$tfile
587         local mdt_idx
588
589         test_mkdir -c1 $DIR/$tdir
590         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
591         ln -s $foo $foo || error "create symlink failed"
592 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
593         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
594         ls -l $foo && error "error not detected"
595         return 0
596 }
597 run_test 17i "don't panic on short symlink (should return error)"
598
599 test_17k() { #bug 22301
600         [ $PARALLEL == "yes" ] && skip "skip parallel run"
601         [[ -z "$(which rsync 2>/dev/null)" ]] &&
602                 skip "no rsync command"
603         rsync --help | grep -q xattr ||
604                 skip_env "$(rsync --version | head -n1) does not support xattrs"
605         test_mkdir $DIR/$tdir
606         test_mkdir $DIR/$tdir.new
607         touch $DIR/$tdir/$tfile
608         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
609         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
610                 error "rsync failed with xattrs enabled"
611 }
612 run_test 17k "symlinks: rsync with xattrs enabled"
613
614 test_17l() { # LU-279
615         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
616                 skip "no getfattr command"
617
618         test_mkdir $DIR/$tdir
619         touch $DIR/$tdir/$tfile
620         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
621         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
622                 # -h to not follow symlinks. -m '' to list all the xattrs.
623                 # grep to remove first line: '# file: $path'.
624                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
625                 do
626                         lgetxattr_size_check $path $xattr ||
627                                 error "lgetxattr_size_check $path $xattr failed"
628                 done
629         done
630 }
631 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
632
633 # LU-1540
634 test_17m() {
635         [ $PARALLEL == "yes" ] && skip "skip parallel run"
636         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
637         remote_mds_nodsh && skip "remote MDS with nodsh"
638         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
639         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
640                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
641
642         local short_sym="0123456789"
643         local wdir=$DIR/$tdir
644         local i
645
646         test_mkdir $wdir
647         long_sym=$short_sym
648         # create a long symlink file
649         for ((i = 0; i < 4; ++i)); do
650                 long_sym=${long_sym}${long_sym}
651         done
652
653         echo "create 512 short and long symlink files under $wdir"
654         for ((i = 0; i < 256; ++i)); do
655                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
656                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
657         done
658
659         echo "erase them"
660         rm -f $wdir/*
661         sync
662         wait_delete_completed
663
664         echo "recreate the 512 symlink files with a shorter string"
665         for ((i = 0; i < 512; ++i)); do
666                 # rewrite the symlink file with a shorter string
667                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
668                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
669         done
670
671         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
672         local devname=$(mdsdevname $mds_index)
673
674         echo "stop and checking mds${mds_index}:"
675         # e2fsck should not return error
676         stop mds${mds_index}
677         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
678         rc=$?
679
680         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
681                 error "start mds${mds_index} failed"
682         df $MOUNT > /dev/null 2>&1
683         [ $rc -eq 0 ] ||
684                 error "e2fsck detected error for short/long symlink: rc=$rc"
685         rm -f $wdir/*
686 }
687 run_test 17m "run e2fsck against MDT which contains short/long symlink"
688
689 check_fs_consistency_17n() {
690         local mdt_index
691         local rc=0
692
693         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
694         # so it only check MDT1/MDT2 instead of all of MDTs.
695         for mdt_index in 1 2; do
696                 local devname=$(mdsdevname $mdt_index)
697                 # e2fsck should not return error
698                 stop mds${mdt_index}
699                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
700                         rc=$((rc + $?))
701
702                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
703                         error "mount mds$mdt_index failed"
704                 df $MOUNT > /dev/null 2>&1
705         done
706         return $rc
707 }
708
709 test_17n() {
710         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
711         [ $PARALLEL == "yes" ] && skip "skip parallel run"
712         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
713         remote_mds_nodsh && skip "remote MDS with nodsh"
714         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
715         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
716                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
717
718         local i
719
720         test_mkdir $DIR/$tdir
721         for ((i=0; i<10; i++)); do
722                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
723                         error "create remote dir error $i"
724                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
725                         error "create files under remote dir failed $i"
726         done
727
728         check_fs_consistency_17n ||
729                 error "e2fsck report error after create files under remote dir"
730
731         for ((i = 0; i < 10; i++)); do
732                 rm -rf $DIR/$tdir/remote_dir_${i} ||
733                         error "destroy remote dir error $i"
734         done
735
736         check_fs_consistency_17n ||
737                 error "e2fsck report error after unlink files under remote dir"
738
739         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
740                 skip "lustre < 2.4.50 does not support migrate mv"
741
742         for ((i = 0; i < 10; i++)); do
743                 mkdir -p $DIR/$tdir/remote_dir_${i}
744                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
745                         error "create files under remote dir failed $i"
746                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
747                         error "migrate remote dir error $i"
748         done
749         check_fs_consistency_17n || error "e2fsck report error after migration"
750
751         for ((i = 0; i < 10; i++)); do
752                 rm -rf $DIR/$tdir/remote_dir_${i} ||
753                         error "destroy remote dir error $i"
754         done
755
756         check_fs_consistency_17n || error "e2fsck report error after unlink"
757 }
758 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
759
760 test_17o() {
761         remote_mds_nodsh && skip "remote MDS with nodsh"
762         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
763                 skip "Need MDS version at least 2.3.64"
764
765         local wdir=$DIR/${tdir}o
766         local mdt_index
767         local rc=0
768
769         test_mkdir $wdir
770         touch $wdir/$tfile
771         mdt_index=$($LFS getstripe -m $wdir/$tfile)
772         mdt_index=$((mdt_index + 1))
773
774         cancel_lru_locks mdc
775         #fail mds will wait the failover finish then set
776         #following fail_loc to avoid interfer the recovery process.
777         fail mds${mdt_index}
778
779         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
780         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
781         ls -l $wdir/$tfile && rc=1
782         do_facet mds${mdt_index} lctl set_param fail_loc=0
783         [[ $rc -eq 0 ]] || error "stat file should fail"
784 }
785 run_test 17o "stat file with incompat LMA feature"
786
787 test_18() {
788         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
789         ls $DIR || error "Failed to ls $DIR: $?"
790 }
791 run_test 18 "touch .../f ; ls ... =============================="
792
793 test_19a() {
794         touch $DIR/$tfile
795         ls -l $DIR
796         rm $DIR/$tfile
797         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
798 }
799 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
800
801 test_19b() {
802         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
803 }
804 run_test 19b "ls -l .../f19 (should return error) =============="
805
806 test_19c() {
807         [ $RUNAS_ID -eq $UID ] &&
808                 skip_env "RUNAS_ID = UID = $UID -- skipping"
809
810         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
811 }
812 run_test 19c "$RUNAS touch .../f19 (should return error) =="
813
814 test_19d() {
815         cat $DIR/f19 && error || true
816 }
817 run_test 19d "cat .../f19 (should return error) =============="
818
819 test_20() {
820         touch $DIR/$tfile
821         rm $DIR/$tfile
822         touch $DIR/$tfile
823         rm $DIR/$tfile
824         touch $DIR/$tfile
825         rm $DIR/$tfile
826         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
827 }
828 run_test 20 "touch .../f ; ls -l ..."
829
830 test_21() {
831         test_mkdir $DIR/$tdir
832         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
833         ln -s dangle $DIR/$tdir/link
834         echo foo >> $DIR/$tdir/link
835         cat $DIR/$tdir/dangle
836         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
837         $CHECKSTAT -f -t file $DIR/$tdir/link ||
838                 error "$tdir/link not linked to a file"
839 }
840 run_test 21 "write to dangling link"
841
842 test_22() {
843         local wdir=$DIR/$tdir
844         test_mkdir $wdir
845         chown $RUNAS_ID:$RUNAS_GID $wdir
846         (cd $wdir || error "cd $wdir failed";
847                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
848                 $RUNAS tar xf -)
849         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
850         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
851         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
852                 error "checkstat -u failed"
853 }
854 run_test 22 "unpack tar archive as non-root user"
855
856 # was test_23
857 test_23a() {
858         test_mkdir $DIR/$tdir
859         local file=$DIR/$tdir/$tfile
860
861         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
862         openfile -f O_CREAT:O_EXCL $file &&
863                 error "$file recreate succeeded" || true
864 }
865 run_test 23a "O_CREAT|O_EXCL in subdir"
866
867 test_23b() { # bug 18988
868         test_mkdir $DIR/$tdir
869         local file=$DIR/$tdir/$tfile
870
871         rm -f $file
872         echo foo > $file || error "write filed"
873         echo bar >> $file || error "append filed"
874         $CHECKSTAT -s 8 $file || error "wrong size"
875         rm $file
876 }
877 run_test 23b "O_APPEND check"
878
879 # LU-9409, size with O_APPEND and tiny writes
880 test_23c() {
881         local file=$DIR/$tfile
882
883         # single dd
884         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
885         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
886         rm -f $file
887
888         # racing tiny writes
889         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
890         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
891         wait
892         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
893         rm -f $file
894
895         #racing tiny & normal writes
896         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
897         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
898         wait
899         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
900         rm -f $file
901
902         #racing tiny & normal writes 2, ugly numbers
903         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
904         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
905         wait
906         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
907         rm -f $file
908 }
909 run_test 23c "O_APPEND size checks for tiny writes"
910
911 # LU-11069 file offset is correct after appending writes
912 test_23d() {
913         local file=$DIR/$tfile
914         local offset
915
916         echo CentaurHauls > $file
917         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
918         if ((offset != 26)); then
919                 error "wrong offset, expected 26, got '$offset'"
920         fi
921 }
922 run_test 23d "file offset is correct after appending writes"
923
924 # rename sanity
925 test_24a() {
926         echo '-- same directory rename'
927         test_mkdir $DIR/$tdir
928         touch $DIR/$tdir/$tfile.1
929         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
930         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
931 }
932 run_test 24a "rename file to non-existent target"
933
934 test_24b() {
935         test_mkdir $DIR/$tdir
936         touch $DIR/$tdir/$tfile.{1,2}
937         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
938         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
939         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
940 }
941 run_test 24b "rename file to existing target"
942
943 test_24c() {
944         test_mkdir $DIR/$tdir
945         test_mkdir $DIR/$tdir/d$testnum.1
946         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
947         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
948         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
949 }
950 run_test 24c "rename directory to non-existent target"
951
952 test_24d() {
953         test_mkdir -c1 $DIR/$tdir
954         test_mkdir -c1 $DIR/$tdir/d$testnum.1
955         test_mkdir -c1 $DIR/$tdir/d$testnum.2
956         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
957         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
958         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
959 }
960 run_test 24d "rename directory to existing target"
961
962 test_24e() {
963         echo '-- cross directory renames --'
964         test_mkdir $DIR/R5a
965         test_mkdir $DIR/R5b
966         touch $DIR/R5a/f
967         mv $DIR/R5a/f $DIR/R5b/g
968         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
969         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
970 }
971 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
972
973 test_24f() {
974         test_mkdir $DIR/R6a
975         test_mkdir $DIR/R6b
976         touch $DIR/R6a/f $DIR/R6b/g
977         mv $DIR/R6a/f $DIR/R6b/g
978         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
979         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
980 }
981 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
982
983 test_24g() {
984         test_mkdir $DIR/R7a
985         test_mkdir $DIR/R7b
986         test_mkdir $DIR/R7a/d
987         mv $DIR/R7a/d $DIR/R7b/e
988         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
989         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
990 }
991 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
992
993 test_24h() {
994         test_mkdir -c1 $DIR/R8a
995         test_mkdir -c1 $DIR/R8b
996         test_mkdir -c1 $DIR/R8a/d
997         test_mkdir -c1 $DIR/R8b/e
998         mrename $DIR/R8a/d $DIR/R8b/e
999         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1000         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1001 }
1002 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1003
1004 test_24i() {
1005         echo "-- rename error cases"
1006         test_mkdir $DIR/R9
1007         test_mkdir $DIR/R9/a
1008         touch $DIR/R9/f
1009         mrename $DIR/R9/f $DIR/R9/a
1010         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1011         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1012         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1013 }
1014 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1015
1016 test_24j() {
1017         test_mkdir $DIR/R10
1018         mrename $DIR/R10/f $DIR/R10/g
1019         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1020         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1021         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1022 }
1023 run_test 24j "source does not exist ============================"
1024
1025 test_24k() {
1026         test_mkdir $DIR/R11a
1027         test_mkdir $DIR/R11a/d
1028         touch $DIR/R11a/f
1029         mv $DIR/R11a/f $DIR/R11a/d
1030         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1031         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1032 }
1033 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1034
1035 # bug 2429 - rename foo foo foo creates invalid file
1036 test_24l() {
1037         f="$DIR/f24l"
1038         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1039 }
1040 run_test 24l "Renaming a file to itself ========================"
1041
1042 test_24m() {
1043         f="$DIR/f24m"
1044         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1045         # on ext3 this does not remove either the source or target files
1046         # though the "expected" operation would be to remove the source
1047         $CHECKSTAT -t file ${f} || error "${f} missing"
1048         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1049 }
1050 run_test 24m "Renaming a file to a hard link to itself ========="
1051
1052 test_24n() {
1053     f="$DIR/f24n"
1054     # this stats the old file after it was renamed, so it should fail
1055     touch ${f}
1056     $CHECKSTAT ${f} || error "${f} missing"
1057     mv ${f} ${f}.rename
1058     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1059     $CHECKSTAT -a ${f} || error "${f} exists"
1060 }
1061 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1062
1063 test_24o() {
1064         test_mkdir $DIR/$tdir
1065         rename_many -s random -v -n 10 $DIR/$tdir
1066 }
1067 run_test 24o "rename of files during htree split"
1068
1069 test_24p() {
1070         test_mkdir $DIR/R12a
1071         test_mkdir $DIR/R12b
1072         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1073         mrename $DIR/R12a $DIR/R12b
1074         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1075         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1076         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1077         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1078 }
1079 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1080
1081 cleanup_multiop_pause() {
1082         trap 0
1083         kill -USR1 $MULTIPID
1084 }
1085
1086 test_24q() {
1087         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1088
1089         test_mkdir $DIR/R13a
1090         test_mkdir $DIR/R13b
1091         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1092         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1093         MULTIPID=$!
1094
1095         trap cleanup_multiop_pause EXIT
1096         mrename $DIR/R13a $DIR/R13b
1097         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1098         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1099         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1100         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1101         cleanup_multiop_pause
1102         wait $MULTIPID || error "multiop close failed"
1103 }
1104 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1105
1106 test_24r() { #bug 3789
1107         test_mkdir $DIR/R14a
1108         test_mkdir $DIR/R14a/b
1109         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1110         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1111         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1112 }
1113 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1114
1115 test_24s() {
1116         test_mkdir $DIR/R15a
1117         test_mkdir $DIR/R15a/b
1118         test_mkdir $DIR/R15a/b/c
1119         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1120         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1121         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1122 }
1123 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1124 test_24t() {
1125         test_mkdir $DIR/R16a
1126         test_mkdir $DIR/R16a/b
1127         test_mkdir $DIR/R16a/b/c
1128         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1129         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1130         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1131 }
1132 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1133
1134 test_24u() { # bug12192
1135         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1136         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1137 }
1138 run_test 24u "create stripe file"
1139
1140 simple_cleanup_common() {
1141         local rc=0
1142         trap 0
1143         [ -z "$DIR" ] || [ -z "$tdir" ] && return 0
1144
1145         local start=$SECONDS
1146         rm -rf $DIR/$tdir
1147         rc=$?
1148         wait_delete_completed
1149         echo "cleanup time $((SECONDS - start))"
1150         return $rc
1151 }
1152
1153 max_pages_per_rpc() {
1154         local mdtname="$(printf "MDT%04x" ${1:-0})"
1155         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1156 }
1157
1158 test_24v() {
1159         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1160
1161         local nrfiles=${COUNT:-100000}
1162         local fname="$DIR/$tdir/$tfile"
1163
1164         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1165         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1166
1167         test_mkdir "$(dirname $fname)"
1168         # assume MDT0000 has the fewest inodes
1169         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1170         local free_inodes=$(($(mdt_free_inodes 0) * stripes))
1171         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1172
1173         trap simple_cleanup_common EXIT
1174
1175         createmany -m "$fname" $nrfiles
1176
1177         cancel_lru_locks mdc
1178         lctl set_param mdc.*.stats clear
1179
1180         # was previously test_24D: LU-6101
1181         # readdir() returns correct number of entries after cursor reload
1182         local num_ls=$(ls $DIR/$tdir | wc -l)
1183         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1184         local num_all=$(ls -a $DIR/$tdir | wc -l)
1185         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1186                 [ $num_all -ne $((nrfiles + 2)) ]; then
1187                         error "Expected $nrfiles files, got $num_ls " \
1188                                 "($num_uniq unique $num_all .&..)"
1189         fi
1190         # LU-5 large readdir
1191         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1192         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1193         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1194         # take into account of overhead in lu_dirpage header and end mark in
1195         # each page, plus one in rpc_num calculation.
1196         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1197         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1198         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1199         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1200         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1201         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1202         echo "readpages: $mds_readpage rpc_max: $rpc_max"
1203         (( $mds_readpage < $rpc_max - 2 || $mds_readpage > $rpc_max + 1)) &&
1204                 error "large readdir doesn't take effect: " \
1205                       "$mds_readpage should be about $rpc_max"
1206
1207         simple_cleanup_common
1208 }
1209 run_test 24v "list large directory (test hash collision, b=17560)"
1210
1211 test_24w() { # bug21506
1212         SZ1=234852
1213         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1214         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1215         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1216         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1217         [[ "$SZ1" -eq "$SZ2" ]] ||
1218                 error "Error reading at the end of the file $tfile"
1219 }
1220 run_test 24w "Reading a file larger than 4Gb"
1221
1222 test_24x() {
1223         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1224         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1225         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1226                 skip "Need MDS version at least 2.7.56"
1227
1228         local MDTIDX=1
1229         local remote_dir=$DIR/$tdir/remote_dir
1230
1231         test_mkdir $DIR/$tdir
1232         $LFS mkdir -i $MDTIDX $remote_dir ||
1233                 error "create remote directory failed"
1234
1235         test_mkdir $DIR/$tdir/src_dir
1236         touch $DIR/$tdir/src_file
1237         test_mkdir $remote_dir/tgt_dir
1238         touch $remote_dir/tgt_file
1239
1240         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1241                 error "rename dir cross MDT failed!"
1242
1243         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1244                 error "rename file cross MDT failed!"
1245
1246         touch $DIR/$tdir/ln_file
1247         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1248                 error "ln file cross MDT failed"
1249
1250         rm -rf $DIR/$tdir || error "Can not delete directories"
1251 }
1252 run_test 24x "cross MDT rename/link"
1253
1254 test_24y() {
1255         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1256         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1257
1258         local remote_dir=$DIR/$tdir/remote_dir
1259         local mdtidx=1
1260
1261         test_mkdir $DIR/$tdir
1262         $LFS mkdir -i $mdtidx $remote_dir ||
1263                 error "create remote directory failed"
1264
1265         test_mkdir $remote_dir/src_dir
1266         touch $remote_dir/src_file
1267         test_mkdir $remote_dir/tgt_dir
1268         touch $remote_dir/tgt_file
1269
1270         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1271                 error "rename subdir in the same remote dir failed!"
1272
1273         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1274                 error "rename files in the same remote dir failed!"
1275
1276         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1277                 error "link files in the same remote dir failed!"
1278
1279         rm -rf $DIR/$tdir || error "Can not delete directories"
1280 }
1281 run_test 24y "rename/link on the same dir should succeed"
1282
1283 test_24z() {
1284         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1285         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1286                 skip "Need MDS version at least 2.12.51"
1287
1288         local index
1289
1290         for index in 0 1; do
1291                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1292                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1293         done
1294
1295         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1296
1297         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1298         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1299
1300         local mdts=$(comma_list $(mdts_nodes))
1301
1302         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1303         stack_trap "do_nodes $mdts $LCTL \
1304                 set_param mdt.*.enable_remote_rename=1" EXIT
1305
1306         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1307
1308         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1309         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1310 }
1311 run_test 24z "cross-MDT rename is done as cp"
1312
1313 test_24A() { # LU-3182
1314         local NFILES=5000
1315
1316         rm -rf $DIR/$tdir
1317         test_mkdir $DIR/$tdir
1318         trap simple_cleanup_common EXIT
1319         createmany -m $DIR/$tdir/$tfile $NFILES
1320         local t=$(ls $DIR/$tdir | wc -l)
1321         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1322         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1323         if [ $t -ne $NFILES ] || [ $u -ne $NFILES ] ||
1324            [ $v -ne $((NFILES + 2)) ] ; then
1325                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1326         fi
1327
1328         simple_cleanup_common || error "Can not delete directories"
1329 }
1330 run_test 24A "readdir() returns correct number of entries."
1331
1332 test_24B() { # LU-4805
1333         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1334
1335         local count
1336
1337         test_mkdir $DIR/$tdir
1338         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1339                 error "create striped dir failed"
1340
1341         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1342         [ $count -eq 2 ] || error "Expected 2, got $count"
1343
1344         touch $DIR/$tdir/striped_dir/a
1345
1346         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1347         [ $count -eq 3 ] || error "Expected 3, got $count"
1348
1349         touch $DIR/$tdir/striped_dir/.f
1350
1351         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1352         [ $count -eq 4 ] || error "Expected 4, got $count"
1353
1354         rm -rf $DIR/$tdir || error "Can not delete directories"
1355 }
1356 run_test 24B "readdir for striped dir return correct number of entries"
1357
1358 test_24C() {
1359         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1360
1361         mkdir $DIR/$tdir
1362         mkdir $DIR/$tdir/d0
1363         mkdir $DIR/$tdir/d1
1364
1365         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1366                 error "create striped dir failed"
1367
1368         cd $DIR/$tdir/d0/striped_dir
1369
1370         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1371         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1372         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1373
1374         [ "$d0_ino" = "$parent_ino" ] ||
1375                 error ".. wrong, expect $d0_ino, get $parent_ino"
1376
1377         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1378                 error "mv striped dir failed"
1379
1380         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1381
1382         [ "$d1_ino" = "$parent_ino" ] ||
1383                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1384 }
1385 run_test 24C "check .. in striped dir"
1386
1387 test_24E() {
1388         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1389         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1390
1391         mkdir -p $DIR/$tdir
1392         mkdir $DIR/$tdir/src_dir
1393         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1394                 error "create remote source failed"
1395
1396         touch $DIR/$tdir/src_dir/src_child/a
1397
1398         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1399                 error "create remote target dir failed"
1400
1401         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1402                 error "create remote target child failed"
1403
1404         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1405                 error "rename dir cross MDT failed!"
1406
1407         find $DIR/$tdir
1408
1409         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1410                 error "src_child still exists after rename"
1411
1412         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1413                 error "missing file(a) after rename"
1414
1415         rm -rf $DIR/$tdir || error "Can not delete directories"
1416 }
1417 run_test 24E "cross MDT rename/link"
1418
1419 test_24F () {
1420         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1421
1422         local repeats=1000
1423         [ "$SLOW" = "no" ] && repeats=100
1424
1425         mkdir -p $DIR/$tdir
1426
1427         echo "$repeats repeats"
1428         for ((i = 0; i < repeats; i++)); do
1429                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1430                 touch $DIR/$tdir/test/a || error "touch fails"
1431                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1432                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1433         done
1434
1435         true
1436 }
1437 run_test 24F "hash order vs readdir (LU-11330)"
1438
1439 test_25a() {
1440         echo '== symlink sanity ============================================='
1441
1442         test_mkdir $DIR/d25
1443         ln -s d25 $DIR/s25
1444         touch $DIR/s25/foo ||
1445                 error "File creation in symlinked directory failed"
1446 }
1447 run_test 25a "create file in symlinked directory ==============="
1448
1449 test_25b() {
1450         [ ! -d $DIR/d25 ] && test_25a
1451         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1452 }
1453 run_test 25b "lookup file in symlinked directory ==============="
1454
1455 test_26a() {
1456         test_mkdir $DIR/d26
1457         test_mkdir $DIR/d26/d26-2
1458         ln -s d26/d26-2 $DIR/s26
1459         touch $DIR/s26/foo || error "File creation failed"
1460 }
1461 run_test 26a "multiple component symlink ======================="
1462
1463 test_26b() {
1464         test_mkdir -p $DIR/$tdir/d26-2
1465         ln -s $tdir/d26-2/foo $DIR/s26-2
1466         touch $DIR/s26-2 || error "File creation failed"
1467 }
1468 run_test 26b "multiple component symlink at end of lookup ======"
1469
1470 test_26c() {
1471         test_mkdir $DIR/d26.2
1472         touch $DIR/d26.2/foo
1473         ln -s d26.2 $DIR/s26.2-1
1474         ln -s s26.2-1 $DIR/s26.2-2
1475         ln -s s26.2-2 $DIR/s26.2-3
1476         chmod 0666 $DIR/s26.2-3/foo
1477 }
1478 run_test 26c "chain of symlinks"
1479
1480 # recursive symlinks (bug 439)
1481 test_26d() {
1482         ln -s d26-3/foo $DIR/d26-3
1483 }
1484 run_test 26d "create multiple component recursive symlink"
1485
1486 test_26e() {
1487         [ ! -h $DIR/d26-3 ] && test_26d
1488         rm $DIR/d26-3
1489 }
1490 run_test 26e "unlink multiple component recursive symlink"
1491
1492 # recursive symlinks (bug 7022)
1493 test_26f() {
1494         test_mkdir $DIR/$tdir
1495         test_mkdir $DIR/$tdir/$tfile
1496         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1497         test_mkdir -p lndir/bar1
1498         test_mkdir $DIR/$tdir/$tfile/$tfile
1499         cd $tfile                || error "cd $tfile failed"
1500         ln -s .. dotdot          || error "ln dotdot failed"
1501         ln -s dotdot/lndir lndir || error "ln lndir failed"
1502         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1503         output=`ls $tfile/$tfile/lndir/bar1`
1504         [ "$output" = bar1 ] && error "unexpected output"
1505         rm -r $tfile             || error "rm $tfile failed"
1506         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1507 }
1508 run_test 26f "rm -r of a directory which has recursive symlink"
1509
1510 test_27a() {
1511         test_mkdir $DIR/$tdir
1512         $LFS getstripe $DIR/$tdir
1513         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1514         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1515         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1516 }
1517 run_test 27a "one stripe file"
1518
1519 test_27b() {
1520         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1521
1522         test_mkdir $DIR/$tdir
1523         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1524         $LFS getstripe -c $DIR/$tdir/$tfile
1525         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1526                 error "two-stripe file doesn't have two stripes"
1527
1528         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1529 }
1530 run_test 27b "create and write to two stripe file"
1531
1532 # 27c family tests specific striping, setstripe -o
1533 test_27ca() {
1534         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1535         test_mkdir -p $DIR/$tdir
1536         local osts="1"
1537
1538         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1539         $LFS getstripe -i $DIR/$tdir/$tfile
1540         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1541                 error "stripe not on specified OST"
1542
1543         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1544 }
1545 run_test 27ca "one stripe on specified OST"
1546
1547 test_27cb() {
1548         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1549         test_mkdir -p $DIR/$tdir
1550         local osts="1,0"
1551         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1552         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1553         echo "$getstripe"
1554
1555         # Strip getstripe output to a space separated list of OSTs
1556         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1557                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1558         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1559                 error "stripes not on specified OSTs"
1560
1561         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1562 }
1563 run_test 27cb "two stripes on specified OSTs"
1564
1565 test_27cc() {
1566         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1567         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1568                 skip "server does not support overstriping"
1569
1570         test_mkdir -p $DIR/$tdir
1571         local osts="0,0"
1572         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1573         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1574         echo "$getstripe"
1575
1576         # Strip getstripe output to a space separated list of OSTs
1577         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1578                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1579         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1580                 error "stripes not on specified OSTs"
1581
1582         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1583 }
1584 run_test 27cc "two stripes on the same OST"
1585
1586 test_27cd() {
1587         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1588         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1589                 skip "server does not support overstriping"
1590         test_mkdir -p $DIR/$tdir
1591         local osts="0,1,1,0"
1592         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1593         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1594         echo "$getstripe"
1595
1596         # Strip getstripe output to a space separated list of OSTs
1597         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1598                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1599         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1600                 error "stripes not on specified OSTs"
1601
1602         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1603 }
1604 run_test 27cd "four stripes on two OSTs"
1605
1606 test_27ce() {
1607         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1608                 skip_env "too many osts, skipping"
1609         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1610                 skip "server does not support overstriping"
1611         # We do one more stripe than we have OSTs
1612         [ $OSTCOUNT -ge 159 ] || large_xattr_enabled ||
1613                 skip_env "ea_inode feature disabled"
1614
1615         test_mkdir -p $DIR/$tdir
1616         local osts=""
1617         for i in $(seq 0 $OSTCOUNT);
1618         do
1619                 osts=$osts"0"
1620                 if [ $i -ne $OSTCOUNT ]; then
1621                         osts=$osts","
1622                 fi
1623         done
1624         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1625         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1626         echo "$getstripe"
1627
1628         # Strip getstripe output to a space separated list of OSTs
1629         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1630                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1631         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1632                 error "stripes not on specified OSTs"
1633
1634         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1635 }
1636 run_test 27ce "more stripes than OSTs with -o"
1637
1638 test_27cf() {
1639         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1640         local pid=0
1641
1642         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1643         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1644         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1645         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1646                 error "failed to set $osp_proc=0"
1647
1648         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1649         pid=$!
1650         sleep 1
1651         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1652         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1653                 error "failed to set $osp_proc=1"
1654         wait $pid
1655         [[ $pid -ne 0 ]] ||
1656                 error "should return error due to $osp_proc=0"
1657 }
1658 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1659
1660 test_27d() {
1661         test_mkdir $DIR/$tdir
1662         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1663                 error "setstripe failed"
1664         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1665         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1666 }
1667 run_test 27d "create file with default settings"
1668
1669 test_27e() {
1670         # LU-5839 adds check for existed layout before setting it
1671         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1672                 skip "Need MDS version at least 2.7.56"
1673
1674         test_mkdir $DIR/$tdir
1675         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1676         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1677         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1678 }
1679 run_test 27e "setstripe existing file (should return error)"
1680
1681 test_27f() {
1682         test_mkdir $DIR/$tdir
1683         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1684                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1685         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1686                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1687         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1688         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1689 }
1690 run_test 27f "setstripe with bad stripe size (should return error)"
1691
1692 test_27g() {
1693         test_mkdir $DIR/$tdir
1694         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1695         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1696                 error "$DIR/$tdir/$tfile has object"
1697 }
1698 run_test 27g "$LFS getstripe with no objects"
1699
1700 test_27ga() {
1701         test_mkdir $DIR/$tdir
1702         touch $DIR/$tdir/$tfile || error "touch failed"
1703         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1704         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1705         local rc=$?
1706         (( rc == 2 )) || error "getstripe did not return ENOENT"
1707 }
1708 run_test 27ga "$LFS getstripe with missing file (should return error)"
1709
1710 test_27i() {
1711         test_mkdir $DIR/$tdir
1712         touch $DIR/$tdir/$tfile || error "touch failed"
1713         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1714                 error "missing objects"
1715 }
1716 run_test 27i "$LFS getstripe with some objects"
1717
1718 test_27j() {
1719         test_mkdir $DIR/$tdir
1720         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1721                 error "setstripe failed" || true
1722 }
1723 run_test 27j "setstripe with bad stripe offset (should return error)"
1724
1725 test_27k() { # bug 2844
1726         test_mkdir $DIR/$tdir
1727         local file=$DIR/$tdir/$tfile
1728         local ll_max_blksize=$((4 * 1024 * 1024))
1729         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1730         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1731         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1732         dd if=/dev/zero of=$file bs=4k count=1
1733         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1734         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1735 }
1736 run_test 27k "limit i_blksize for broken user apps"
1737
1738 test_27l() {
1739         mcreate $DIR/$tfile || error "creating file"
1740         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1741                 error "setstripe should have failed" || true
1742 }
1743 run_test 27l "check setstripe permissions (should return error)"
1744
1745 test_27m() {
1746         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1747
1748         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1749                 skip_env "multiple clients -- skipping"
1750
1751         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1752                    head -n1)
1753         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1754                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1755         fi
1756         trap simple_cleanup_common EXIT
1757         test_mkdir $DIR/$tdir
1758         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1759         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1760                 error "dd should fill OST0"
1761         i=2
1762         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1763                 i=$((i + 1))
1764                 [ $i -gt 256 ] && break
1765         done
1766         i=$((i + 1))
1767         touch $DIR/$tdir/$tfile.$i
1768         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1769             awk '{print $1}'| grep -w "0") ] &&
1770                 error "OST0 was full but new created file still use it"
1771         i=$((i + 1))
1772         touch $DIR/$tdir/$tfile.$i
1773         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1774             awk '{print $1}'| grep -w "0") ] &&
1775                 error "OST0 was full but new created file still use it"
1776         simple_cleanup_common
1777 }
1778 run_test 27m "create file while OST0 was full"
1779
1780 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1781 # if the OST isn't full anymore.
1782 reset_enospc() {
1783         local ostidx=${1:-""}
1784         local delay
1785         local ready
1786         local get_prealloc
1787
1788         local list=$(comma_list $(osts_nodes))
1789         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1790
1791         do_nodes $list lctl set_param fail_loc=0
1792         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1793         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1794                 awk '{print $1 * 2;exit;}')
1795         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1796                         grep -v \"^0$\""
1797         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1798 }
1799
1800 __exhaust_precreations() {
1801         local OSTIDX=$1
1802         local FAILLOC=$2
1803         local FAILIDX=${3:-$OSTIDX}
1804         local ofacet=ost$((OSTIDX + 1))
1805
1806         test_mkdir -p -c1 $DIR/$tdir
1807         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
1808         local mfacet=mds$((mdtidx + 1))
1809         echo OSTIDX=$OSTIDX MDTIDX=$mdtidx
1810
1811         local OST=$(ostname_from_index $OSTIDX)
1812
1813         # on the mdt's osc
1814         local mdtosc_proc1=$(get_mdtosc_proc_path $mfacet $OST)
1815         local last_id=$(do_facet $mfacet lctl get_param -n \
1816                         osp.$mdtosc_proc1.prealloc_last_id)
1817         local next_id=$(do_facet $mfacet lctl get_param -n \
1818                         osp.$mdtosc_proc1.prealloc_next_id)
1819
1820         local mdtosc_proc2=$(get_mdtosc_proc_path $mfacet)
1821         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1822
1823         test_mkdir -p $DIR/$tdir/${OST}
1824         $LFS setstripe -i $OSTIDX -c 1 $DIR/$tdir/${OST}
1825 #define OBD_FAIL_OST_ENOSPC              0x215
1826         do_facet $ofacet lctl set_param fail_val=$FAILIDX fail_loc=0x215
1827         echo "Creating to objid $last_id on ost $OST..."
1828         createmany -o $DIR/$tdir/${OST}/f $next_id $((last_id - next_id + 2))
1829         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1830         do_facet $ofacet lctl set_param fail_loc=$FAILLOC
1831 }
1832
1833 exhaust_precreations() {
1834         __exhaust_precreations $1 $2 $3
1835         sleep_maxage
1836 }
1837
1838 exhaust_all_precreations() {
1839         local i
1840         for (( i=0; i < OSTCOUNT; i++ )) ; do
1841                 __exhaust_precreations $i $1 -1
1842         done
1843         sleep_maxage
1844 }
1845
1846 test_27n() {
1847         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1848         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1849         remote_mds_nodsh && skip "remote MDS with nodsh"
1850         remote_ost_nodsh && skip "remote OST with nodsh"
1851
1852         reset_enospc
1853         rm -f $DIR/$tdir/$tfile
1854         exhaust_precreations 0 0x80000215
1855         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1856         touch $DIR/$tdir/$tfile || error "touch failed"
1857         $LFS getstripe $DIR/$tdir/$tfile
1858         reset_enospc
1859 }
1860 run_test 27n "create file with some full OSTs"
1861
1862 test_27o() {
1863         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1864         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1865         remote_mds_nodsh && skip "remote MDS with nodsh"
1866         remote_ost_nodsh && skip "remote OST with nodsh"
1867
1868         reset_enospc
1869         rm -f $DIR/$tdir/$tfile
1870         exhaust_all_precreations 0x215
1871
1872         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1873
1874         reset_enospc
1875         rm -rf $DIR/$tdir/*
1876 }
1877 run_test 27o "create file with all full OSTs (should error)"
1878
1879 test_27p() {
1880         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1881         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1882         remote_mds_nodsh && skip "remote MDS with nodsh"
1883         remote_ost_nodsh && skip "remote OST with nodsh"
1884
1885         reset_enospc
1886         rm -f $DIR/$tdir/$tfile
1887         test_mkdir $DIR/$tdir
1888
1889         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1890         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1891         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1892
1893         exhaust_precreations 0 0x80000215
1894         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1895         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1896         $LFS getstripe $DIR/$tdir/$tfile
1897
1898         reset_enospc
1899 }
1900 run_test 27p "append to a truncated file with some full OSTs"
1901
1902 test_27q() {
1903         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1904         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1905         remote_mds_nodsh && skip "remote MDS with nodsh"
1906         remote_ost_nodsh && skip "remote OST with nodsh"
1907
1908         reset_enospc
1909         rm -f $DIR/$tdir/$tfile
1910
1911         test_mkdir $DIR/$tdir
1912         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1913         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1914                 error "truncate $DIR/$tdir/$tfile failed"
1915         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1916
1917         exhaust_all_precreations 0x215
1918
1919         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1920         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1921
1922         reset_enospc
1923 }
1924 run_test 27q "append to truncated file with all OSTs full (should error)"
1925
1926 test_27r() {
1927         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1928         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1929         remote_mds_nodsh && skip "remote MDS with nodsh"
1930         remote_ost_nodsh && skip "remote OST with nodsh"
1931
1932         reset_enospc
1933         rm -f $DIR/$tdir/$tfile
1934         exhaust_precreations 0 0x80000215
1935
1936         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1937
1938         reset_enospc
1939 }
1940 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
1941
1942 test_27s() { # bug 10725
1943         test_mkdir $DIR/$tdir
1944         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
1945         local stripe_count=0
1946         [ $OSTCOUNT -eq 1 ] || stripe_count=2
1947         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
1948                 error "stripe width >= 2^32 succeeded" || true
1949
1950 }
1951 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
1952
1953 test_27t() { # bug 10864
1954         WDIR=$(pwd)
1955         WLFS=$(which lfs)
1956         cd $DIR
1957         touch $tfile
1958         $WLFS getstripe $tfile
1959         cd $WDIR
1960 }
1961 run_test 27t "check that utils parse path correctly"
1962
1963 test_27u() { # bug 4900
1964         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1965         remote_mds_nodsh && skip "remote MDS with nodsh"
1966
1967         local index
1968         local list=$(comma_list $(mdts_nodes))
1969
1970 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
1971         do_nodes $list $LCTL set_param fail_loc=0x139
1972         test_mkdir -p $DIR/$tdir
1973         trap simple_cleanup_common EXIT
1974         createmany -o $DIR/$tdir/t- 1000
1975         do_nodes $list $LCTL set_param fail_loc=0
1976
1977         TLOG=$TMP/$tfile.getstripe
1978         $LFS getstripe $DIR/$tdir > $TLOG
1979         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
1980         unlinkmany $DIR/$tdir/t- 1000
1981         trap 0
1982         [[ $OBJS -gt 0 ]] &&
1983                 error "$OBJS objects created on OST-0. See $TLOG" ||
1984                 rm -f $TLOG
1985 }
1986 run_test 27u "skip object creation on OSC w/o objects"
1987
1988 test_27v() { # bug 4900
1989         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1990         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1991         remote_mds_nodsh && skip "remote MDS with nodsh"
1992         remote_ost_nodsh && skip "remote OST with nodsh"
1993
1994         exhaust_all_precreations 0x215
1995         reset_enospc
1996
1997         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
1998
1999         touch $DIR/$tdir/$tfile
2000         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2001         # all except ost1
2002         for (( i=1; i < OSTCOUNT; i++ )); do
2003                 do_facet ost$i lctl set_param fail_loc=0x705
2004         done
2005         local START=`date +%s`
2006         createmany -o $DIR/$tdir/$tfile 32
2007
2008         local FINISH=`date +%s`
2009         local TIMEOUT=`lctl get_param -n timeout`
2010         local PROCESS=$((FINISH - START))
2011         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2012                error "$FINISH - $START >= $TIMEOUT / 2"
2013         sleep $((TIMEOUT / 2 - PROCESS))
2014         reset_enospc
2015 }
2016 run_test 27v "skip object creation on slow OST"
2017
2018 test_27w() { # bug 10997
2019         test_mkdir $DIR/$tdir
2020         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2021         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2022                 error "stripe size $size != 65536" || true
2023         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2024                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2025 }
2026 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2027
2028 test_27wa() {
2029         [[ $OSTCOUNT -lt 2 ]] &&
2030                 skip_env "skipping multiple stripe count/offset test"
2031
2032         test_mkdir $DIR/$tdir
2033         for i in $(seq 1 $OSTCOUNT); do
2034                 offset=$((i - 1))
2035                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2036                         error "setstripe -c $i -i $offset failed"
2037                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2038                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2039                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2040                 [ $index -ne $offset ] &&
2041                         error "stripe offset $index != $offset" || true
2042         done
2043 }
2044 run_test 27wa "check $LFS setstripe -c -i options"
2045
2046 test_27x() {
2047         remote_ost_nodsh && skip "remote OST with nodsh"
2048         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2049         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2050
2051         OFFSET=$(($OSTCOUNT - 1))
2052         OSTIDX=0
2053         local OST=$(ostname_from_index $OSTIDX)
2054
2055         test_mkdir $DIR/$tdir
2056         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2057         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2058         sleep_maxage
2059         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2060         for i in $(seq 0 $OFFSET); do
2061                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2062                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2063                 error "OST0 was degraded but new created file still use it"
2064         done
2065         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2066 }
2067 run_test 27x "create files while OST0 is degraded"
2068
2069 test_27y() {
2070         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2071         remote_mds_nodsh && skip "remote MDS with nodsh"
2072         remote_ost_nodsh && skip "remote OST with nodsh"
2073         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2074
2075         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2076         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2077                 osp.$mdtosc.prealloc_last_id)
2078         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2079                 osp.$mdtosc.prealloc_next_id)
2080         local fcount=$((last_id - next_id))
2081         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2082         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2083
2084         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2085                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2086         local OST_DEACTIVE_IDX=-1
2087         local OSC
2088         local OSTIDX
2089         local OST
2090
2091         for OSC in $MDS_OSCS; do
2092                 OST=$(osc_to_ost $OSC)
2093                 OSTIDX=$(index_from_ostuuid $OST)
2094                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2095                         OST_DEACTIVE_IDX=$OSTIDX
2096                 fi
2097                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2098                         echo $OSC "is Deactivated:"
2099                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2100                 fi
2101         done
2102
2103         OSTIDX=$(index_from_ostuuid $OST)
2104         test_mkdir $DIR/$tdir
2105         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2106
2107         for OSC in $MDS_OSCS; do
2108                 OST=$(osc_to_ost $OSC)
2109                 OSTIDX=$(index_from_ostuuid $OST)
2110                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2111                         echo $OST "is degraded:"
2112                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2113                                                 obdfilter.$OST.degraded=1
2114                 fi
2115         done
2116
2117         sleep_maxage
2118         createmany -o $DIR/$tdir/$tfile $fcount
2119
2120         for OSC in $MDS_OSCS; do
2121                 OST=$(osc_to_ost $OSC)
2122                 OSTIDX=$(index_from_ostuuid $OST)
2123                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2124                         echo $OST "is recovered from degraded:"
2125                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2126                                                 obdfilter.$OST.degraded=0
2127                 else
2128                         do_facet $SINGLEMDS lctl --device %$OSC activate
2129                 fi
2130         done
2131
2132         # all osp devices get activated, hence -1 stripe count restored
2133         local stripe_count=0
2134
2135         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2136         # devices get activated.
2137         sleep_maxage
2138         $LFS setstripe -c -1 $DIR/$tfile
2139         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2140         rm -f $DIR/$tfile
2141         [ $stripe_count -ne $OSTCOUNT ] &&
2142                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2143         return 0
2144 }
2145 run_test 27y "create files while OST0 is degraded and the rest inactive"
2146
2147 check_seq_oid()
2148 {
2149         log "check file $1"
2150
2151         lmm_count=$($LFS getstripe -c $1)
2152         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2153         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2154
2155         local old_ifs="$IFS"
2156         IFS=$'[:]'
2157         fid=($($LFS path2fid $1))
2158         IFS="$old_ifs"
2159
2160         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2161         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2162
2163         # compare lmm_seq and lu_fid->f_seq
2164         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2165         # compare lmm_object_id and lu_fid->oid
2166         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2167
2168         # check the trusted.fid attribute of the OST objects of the file
2169         local have_obdidx=false
2170         local stripe_nr=0
2171         $LFS getstripe $1 | while read obdidx oid hex seq; do
2172                 # skip lines up to and including "obdidx"
2173                 [ -z "$obdidx" ] && break
2174                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2175                 $have_obdidx || continue
2176
2177                 local ost=$((obdidx + 1))
2178                 local dev=$(ostdevname $ost)
2179                 local oid_hex
2180
2181                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2182
2183                 seq=$(echo $seq | sed -e "s/^0x//g")
2184                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2185                         oid_hex=$(echo $oid)
2186                 else
2187                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2188                 fi
2189                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2190
2191                 local ff=""
2192                 #
2193                 # Don't unmount/remount the OSTs if we don't need to do that.
2194                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2195                 # update too, until that use mount/ll_decode_filter_fid/mount.
2196                 # Re-enable when debugfs will understand new filter_fid.
2197                 #
2198                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2199                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2200                                 $dev 2>/dev/null" | grep "parent=")
2201                 fi
2202                 if [ -z "$ff" ]; then
2203                         stop ost$ost
2204                         mount_fstype ost$ost
2205                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2206                                 $(facet_mntpt ost$ost)/$obj_file)
2207                         unmount_fstype ost$ost
2208                         start ost$ost $dev $OST_MOUNT_OPTS
2209                         clients_up
2210                 fi
2211
2212                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2213
2214                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2215
2216                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2217                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2218                 #
2219                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2220                 #       stripe_size=1048576 component_id=1 component_start=0 \
2221                 #       component_end=33554432
2222                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2223                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2224                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2225                 local ff_pstripe
2226                 if grep -q 'stripe=' <<<$ff; then
2227                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2228                 else
2229                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2230                         # into f_ver in this case.  See comment on ff_parent.
2231                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2232                 fi
2233
2234                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2235                 [ $ff_pseq = $lmm_seq ] ||
2236                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2237                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2238                 [ $ff_poid = $lmm_oid ] ||
2239                         error "FF parent OID $ff_poid != $lmm_oid"
2240                 (($ff_pstripe == $stripe_nr)) ||
2241                         error "FF stripe $ff_pstripe != $stripe_nr"
2242
2243                 stripe_nr=$((stripe_nr + 1))
2244                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2245                         continue
2246                 if grep -q 'stripe_count=' <<<$ff; then
2247                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2248                                             -e 's/ .*//' <<<$ff)
2249                         [ $lmm_count = $ff_scnt ] ||
2250                                 error "FF stripe count $lmm_count != $ff_scnt"
2251                 fi
2252         done
2253 }
2254
2255 test_27z() {
2256         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2257         remote_ost_nodsh && skip "remote OST with nodsh"
2258
2259         test_mkdir $DIR/$tdir
2260         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2261                 { error "setstripe -c -1 failed"; return 1; }
2262         # We need to send a write to every object to get parent FID info set.
2263         # This _should_ also work for setattr, but does not currently.
2264         # touch $DIR/$tdir/$tfile-1 ||
2265         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2266                 { error "dd $tfile-1 failed"; return 2; }
2267         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2268                 { error "setstripe -c -1 failed"; return 3; }
2269         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2270                 { error "dd $tfile-2 failed"; return 4; }
2271
2272         # make sure write RPCs have been sent to OSTs
2273         sync; sleep 5; sync
2274
2275         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2276         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2277 }
2278 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2279
2280 test_27A() { # b=19102
2281         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2282
2283         save_layout_restore_at_exit $MOUNT
2284         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2285         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2286                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2287         local default_size=$($LFS getstripe -S $MOUNT)
2288         local default_offset=$($LFS getstripe -i $MOUNT)
2289         local dsize=$(do_facet $SINGLEMDS \
2290                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2291         [ $default_size -eq $dsize ] ||
2292                 error "stripe size $default_size != $dsize"
2293         [ $default_offset -eq -1 ] ||
2294                 error "stripe offset $default_offset != -1"
2295 }
2296 run_test 27A "check filesystem-wide default LOV EA values"
2297
2298 test_27B() { # LU-2523
2299         test_mkdir $DIR/$tdir
2300         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2301         touch $DIR/$tdir/f0
2302         # open f1 with O_LOV_DELAY_CREATE
2303         # rename f0 onto f1
2304         # call setstripe ioctl on open file descriptor for f1
2305         # close
2306         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2307                 $DIR/$tdir/f0
2308
2309         rm -f $DIR/$tdir/f1
2310         # open f1 with O_LOV_DELAY_CREATE
2311         # unlink f1
2312         # call setstripe ioctl on open file descriptor for f1
2313         # close
2314         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2315
2316         # Allow multiop to fail in imitation of NFS's busted semantics.
2317         true
2318 }
2319 run_test 27B "call setstripe on open unlinked file/rename victim"
2320
2321 # 27C family tests full striping and overstriping
2322 test_27Ca() { #LU-2871
2323         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2324
2325         declare -a ost_idx
2326         local index
2327         local found
2328         local i
2329         local j
2330
2331         test_mkdir $DIR/$tdir
2332         cd $DIR/$tdir
2333         for i in $(seq 0 $((OSTCOUNT - 1))); do
2334                 # set stripe across all OSTs starting from OST$i
2335                 $LFS setstripe -i $i -c -1 $tfile$i
2336                 # get striping information
2337                 ost_idx=($($LFS getstripe $tfile$i |
2338                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2339                 echo ${ost_idx[@]}
2340
2341                 # check the layout
2342                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2343                         error "${#ost_idx[@]} != $OSTCOUNT"
2344
2345                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2346                         found=0
2347                         for j in $(echo ${ost_idx[@]}); do
2348                                 if [ $index -eq $j ]; then
2349                                         found=1
2350                                         break
2351                                 fi
2352                         done
2353                         [ $found = 1 ] ||
2354                                 error "Can not find $index in ${ost_idx[@]}"
2355                 done
2356         done
2357 }
2358 run_test 27Ca "check full striping across all OSTs"
2359
2360 test_27Cb() {
2361         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2362                 skip "server does not support overstriping"
2363         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2364                 skip_env "too many osts, skipping"
2365
2366         test_mkdir -p $DIR/$tdir
2367         local setcount=$(($OSTCOUNT * 2))
2368         [ $setcount -ge 160 ] || large_xattr_enabled ||
2369                 skip_env "ea_inode feature disabled"
2370
2371         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2372                 error "setstripe failed"
2373
2374         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2375         [ $count -eq $setcount ] ||
2376                 error "stripe count $count, should be $setcount"
2377
2378         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2379                 error "overstriped should be set in pattern"
2380
2381         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2382                 error "dd failed"
2383 }
2384 run_test 27Cb "more stripes than OSTs with -C"
2385
2386 test_27Cc() {
2387         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2388                 skip "server does not support overstriping"
2389         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2390
2391         test_mkdir -p $DIR/$tdir
2392         local setcount=$(($OSTCOUNT - 1))
2393
2394         [ $setcount -ge 160 ] || large_xattr_enabled ||
2395                 skip_env "ea_inode feature disabled"
2396
2397         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2398                 error "setstripe failed"
2399
2400         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2401         [ $count -eq $setcount ] ||
2402                 error "stripe count $count, should be $setcount"
2403
2404         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2405                 error "overstriped should not be set in pattern"
2406
2407         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2408                 error "dd failed"
2409 }
2410 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2411
2412 test_27Cd() {
2413         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2414                 skip "server does not support overstriping"
2415         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2416         large_xattr_enabled || skip_env "ea_inode feature disabled"
2417
2418         test_mkdir -p $DIR/$tdir
2419         local setcount=$LOV_MAX_STRIPE_COUNT
2420
2421         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2422                 error "setstripe failed"
2423
2424         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2425         [ $count -eq $setcount ] ||
2426                 error "stripe count $count, should be $setcount"
2427
2428         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2429                 error "overstriped should be set in pattern"
2430
2431         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2432                 error "dd failed"
2433
2434         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2435 }
2436 run_test 27Cd "test maximum stripe count"
2437
2438 test_27Ce() {
2439         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2440                 skip "server does not support overstriping"
2441         test_mkdir -p $DIR/$tdir
2442
2443         pool_add $TESTNAME || error "Pool creation failed"
2444         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2445
2446         local setcount=8
2447
2448         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2449                 error "setstripe failed"
2450
2451         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2452         [ $count -eq $setcount ] ||
2453                 error "stripe count $count, should be $setcount"
2454
2455         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2456                 error "overstriped should be set in pattern"
2457
2458         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2459                 error "dd failed"
2460
2461         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2462 }
2463 run_test 27Ce "test pool with overstriping"
2464
2465 test_27Cf() {
2466         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2467                 skip "server does not support overstriping"
2468         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2469                 skip_env "too many osts, skipping"
2470
2471         test_mkdir -p $DIR/$tdir
2472
2473         local setcount=$(($OSTCOUNT * 2))
2474         [ $setcount -ge 160 ] || large_xattr_enabled ||
2475                 skip_env "ea_inode feature disabled"
2476
2477         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2478                 error "setstripe failed"
2479
2480         echo 1 > $DIR/$tdir/$tfile
2481
2482         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2483         [ $count -eq $setcount ] ||
2484                 error "stripe count $count, should be $setcount"
2485
2486         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2487                 error "overstriped should be set in pattern"
2488
2489         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2490                 error "dd failed"
2491
2492         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2493 }
2494 run_test 27Cf "test default inheritance with overstriping"
2495
2496 test_27D() {
2497         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2498         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2499         remote_mds_nodsh && skip "remote MDS with nodsh"
2500
2501         local POOL=${POOL:-testpool}
2502         local first_ost=0
2503         local last_ost=$(($OSTCOUNT - 1))
2504         local ost_step=1
2505         local ost_list=$(seq $first_ost $ost_step $last_ost)
2506         local ost_range="$first_ost $last_ost $ost_step"
2507
2508         test_mkdir $DIR/$tdir
2509         pool_add $POOL || error "pool_add failed"
2510         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2511
2512         local skip27D
2513         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2514                 skip27D+="-s 29"
2515         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2516                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2517                         skip27D+=" -s 30,31"
2518         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2519           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2520                 skip27D+=" -s 32,33"
2521         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2522                 skip27D+=" -s 34"
2523         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2524                 error "llapi_layout_test failed"
2525
2526         destroy_test_pools || error "destroy test pools failed"
2527 }
2528 run_test 27D "validate llapi_layout API"
2529
2530 # Verify that default_easize is increased from its initial value after
2531 # accessing a widely striped file.
2532 test_27E() {
2533         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2534         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2535                 skip "client does not have LU-3338 fix"
2536
2537         # 72 bytes is the minimum space required to store striping
2538         # information for a file striped across one OST:
2539         # (sizeof(struct lov_user_md_v3) +
2540         #  sizeof(struct lov_user_ost_data_v1))
2541         local min_easize=72
2542         $LCTL set_param -n llite.*.default_easize $min_easize ||
2543                 error "lctl set_param failed"
2544         local easize=$($LCTL get_param -n llite.*.default_easize)
2545
2546         [ $easize -eq $min_easize ] ||
2547                 error "failed to set default_easize"
2548
2549         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2550                 error "setstripe failed"
2551         # In order to ensure stat() call actually talks to MDS we need to
2552         # do something drastic to this file to shake off all lock, e.g.
2553         # rename it (kills lookup lock forcing cache cleaning)
2554         mv $DIR/$tfile $DIR/${tfile}-1
2555         ls -l $DIR/${tfile}-1
2556         rm $DIR/${tfile}-1
2557
2558         easize=$($LCTL get_param -n llite.*.default_easize)
2559
2560         [ $easize -gt $min_easize ] ||
2561                 error "default_easize not updated"
2562 }
2563 run_test 27E "check that default extended attribute size properly increases"
2564
2565 test_27F() { # LU-5346/LU-7975
2566         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2567         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2568         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2569                 skip "Need MDS version at least 2.8.51"
2570         remote_ost_nodsh && skip "remote OST with nodsh"
2571
2572         test_mkdir $DIR/$tdir
2573         rm -f $DIR/$tdir/f0
2574         $LFS setstripe -c 2 $DIR/$tdir
2575
2576         # stop all OSTs to reproduce situation for LU-7975 ticket
2577         for num in $(seq $OSTCOUNT); do
2578                 stop ost$num
2579         done
2580
2581         # open/create f0 with O_LOV_DELAY_CREATE
2582         # truncate f0 to a non-0 size
2583         # close
2584         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2585
2586         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2587         # open/write it again to force delayed layout creation
2588         cat /etc/hosts > $DIR/$tdir/f0 &
2589         catpid=$!
2590
2591         # restart OSTs
2592         for num in $(seq $OSTCOUNT); do
2593                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2594                         error "ost$num failed to start"
2595         done
2596
2597         wait $catpid || error "cat failed"
2598
2599         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2600         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2601                 error "wrong stripecount"
2602
2603 }
2604 run_test 27F "Client resend delayed layout creation with non-zero size"
2605
2606 test_27G() { #LU-10629
2607         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2608                 skip "Need MDS version at least 2.11.51"
2609         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2610         remote_mds_nodsh && skip "remote MDS with nodsh"
2611         local POOL=${POOL:-testpool}
2612         local ostrange="0 0 1"
2613
2614         test_mkdir $DIR/$tdir
2615         touch $DIR/$tdir/$tfile.nopool
2616         pool_add $POOL || error "pool_add failed"
2617         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2618         $LFS setstripe -p $POOL $DIR/$tdir
2619
2620         local pool=$($LFS getstripe -p $DIR/$tdir)
2621
2622         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2623         touch $DIR/$tdir/$tfile.default
2624         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2625         $LFS find $DIR/$tdir -type f --pool $POOL
2626         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2627         [[ "$found" == "2" ]] ||
2628                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2629
2630         $LFS setstripe -d $DIR/$tdir
2631
2632         pool=$($LFS getstripe -p -d $DIR/$tdir)
2633
2634         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2635 }
2636 run_test 27G "Clear OST pool from stripe"
2637
2638 test_27H() {
2639         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2640                 skip "Need MDS version newer than 2.11.54"
2641         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2642         test_mkdir $DIR/$tdir
2643         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2644         touch $DIR/$tdir/$tfile
2645         $LFS getstripe -c $DIR/$tdir/$tfile
2646         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2647                 error "two-stripe file doesn't have two stripes"
2648
2649         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2650         $LFS getstripe -y $DIR/$tdir/$tfile
2651         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2652              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2653                 error "expected l_ost_idx: [02]$ not matched"
2654
2655         # make sure ost list has been cleared
2656         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2657         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2658                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2659         touch $DIR/$tdir/f3
2660         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2661 }
2662 run_test 27H "Set specific OSTs stripe"
2663
2664 test_27I() {
2665         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2666         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2667         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2668                 skip "Need MDS version newer than 2.12.52"
2669         local pool=$TESTNAME
2670         local ostrange="1 1 1"
2671
2672         save_layout_restore_at_exit $MOUNT
2673         $LFS setstripe -c 2 -i 0 $MOUNT
2674         pool_add $pool || error "pool_add failed"
2675         pool_add_targets $pool $ostrange || "pool_add_targets failed"
2676         test_mkdir $DIR/$tdir
2677         $LFS setstripe -p $pool $DIR/$tdir
2678         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2679         $LFS getstripe $DIR/$tdir/$tfile
2680 }
2681 run_test 27I "check that root dir striping does not break parent dir one"
2682
2683 test_27J() {
2684         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2685                 skip "Need MDS version newer than 2.12.51"
2686
2687         test_mkdir $DIR/$tdir
2688         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2689         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2690
2691         # create foreign file (raw way)
2692         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2693                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2694
2695         # verify foreign file (raw way)
2696         parse_foreign_file -f $DIR/$tdir/$tfile |
2697                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2698                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2699         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2700                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2701         parse_foreign_file -f $DIR/$tdir/$tfile |
2702                 grep "lov_foreign_size: 73" ||
2703                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2704         parse_foreign_file -f $DIR/$tdir/$tfile |
2705                 grep "lov_foreign_type: 1" ||
2706                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2707         parse_foreign_file -f $DIR/$tdir/$tfile |
2708                 grep "lov_foreign_flags: 0x0000DA08" ||
2709                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2710         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2711                 grep "lov_foreign_value: 0x" |
2712                 sed -e 's/lov_foreign_value: 0x//')
2713         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2714         [[ $lov = ${lov2// /} ]] ||
2715                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2716
2717         # create foreign file (lfs + API)
2718         $LFS setstripe --foreign=daos --flags 0xda08 \
2719                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2720                 error "$DIR/$tdir/${tfile}2: create failed"
2721
2722         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2723                 grep "lfm_magic:.*0x0BD70BD0" ||
2724                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2725         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2726         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2727                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2728         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*daos" ||
2729                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2730         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2731                 grep "lfm_flags:.*0x0000DA08" ||
2732                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2733         $LFS getstripe $DIR/$tdir/${tfile}2 |
2734                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2735                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2736
2737         # modify striping should fail
2738         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2739                 error "$DIR/$tdir/$tfile: setstripe should fail"
2740         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2741                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2742
2743         # R/W should fail
2744         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2745         cat $DIR/$tdir/${tfile}2 &&
2746                 error "$DIR/$tdir/${tfile}2: read should fail"
2747         cat /etc/passwd > $DIR/$tdir/$tfile &&
2748                 error "$DIR/$tdir/$tfile: write should fail"
2749         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2750                 error "$DIR/$tdir/${tfile}2: write should fail"
2751
2752         # chmod should work
2753         chmod 222 $DIR/$tdir/$tfile ||
2754                 error "$DIR/$tdir/$tfile: chmod failed"
2755         chmod 222 $DIR/$tdir/${tfile}2 ||
2756                 error "$DIR/$tdir/${tfile}2: chmod failed"
2757
2758         # chown should work
2759         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2760                 error "$DIR/$tdir/$tfile: chown failed"
2761         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2762                 error "$DIR/$tdir/${tfile}2: chown failed"
2763
2764         # rename should work
2765         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2766                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2767         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2768                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2769
2770         #remove foreign file
2771         rm $DIR/$tdir/${tfile}.new ||
2772                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2773         rm $DIR/$tdir/${tfile}2.new ||
2774                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2775 }
2776 run_test 27J "basic ops on file with foreign LOV"
2777
2778 test_27K() {
2779         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2780                 skip "Need MDS version newer than 2.12.49"
2781
2782         test_mkdir $DIR/$tdir
2783         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2784         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2785
2786         # create foreign dir (raw way)
2787         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2788                 error "create_foreign_dir FAILED"
2789
2790         # verify foreign dir (raw way)
2791         parse_foreign_dir -d $DIR/$tdir/$tdir |
2792                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2793                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2794         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2795                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2796         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2797                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2798         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_flags: 0$" ||
2799                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2800         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2801                 grep "lmv_foreign_value: 0x" |
2802                 sed 's/lmv_foreign_value: 0x//')
2803         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2804                 sed 's/ //g')
2805         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2806
2807         # create foreign dir (lfs + API)
2808         $LFS mkdir --foreign=daos --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2809                 $DIR/$tdir/${tdir}2 ||
2810                 error "$DIR/$tdir/${tdir}2: create failed"
2811
2812         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2813                 grep "lfm_magic:.*0x0CD50CD0" ||
2814                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2815         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2816         # - sizeof(lfm_type) - sizeof(lfm_flags)
2817         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2818                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2819         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*daos" ||
2820                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2821         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2822                 grep "lfm_flags:.*0x0000DA05" ||
2823                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2824         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2825                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2826                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2827
2828         # file create in dir should fail
2829         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
2830         touch $DIR/$tdir/${tdir}2/$tfile &&
2831                 "$DIR/${tdir}2: file create should fail"
2832
2833         # chmod should work
2834         chmod 777 $DIR/$tdir/$tdir ||
2835                 error "$DIR/$tdir: chmod failed"
2836         chmod 777 $DIR/$tdir/${tdir}2 ||
2837                 error "$DIR/${tdir}2: chmod failed"
2838
2839         # chown should work
2840         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2841                 error "$DIR/$tdir: chown failed"
2842         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2843                 error "$DIR/${tdir}2: chown failed"
2844
2845         # rename should work
2846         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2847                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2848         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2849                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2850
2851         #remove foreign dir
2852         rmdir $DIR/$tdir/${tdir}.new ||
2853                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2854         rmdir $DIR/$tdir/${tdir}2.new ||
2855                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2856 }
2857 run_test 27K "basic ops on dir with foreign LMV"
2858
2859 test_27L() {
2860         remote_mds_nodsh && skip "remote MDS with nodsh"
2861
2862         local POOL=${POOL:-$TESTNAME}
2863
2864         pool_add $POOL || error "pool_add failed"
2865
2866         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2867                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2868                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2869 }
2870 run_test 27L "lfs pool_list gives correct pool name"
2871
2872 test_27M() {
2873         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2874                 skip "Need MDS version >= than 2.12.57"
2875         remote_mds_nodsh && skip "remote MDS with nodsh"
2876         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2877
2878         test_mkdir $DIR/$tdir
2879
2880         # Set default striping on directory
2881         $LFS setstripe -C 4 $DIR/$tdir
2882
2883         echo 1 > $DIR/$tdir/${tfile}.1
2884         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2885         local setcount=4
2886         [ $count -eq $setcount ] ||
2887                 error "(1) stripe count $count, should be $setcount"
2888
2889         # Capture existing append_stripe_count setting for restore
2890         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2891         local mdts=$(comma_list $(mdts_nodes))
2892         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$orig_count" EXIT
2893
2894         local appendcount=$orig_count
2895         echo 1 >> $DIR/$tdir/${tfile}.2_append
2896         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
2897         [ $count -eq $appendcount ] ||
2898                 error "(2)stripe count $count, should be $appendcount for append"
2899
2900         # Disable O_APPEND striping, verify it works
2901         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
2902
2903         # Should now get the default striping, which is 4
2904         setcount=4
2905         echo 1 >> $DIR/$tdir/${tfile}.3_append
2906         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
2907         [ $count -eq $setcount ] ||
2908                 error "(3) stripe count $count, should be $setcount"
2909
2910         # Try changing the stripe count for append files
2911         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
2912
2913         # Append striping is now 2 (directory default is still 4)
2914         appendcount=2
2915         echo 1 >> $DIR/$tdir/${tfile}.4_append
2916         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
2917         [ $count -eq $appendcount ] ||
2918                 error "(4) stripe count $count, should be $appendcount for append"
2919
2920         # Test append stripe count of -1
2921         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
2922         appendcount=$OSTCOUNT
2923         echo 1 >> $DIR/$tdir/${tfile}.5
2924         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
2925         [ $count -eq $appendcount ] ||
2926                 error "(5) stripe count $count, should be $appendcount for append"
2927
2928         # Set append striping back to default of 1
2929         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
2930
2931         # Try a new default striping, PFL + DOM
2932         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
2933
2934         # Create normal DOM file, DOM returns stripe count == 0
2935         setcount=0
2936         touch $DIR/$tdir/${tfile}.6
2937         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
2938         [ $count -eq $setcount ] ||
2939                 error "(6) stripe count $count, should be $setcount"
2940
2941         # Show
2942         appendcount=1
2943         echo 1 >> $DIR/$tdir/${tfile}.7_append
2944         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
2945         [ $count -eq $appendcount ] ||
2946                 error "(7) stripe count $count, should be $appendcount for append"
2947
2948         # Clean up DOM layout
2949         $LFS setstripe -d $DIR/$tdir
2950
2951         # Now test that append striping works when layout is from root
2952         $LFS setstripe -c 2 $MOUNT
2953         # Make a special directory for this
2954         mkdir $DIR/${tdir}/${tdir}.2
2955         stack_trap "$LFS setstripe -d $MOUNT" EXIT
2956
2957         # Verify for normal file
2958         setcount=2
2959         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
2960         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
2961         [ $count -eq $setcount ] ||
2962                 error "(8) stripe count $count, should be $setcount"
2963
2964         appendcount=1
2965         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
2966         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
2967         [ $count -eq $appendcount ] ||
2968                 error "(9) stripe count $count, should be $appendcount for append"
2969
2970         # Now test O_APPEND striping with pools
2971         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
2972         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'" EXIT
2973
2974         # Create the pool
2975         pool_add $TESTNAME || error "pool creation failed"
2976         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
2977
2978         echo 1 >> $DIR/$tdir/${tfile}.10_append
2979
2980         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
2981         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
2982
2983         # Check that count is still correct
2984         appendcount=1
2985         echo 1 >> $DIR/$tdir/${tfile}.11_append
2986         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
2987         [ $count -eq $appendcount ] ||
2988                 error "(11) stripe count $count, should be $appendcount for append"
2989
2990         # Disable O_APPEND stripe count, verify pool works separately
2991         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
2992
2993         echo 1 >> $DIR/$tdir/${tfile}.12_append
2994
2995         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
2996         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
2997
2998         # Remove pool setting, verify it's not applied
2999         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3000
3001         echo 1 >> $DIR/$tdir/${tfile}.13_append
3002
3003         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3004         [ "$pool" = "" ] || error "(13) pool found: $pool"
3005 }
3006 run_test 27M "test O_APPEND striping"
3007
3008 test_27N() {
3009         combined_mgs_mds && skip "needs separate MGS/MDT"
3010
3011         pool_add $TESTNAME || error "pool_add failed"
3012         do_facet mgs "$LCTL pool_list $FSNAME" |
3013                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3014                 error "lctl pool_list on MGS failed"
3015 }
3016 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3017
3018 # createtest also checks that device nodes are created and
3019 # then visible correctly (#2091)
3020 test_28() { # bug 2091
3021         test_mkdir $DIR/d28
3022         $CREATETEST $DIR/d28/ct || error "createtest failed"
3023 }
3024 run_test 28 "create/mknod/mkdir with bad file types ============"
3025
3026 test_29() {
3027         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3028
3029         sync; sleep 1; sync # flush out any dirty pages from previous tests
3030         cancel_lru_locks
3031         test_mkdir $DIR/d29
3032         touch $DIR/d29/foo
3033         log 'first d29'
3034         ls -l $DIR/d29
3035
3036         declare -i LOCKCOUNTORIG=0
3037         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3038                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3039         done
3040         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3041
3042         declare -i LOCKUNUSEDCOUNTORIG=0
3043         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3044                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3045         done
3046
3047         log 'second d29'
3048         ls -l $DIR/d29
3049         log 'done'
3050
3051         declare -i LOCKCOUNTCURRENT=0
3052         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3053                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3054         done
3055
3056         declare -i LOCKUNUSEDCOUNTCURRENT=0
3057         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3058                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3059         done
3060
3061         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3062                 $LCTL set_param -n ldlm.dump_namespaces ""
3063                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3064                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3065                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3066                 return 2
3067         fi
3068         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3069                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3070                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3071                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3072                 return 3
3073         fi
3074 }
3075 run_test 29 "IT_GETATTR regression  ============================"
3076
3077 test_30a() { # was test_30
3078         cp $(which ls) $DIR || cp /bin/ls $DIR
3079         $DIR/ls / || error "Can't execute binary from lustre"
3080         rm $DIR/ls
3081 }
3082 run_test 30a "execute binary from Lustre (execve) =============="
3083
3084 test_30b() {
3085         cp `which ls` $DIR || cp /bin/ls $DIR
3086         chmod go+rx $DIR/ls
3087         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3088         rm $DIR/ls
3089 }
3090 run_test 30b "execute binary from Lustre as non-root ==========="
3091
3092 test_30c() { # b=22376
3093         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3094
3095         cp $(which ls) $DIR || cp /bin/ls $DIR
3096         chmod a-rw $DIR/ls
3097         cancel_lru_locks mdc
3098         cancel_lru_locks osc
3099         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3100         rm -f $DIR/ls
3101 }
3102 run_test 30c "execute binary from Lustre without read perms ===="
3103
3104 test_30d() {
3105         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3106
3107         for i in {1..10}; do
3108                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3109                 local PID=$!
3110                 sleep 1
3111                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3112                 wait $PID || error "executing dd from Lustre failed"
3113                 rm -f $DIR/$tfile
3114         done
3115
3116         rm -f $DIR/dd
3117 }
3118 run_test 30d "execute binary from Lustre while clear locks"
3119
3120 test_31a() {
3121         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3122         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3123 }
3124 run_test 31a "open-unlink file =================================="
3125
3126 test_31b() {
3127         touch $DIR/f31 || error "touch $DIR/f31 failed"
3128         ln $DIR/f31 $DIR/f31b || error "ln failed"
3129         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3130         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3131 }
3132 run_test 31b "unlink file with multiple links while open ======="
3133
3134 test_31c() {
3135         touch $DIR/f31 || error "touch $DIR/f31 failed"
3136         ln $DIR/f31 $DIR/f31c || error "ln failed"
3137         multiop_bg_pause $DIR/f31 O_uc ||
3138                 error "multiop_bg_pause for $DIR/f31 failed"
3139         MULTIPID=$!
3140         $MULTIOP $DIR/f31c Ouc
3141         kill -USR1 $MULTIPID
3142         wait $MULTIPID
3143 }
3144 run_test 31c "open-unlink file with multiple links ============="
3145
3146 test_31d() {
3147         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3148         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3149 }
3150 run_test 31d "remove of open directory ========================="
3151
3152 test_31e() { # bug 2904
3153         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3154 }
3155 run_test 31e "remove of open non-empty directory ==============="
3156
3157 test_31f() { # bug 4554
3158         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3159
3160         set -vx
3161         test_mkdir $DIR/d31f
3162         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3163         cp /etc/hosts $DIR/d31f
3164         ls -l $DIR/d31f
3165         $LFS getstripe $DIR/d31f/hosts
3166         multiop_bg_pause $DIR/d31f D_c || return 1
3167         MULTIPID=$!
3168
3169         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3170         test_mkdir $DIR/d31f
3171         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3172         cp /etc/hosts $DIR/d31f
3173         ls -l $DIR/d31f
3174         $LFS getstripe $DIR/d31f/hosts
3175         multiop_bg_pause $DIR/d31f D_c || return 1
3176         MULTIPID2=$!
3177
3178         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3179         wait $MULTIPID || error "first opendir $MULTIPID failed"
3180
3181         sleep 6
3182
3183         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3184         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3185         set +vx
3186 }
3187 run_test 31f "remove of open directory with open-unlink file ==="
3188
3189 test_31g() {
3190         echo "-- cross directory link --"
3191         test_mkdir -c1 $DIR/${tdir}ga
3192         test_mkdir -c1 $DIR/${tdir}gb
3193         touch $DIR/${tdir}ga/f
3194         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3195         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3196         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3197         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3198         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3199 }
3200 run_test 31g "cross directory link==============="
3201
3202 test_31h() {
3203         echo "-- cross directory link --"
3204         test_mkdir -c1 $DIR/${tdir}
3205         test_mkdir -c1 $DIR/${tdir}/dir
3206         touch $DIR/${tdir}/f
3207         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3208         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3209         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3210         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3211         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3212 }
3213 run_test 31h "cross directory link under child==============="
3214
3215 test_31i() {
3216         echo "-- cross directory link --"
3217         test_mkdir -c1 $DIR/$tdir
3218         test_mkdir -c1 $DIR/$tdir/dir
3219         touch $DIR/$tdir/dir/f
3220         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3221         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3222         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3223         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3224         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3225 }
3226 run_test 31i "cross directory link under parent==============="
3227
3228 test_31j() {
3229         test_mkdir -c1 -p $DIR/$tdir
3230         test_mkdir -c1 -p $DIR/$tdir/dir1
3231         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3232         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3233         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3234         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3235         return 0
3236 }
3237 run_test 31j "link for directory==============="
3238
3239 test_31k() {
3240         test_mkdir -c1 -p $DIR/$tdir
3241         touch $DIR/$tdir/s
3242         touch $DIR/$tdir/exist
3243         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3244         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3245         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3246         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3247         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3248         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3249         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3250         return 0
3251 }
3252 run_test 31k "link to file: the same, non-existing, dir==============="
3253
3254 test_31m() {
3255         mkdir $DIR/d31m
3256         touch $DIR/d31m/s
3257         mkdir $DIR/d31m2
3258         touch $DIR/d31m2/exist
3259         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3260         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3261         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3262         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3263         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3264         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3265         return 0
3266 }
3267 run_test 31m "link to file: the same, non-existing, dir==============="
3268
3269 test_31n() {
3270         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3271         nlink=$(stat --format=%h $DIR/$tfile)
3272         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3273         local fd=$(free_fd)
3274         local cmd="exec $fd<$DIR/$tfile"
3275         eval $cmd
3276         cmd="exec $fd<&-"
3277         trap "eval $cmd" EXIT
3278         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3279         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3280         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3281         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3282         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3283         eval $cmd
3284 }
3285 run_test 31n "check link count of unlinked file"
3286
3287 link_one() {
3288         local tempfile=$(mktemp $1_XXXXXX)
3289         mlink $tempfile $1 2> /dev/null &&
3290                 echo "$BASHPID: link $tempfile to $1 succeeded"
3291         munlink $tempfile
3292 }
3293
3294 test_31o() { # LU-2901
3295         test_mkdir $DIR/$tdir
3296         for LOOP in $(seq 100); do
3297                 rm -f $DIR/$tdir/$tfile*
3298                 for THREAD in $(seq 8); do
3299                         link_one $DIR/$tdir/$tfile.$LOOP &
3300                 done
3301                 wait
3302                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3303                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3304                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3305                         break || true
3306         done
3307 }
3308 run_test 31o "duplicate hard links with same filename"
3309
3310 test_31p() {
3311         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3312
3313         test_mkdir $DIR/$tdir
3314         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3315         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3316
3317         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3318                 error "open unlink test1 failed"
3319         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3320                 error "open unlink test2 failed"
3321
3322         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3323                 error "test1 still exists"
3324         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3325                 error "test2 still exists"
3326 }
3327 run_test 31p "remove of open striped directory"
3328
3329 cleanup_test32_mount() {
3330         local rc=0
3331         trap 0
3332         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3333         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3334         losetup -d $loopdev || true
3335         rm -rf $DIR/$tdir
3336         return $rc
3337 }
3338
3339 test_32a() {
3340         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3341
3342         echo "== more mountpoints and symlinks ================="
3343         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3344         trap cleanup_test32_mount EXIT
3345         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3346         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3347                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3348         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3349                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3350         cleanup_test32_mount
3351 }
3352 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3353
3354 test_32b() {
3355         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3356
3357         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3358         trap cleanup_test32_mount EXIT
3359         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3360         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3361                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3362         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3363                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3364         cleanup_test32_mount
3365 }
3366 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3367
3368 test_32c() {
3369         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3370
3371         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3372         trap cleanup_test32_mount EXIT
3373         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3374         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3375                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3376         test_mkdir -p $DIR/$tdir/d2/test_dir
3377         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3378                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3379         cleanup_test32_mount
3380 }
3381 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3382
3383 test_32d() {
3384         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3385
3386         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3387         trap cleanup_test32_mount EXIT
3388         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3389         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3390                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3391         test_mkdir -p $DIR/$tdir/d2/test_dir
3392         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3393                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3394         cleanup_test32_mount
3395 }
3396 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3397
3398 test_32e() {
3399         rm -fr $DIR/$tdir
3400         test_mkdir -p $DIR/$tdir/tmp
3401         local tmp_dir=$DIR/$tdir/tmp
3402         ln -s $DIR/$tdir $tmp_dir/symlink11
3403         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3404         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3405         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3406 }
3407 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3408
3409 test_32f() {
3410         rm -fr $DIR/$tdir
3411         test_mkdir -p $DIR/$tdir/tmp
3412         local tmp_dir=$DIR/$tdir/tmp
3413         ln -s $DIR/$tdir $tmp_dir/symlink11
3414         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3415         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3416         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3417 }
3418 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3419
3420 test_32g() {
3421         local tmp_dir=$DIR/$tdir/tmp
3422         test_mkdir -p $tmp_dir
3423         test_mkdir $DIR/${tdir}2
3424         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3425         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3426         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3427         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3428         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3429         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3430 }
3431 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3432
3433 test_32h() {
3434         rm -fr $DIR/$tdir $DIR/${tdir}2
3435         tmp_dir=$DIR/$tdir/tmp
3436         test_mkdir -p $tmp_dir
3437         test_mkdir $DIR/${tdir}2
3438         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3439         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3440         ls $tmp_dir/symlink12 || error "listing symlink12"
3441         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3442 }
3443 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3444
3445 test_32i() {
3446         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3447
3448         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3449         trap cleanup_test32_mount EXIT
3450         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3451         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3452                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3453         touch $DIR/$tdir/test_file
3454         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3455                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3456         cleanup_test32_mount
3457 }
3458 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3459
3460 test_32j() {
3461         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3462
3463         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3464         trap cleanup_test32_mount EXIT
3465         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3466         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3467                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3468         touch $DIR/$tdir/test_file
3469         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3470                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3471         cleanup_test32_mount
3472 }
3473 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3474
3475 test_32k() {
3476         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3477
3478         rm -fr $DIR/$tdir
3479         trap cleanup_test32_mount EXIT
3480         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3481         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3482                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3483         test_mkdir -p $DIR/$tdir/d2
3484         touch $DIR/$tdir/d2/test_file || error "touch failed"
3485         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3486                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3487         cleanup_test32_mount
3488 }
3489 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3490
3491 test_32l() {
3492         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3493
3494         rm -fr $DIR/$tdir
3495         trap cleanup_test32_mount EXIT
3496         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3497         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3498                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3499         test_mkdir -p $DIR/$tdir/d2
3500         touch $DIR/$tdir/d2/test_file || error "touch failed"
3501         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3502                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3503         cleanup_test32_mount
3504 }
3505 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3506
3507 test_32m() {
3508         rm -fr $DIR/d32m
3509         test_mkdir -p $DIR/d32m/tmp
3510         TMP_DIR=$DIR/d32m/tmp
3511         ln -s $DIR $TMP_DIR/symlink11
3512         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3513         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3514                 error "symlink11 not a link"
3515         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3516                 error "symlink01 not a link"
3517 }
3518 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3519
3520 test_32n() {
3521         rm -fr $DIR/d32n
3522         test_mkdir -p $DIR/d32n/tmp
3523         TMP_DIR=$DIR/d32n/tmp
3524         ln -s $DIR $TMP_DIR/symlink11
3525         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3526         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3527         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3528 }
3529 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3530
3531 test_32o() {
3532         touch $DIR/$tfile
3533         test_mkdir -p $DIR/d32o/tmp
3534         TMP_DIR=$DIR/d32o/tmp
3535         ln -s $DIR/$tfile $TMP_DIR/symlink12
3536         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3537         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3538                 error "symlink12 not a link"
3539         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3540         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3541                 error "$DIR/d32o/tmp/symlink12 not file type"
3542         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3543                 error "$DIR/d32o/symlink02 not file type"
3544 }
3545 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3546
3547 test_32p() {
3548         log 32p_1
3549         rm -fr $DIR/d32p
3550         log 32p_2
3551         rm -f $DIR/$tfile
3552         log 32p_3
3553         touch $DIR/$tfile
3554         log 32p_4
3555         test_mkdir -p $DIR/d32p/tmp
3556         log 32p_5
3557         TMP_DIR=$DIR/d32p/tmp
3558         log 32p_6
3559         ln -s $DIR/$tfile $TMP_DIR/symlink12
3560         log 32p_7
3561         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3562         log 32p_8
3563         cat $DIR/d32p/tmp/symlink12 ||
3564                 error "Can't open $DIR/d32p/tmp/symlink12"
3565         log 32p_9
3566         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3567         log 32p_10
3568 }
3569 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3570
3571 test_32q() {
3572         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3573
3574         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3575         trap cleanup_test32_mount EXIT
3576         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3577         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3578         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3579                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3580         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3581         cleanup_test32_mount
3582 }
3583 run_test 32q "stat follows mountpoints in Lustre (should return error)"
3584
3585 test_32r() {
3586         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3587
3588         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3589         trap cleanup_test32_mount EXIT
3590         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3591         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3592         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3593                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3594         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
3595         cleanup_test32_mount
3596 }
3597 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
3598
3599 test_33aa() {
3600         rm -f $DIR/$tfile
3601         touch $DIR/$tfile
3602         chmod 444 $DIR/$tfile
3603         chown $RUNAS_ID $DIR/$tfile
3604         log 33_1
3605         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3606         log 33_2
3607 }
3608 run_test 33aa "write file with mode 444 (should return error)"
3609
3610 test_33a() {
3611         rm -fr $DIR/$tdir
3612         test_mkdir $DIR/$tdir
3613         chown $RUNAS_ID $DIR/$tdir
3614         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
3615                 error "$RUNAS create $tdir/$tfile failed"
3616         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
3617                 error "open RDWR" || true
3618 }
3619 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
3620
3621 test_33b() {
3622         rm -fr $DIR/$tdir
3623         test_mkdir $DIR/$tdir
3624         chown $RUNAS_ID $DIR/$tdir
3625         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
3626 }
3627 run_test 33b "test open file with malformed flags (No panic)"
3628
3629 test_33c() {
3630         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3631         remote_ost_nodsh && skip "remote OST with nodsh"
3632
3633         local ostnum
3634         local ostname
3635         local write_bytes
3636         local all_zeros
3637
3638         all_zeros=:
3639         rm -fr $DIR/$tdir
3640         test_mkdir $DIR/$tdir
3641         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
3642
3643         sync
3644         for ostnum in $(seq $OSTCOUNT); do
3645                 # test-framework's OST numbering is one-based, while Lustre's
3646                 # is zero-based
3647                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3648                 # Parsing llobdstat's output sucks; we could grep the /proc
3649                 # path, but that's likely to not be as portable as using the
3650                 # llobdstat utility.  So we parse lctl output instead.
3651                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3652                         obdfilter/$ostname/stats |
3653                         awk '/^write_bytes/ {print $7}' )
3654                 echo "baseline_write_bytes@$OSTnum/$ostname=$write_bytes"
3655                 if (( ${write_bytes:-0} > 0 ))
3656                 then
3657                         all_zeros=false
3658                         break;
3659                 fi
3660         done
3661
3662         $all_zeros || return 0
3663
3664         # Write four bytes
3665         echo foo > $DIR/$tdir/bar
3666         # Really write them
3667         sync
3668
3669         # Total up write_bytes after writing.  We'd better find non-zeros.
3670         for ostnum in $(seq $OSTCOUNT); do
3671                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3672                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3673                         obdfilter/$ostname/stats |
3674                         awk '/^write_bytes/ {print $7}' )
3675                 echo "write_bytes@$OSTnum/$ostname=$write_bytes"
3676                 if (( ${write_bytes:-0} > 0 ))
3677                 then
3678                         all_zeros=false
3679                         break;
3680                 fi
3681         done
3682
3683         if $all_zeros
3684         then
3685                 for ostnum in $(seq $OSTCOUNT); do
3686                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3687                         echo "Check that write_bytes is present in obdfilter/*/stats:"
3688                         do_facet ost$ostnum lctl get_param -n \
3689                                 obdfilter/$ostname/stats
3690                 done
3691                 error "OST not keeping write_bytes stats (b22312)"
3692         fi
3693 }
3694 run_test 33c "test llobdstat and write_bytes"
3695
3696 test_33d() {
3697         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
3698         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3699
3700         local MDTIDX=1
3701         local remote_dir=$DIR/$tdir/remote_dir
3702
3703         test_mkdir $DIR/$tdir
3704         $LFS mkdir -i $MDTIDX $remote_dir ||
3705                 error "create remote directory failed"
3706
3707         touch $remote_dir/$tfile
3708         chmod 444 $remote_dir/$tfile
3709         chown $RUNAS_ID $remote_dir/$tfile
3710
3711         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3712
3713         chown $RUNAS_ID $remote_dir
3714         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
3715                                         error "create" || true
3716         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
3717                                     error "open RDWR" || true
3718         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
3719 }
3720 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
3721
3722 test_33e() {
3723         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3724
3725         mkdir $DIR/$tdir
3726
3727         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3728         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3729         mkdir $DIR/$tdir/local_dir
3730
3731         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3732         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3733         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3734
3735         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3736                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
3737
3738         rmdir $DIR/$tdir/* || error "rmdir failed"
3739
3740         umask 777
3741         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3742         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3743         mkdir $DIR/$tdir/local_dir
3744
3745         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3746         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3747         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3748
3749         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3750                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
3751
3752         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
3753
3754         umask 000
3755         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3756         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3757         mkdir $DIR/$tdir/local_dir
3758
3759         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3760         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3761         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3762
3763         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3764                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
3765 }
3766 run_test 33e "mkdir and striped directory should have same mode"
3767
3768 cleanup_33f() {
3769         trap 0
3770         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
3771 }
3772
3773 test_33f() {
3774         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3775         remote_mds_nodsh && skip "remote MDS with nodsh"
3776
3777         mkdir $DIR/$tdir
3778         chmod go+rwx $DIR/$tdir
3779         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
3780         trap cleanup_33f EXIT
3781
3782         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
3783                 error "cannot create striped directory"
3784
3785         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
3786                 error "cannot create files in striped directory"
3787
3788         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
3789                 error "cannot remove files in striped directory"
3790
3791         $RUNAS rmdir $DIR/$tdir/striped_dir ||
3792                 error "cannot remove striped directory"
3793
3794         cleanup_33f
3795 }
3796 run_test 33f "nonroot user can create, access, and remove a striped directory"
3797
3798 test_33g() {
3799         mkdir -p $DIR/$tdir/dir2
3800
3801         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
3802         echo $err
3803         [[ $err =~ "exists" ]] || error "Not exists error"
3804 }
3805 run_test 33g "nonroot user create already existing root created file"
3806
3807 test_33h() {
3808         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3809         [ $MDS1_VERSION -lt $(version_code 2.13.50) ] &&
3810                 skip "Need MDS version at least 2.13.50"
3811
3812         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir ||
3813                 error "mkdir $tdir failed"
3814         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
3815
3816         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
3817         local index2
3818
3819         for fname in $DIR/$tdir/$tfile.bak \
3820                      $DIR/$tdir/$tfile.SAV \
3821                      $DIR/$tdir/$tfile.orig \
3822                      $DIR/$tdir/$tfile~; do
3823                 touch $fname  || error "touch $fname failed"
3824                 index2=$($LFS getstripe -m $fname)
3825                 [ $index -eq $index2 ] ||
3826                         error "$fname MDT index mismatch $index != $index2"
3827         done
3828
3829         local failed=0
3830         for i in {1..50}; do
3831                 for fname in $(mktemp -u $DIR/$tdir/.$tfile.XXXXXX) \
3832                              $(mktemp $DIR/$tdir/$tfile.XXXXXXXX); do
3833                         touch $fname  || error "touch $fname failed"
3834                         index2=$($LFS getstripe -m $fname)
3835                         if [[ $index != $index2 ]]; then
3836                                 failed=$((failed + 1))
3837                                 echo "$fname MDT index mismatch $index != $index2"
3838                         fi
3839                 done
3840         done
3841         echo "$failed MDT index mismatches"
3842         (( failed < 4 )) || error "MDT index mismatch $failed times"
3843
3844 }
3845 run_test 33h "temp file is located on the same MDT as target"
3846
3847 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
3848 test_34a() {
3849         rm -f $DIR/f34
3850         $MCREATE $DIR/f34 || error "mcreate failed"
3851         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3852                 error "getstripe failed"
3853         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
3854         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3855                 error "getstripe failed"
3856         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3857                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3858 }
3859 run_test 34a "truncate file that has not been opened ==========="
3860
3861 test_34b() {
3862         [ ! -f $DIR/f34 ] && test_34a
3863         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3864                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3865         $OPENFILE -f O_RDONLY $DIR/f34
3866         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3867                 error "getstripe failed"
3868         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3869                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3870 }
3871 run_test 34b "O_RDONLY opening file doesn't create objects ====="
3872
3873 test_34c() {
3874         [ ! -f $DIR/f34 ] && test_34a
3875         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3876                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3877         $OPENFILE -f O_RDWR $DIR/f34
3878         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
3879                 error "$LFS getstripe failed"
3880         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3881                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3882 }
3883 run_test 34c "O_RDWR opening file-with-size works =============="
3884
3885 test_34d() {
3886         [ ! -f $DIR/f34 ] && test_34a
3887         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
3888                 error "dd failed"
3889         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3890                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3891         rm $DIR/f34
3892 }
3893 run_test 34d "write to sparse file ============================="
3894
3895 test_34e() {
3896         rm -f $DIR/f34e
3897         $MCREATE $DIR/f34e || error "mcreate failed"
3898         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
3899         $CHECKSTAT -s 1000 $DIR/f34e ||
3900                 error "Size of $DIR/f34e not equal to 1000 bytes"
3901         $OPENFILE -f O_RDWR $DIR/f34e
3902         $CHECKSTAT -s 1000 $DIR/f34e ||
3903                 error "Size of $DIR/f34e not equal to 1000 bytes"
3904 }
3905 run_test 34e "create objects, some with size and some without =="
3906
3907 test_34f() { # bug 6242, 6243
3908         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3909
3910         SIZE34F=48000
3911         rm -f $DIR/f34f
3912         $MCREATE $DIR/f34f || error "mcreate failed"
3913         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
3914         dd if=$DIR/f34f of=$TMP/f34f
3915         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
3916         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
3917         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
3918         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
3919         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
3920 }
3921 run_test 34f "read from a file with no objects until EOF ======="
3922
3923 test_34g() {
3924         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3925
3926         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
3927                 error "dd failed"
3928         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
3929         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3930                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
3931         cancel_lru_locks osc
3932         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3933                 error "wrong size after lock cancel"
3934
3935         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
3936         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3937                 error "expanding truncate failed"
3938         cancel_lru_locks osc
3939         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3940                 error "wrong expanded size after lock cancel"
3941 }
3942 run_test 34g "truncate long file ==============================="
3943
3944 test_34h() {
3945         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3946
3947         local gid=10
3948         local sz=1000
3949
3950         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
3951         sync # Flush the cache so that multiop below does not block on cache
3952              # flush when getting the group lock
3953         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
3954         MULTIPID=$!
3955
3956         # Since just timed wait is not good enough, let's do a sync write
3957         # that way we are sure enough time for a roundtrip + processing
3958         # passed + 2 seconds of extra margin.
3959         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
3960         rm $DIR/${tfile}-1
3961         sleep 2
3962
3963         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
3964                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
3965                 kill -9 $MULTIPID
3966         fi
3967         wait $MULTIPID
3968         local nsz=`stat -c %s $DIR/$tfile`
3969         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
3970 }
3971 run_test 34h "ftruncate file under grouplock should not block"
3972
3973 test_35a() {
3974         cp /bin/sh $DIR/f35a
3975         chmod 444 $DIR/f35a
3976         chown $RUNAS_ID $DIR/f35a
3977         $RUNAS $DIR/f35a && error || true
3978         rm $DIR/f35a
3979 }
3980 run_test 35a "exec file with mode 444 (should return and not leak)"
3981
3982 test_36a() {
3983         rm -f $DIR/f36
3984         utime $DIR/f36 || error "utime failed for MDS"
3985 }
3986 run_test 36a "MDS utime check (mknod, utime)"
3987
3988 test_36b() {
3989         echo "" > $DIR/f36
3990         utime $DIR/f36 || error "utime failed for OST"
3991 }
3992 run_test 36b "OST utime check (open, utime)"
3993
3994 test_36c() {
3995         rm -f $DIR/d36/f36
3996         test_mkdir $DIR/d36
3997         chown $RUNAS_ID $DIR/d36
3998         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
3999 }
4000 run_test 36c "non-root MDS utime check (mknod, utime)"
4001
4002 test_36d() {
4003         [ ! -d $DIR/d36 ] && test_36c
4004         echo "" > $DIR/d36/f36
4005         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4006 }
4007 run_test 36d "non-root OST utime check (open, utime)"
4008
4009 test_36e() {
4010         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4011
4012         test_mkdir $DIR/$tdir
4013         touch $DIR/$tdir/$tfile
4014         $RUNAS utime $DIR/$tdir/$tfile &&
4015                 error "utime worked, expected failure" || true
4016 }
4017 run_test 36e "utime on non-owned file (should return error)"
4018
4019 subr_36fh() {
4020         local fl="$1"
4021         local LANG_SAVE=$LANG
4022         local LC_LANG_SAVE=$LC_LANG
4023         export LANG=C LC_LANG=C # for date language
4024
4025         DATESTR="Dec 20  2000"
4026         test_mkdir $DIR/$tdir
4027         lctl set_param fail_loc=$fl
4028         date; date +%s
4029         cp /etc/hosts $DIR/$tdir/$tfile
4030         sync & # write RPC generated with "current" inode timestamp, but delayed
4031         sleep 1
4032         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4033         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4034         cancel_lru_locks $OSC
4035         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4036         date; date +%s
4037         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4038                 echo "BEFORE: $LS_BEFORE" && \
4039                 echo "AFTER : $LS_AFTER" && \
4040                 echo "WANT  : $DATESTR" && \
4041                 error "$DIR/$tdir/$tfile timestamps changed" || true
4042
4043         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4044 }
4045
4046 test_36f() {
4047         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4048
4049         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4050         subr_36fh "0x80000214"
4051 }
4052 run_test 36f "utime on file racing with OST BRW write =========="
4053
4054 test_36g() {
4055         remote_ost_nodsh && skip "remote OST with nodsh"
4056         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4057         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4058                 skip "Need MDS version at least 2.12.51"
4059
4060         local fmd_max_age
4061         local fmd
4062         local facet="ost1"
4063         local tgt="obdfilter"
4064
4065         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4066
4067         test_mkdir $DIR/$tdir
4068         fmd_max_age=$(do_facet $facet \
4069                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4070                 head -n 1")
4071
4072         echo "FMD max age: ${fmd_max_age}s"
4073         touch $DIR/$tdir/$tfile
4074         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4075                 gawk '{cnt=cnt+$1}  END{print cnt}')
4076         echo "FMD before: $fmd"
4077         [[ $fmd == 0 ]] &&
4078                 error "FMD wasn't create by touch"
4079         sleep $((fmd_max_age + 12))
4080         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4081                 gawk '{cnt=cnt+$1}  END{print cnt}')
4082         echo "FMD after: $fmd"
4083         [[ $fmd == 0 ]] ||
4084                 error "FMD wasn't expired by ping"
4085 }
4086 run_test 36g "FMD cache expiry ====================="
4087
4088 test_36h() {
4089         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4090
4091         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4092         subr_36fh "0x80000227"
4093 }
4094 run_test 36h "utime on file racing with OST BRW write =========="
4095
4096 test_36i() {
4097         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4098
4099         test_mkdir $DIR/$tdir
4100         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4101
4102         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4103         local new_mtime=$((mtime + 200))
4104
4105         #change Modify time of striped dir
4106         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4107                         error "change mtime failed"
4108
4109         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4110
4111         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4112 }
4113 run_test 36i "change mtime on striped directory"
4114
4115 # test_37 - duplicate with tests 32q 32r
4116
4117 test_38() {
4118         local file=$DIR/$tfile
4119         touch $file
4120         openfile -f O_DIRECTORY $file
4121         local RC=$?
4122         local ENOTDIR=20
4123         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4124         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4125 }
4126 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4127
4128 test_39a() { # was test_39
4129         touch $DIR/$tfile
4130         touch $DIR/${tfile}2
4131 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4132 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4133 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4134         sleep 2
4135         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4136         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4137                 echo "mtime"
4138                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4139                 echo "atime"
4140                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4141                 echo "ctime"
4142                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4143                 error "O_TRUNC didn't change timestamps"
4144         fi
4145 }
4146 run_test 39a "mtime changed on create"
4147
4148 test_39b() {
4149         test_mkdir -c1 $DIR/$tdir
4150         cp -p /etc/passwd $DIR/$tdir/fopen
4151         cp -p /etc/passwd $DIR/$tdir/flink
4152         cp -p /etc/passwd $DIR/$tdir/funlink
4153         cp -p /etc/passwd $DIR/$tdir/frename
4154         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4155
4156         sleep 1
4157         echo "aaaaaa" >> $DIR/$tdir/fopen
4158         echo "aaaaaa" >> $DIR/$tdir/flink
4159         echo "aaaaaa" >> $DIR/$tdir/funlink
4160         echo "aaaaaa" >> $DIR/$tdir/frename
4161
4162         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4163         local link_new=`stat -c %Y $DIR/$tdir/flink`
4164         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4165         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4166
4167         cat $DIR/$tdir/fopen > /dev/null
4168         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4169         rm -f $DIR/$tdir/funlink2
4170         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4171
4172         for (( i=0; i < 2; i++ )) ; do
4173                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4174                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4175                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4176                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4177
4178                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4179                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4180                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4181                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4182
4183                 cancel_lru_locks $OSC
4184                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4185         done
4186 }
4187 run_test 39b "mtime change on open, link, unlink, rename  ======"
4188
4189 # this should be set to past
4190 TEST_39_MTIME=`date -d "1 year ago" +%s`
4191
4192 # bug 11063
4193 test_39c() {
4194         touch $DIR1/$tfile
4195         sleep 2
4196         local mtime0=`stat -c %Y $DIR1/$tfile`
4197
4198         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4199         local mtime1=`stat -c %Y $DIR1/$tfile`
4200         [ "$mtime1" = $TEST_39_MTIME ] || \
4201                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4202
4203         local d1=`date +%s`
4204         echo hello >> $DIR1/$tfile
4205         local d2=`date +%s`
4206         local mtime2=`stat -c %Y $DIR1/$tfile`
4207         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4208                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4209
4210         mv $DIR1/$tfile $DIR1/$tfile-1
4211
4212         for (( i=0; i < 2; i++ )) ; do
4213                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4214                 [ "$mtime2" = "$mtime3" ] || \
4215                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4216
4217                 cancel_lru_locks $OSC
4218                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4219         done
4220 }
4221 run_test 39c "mtime change on rename ==========================="
4222
4223 # bug 21114
4224 test_39d() {
4225         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4226
4227         touch $DIR1/$tfile
4228         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4229
4230         for (( i=0; i < 2; i++ )) ; do
4231                 local mtime=`stat -c %Y $DIR1/$tfile`
4232                 [ $mtime = $TEST_39_MTIME ] || \
4233                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4234
4235                 cancel_lru_locks $OSC
4236                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4237         done
4238 }
4239 run_test 39d "create, utime, stat =============================="
4240
4241 # bug 21114
4242 test_39e() {
4243         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4244
4245         touch $DIR1/$tfile
4246         local mtime1=`stat -c %Y $DIR1/$tfile`
4247
4248         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4249
4250         for (( i=0; i < 2; i++ )) ; do
4251                 local mtime2=`stat -c %Y $DIR1/$tfile`
4252                 [ $mtime2 = $TEST_39_MTIME ] || \
4253                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4254
4255                 cancel_lru_locks $OSC
4256                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4257         done
4258 }
4259 run_test 39e "create, stat, utime, stat ========================"
4260
4261 # bug 21114
4262 test_39f() {
4263         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4264
4265         touch $DIR1/$tfile
4266         mtime1=`stat -c %Y $DIR1/$tfile`
4267
4268         sleep 2
4269         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4270
4271         for (( i=0; i < 2; i++ )) ; do
4272                 local mtime2=`stat -c %Y $DIR1/$tfile`
4273                 [ $mtime2 = $TEST_39_MTIME ] || \
4274                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4275
4276                 cancel_lru_locks $OSC
4277                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4278         done
4279 }
4280 run_test 39f "create, stat, sleep, utime, stat ================="
4281
4282 # bug 11063
4283 test_39g() {
4284         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4285
4286         echo hello >> $DIR1/$tfile
4287         local mtime1=`stat -c %Y $DIR1/$tfile`
4288
4289         sleep 2
4290         chmod o+r $DIR1/$tfile
4291
4292         for (( i=0; i < 2; i++ )) ; do
4293                 local mtime2=`stat -c %Y $DIR1/$tfile`
4294                 [ "$mtime1" = "$mtime2" ] || \
4295                         error "lost mtime: $mtime2, should be $mtime1"
4296
4297                 cancel_lru_locks $OSC
4298                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4299         done
4300 }
4301 run_test 39g "write, chmod, stat ==============================="
4302
4303 # bug 11063
4304 test_39h() {
4305         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4306
4307         touch $DIR1/$tfile
4308         sleep 1
4309
4310         local d1=`date`
4311         echo hello >> $DIR1/$tfile
4312         local mtime1=`stat -c %Y $DIR1/$tfile`
4313
4314         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4315         local d2=`date`
4316         if [ "$d1" != "$d2" ]; then
4317                 echo "write and touch not within one second"
4318         else
4319                 for (( i=0; i < 2; i++ )) ; do
4320                         local mtime2=`stat -c %Y $DIR1/$tfile`
4321                         [ "$mtime2" = $TEST_39_MTIME ] || \
4322                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4323
4324                         cancel_lru_locks $OSC
4325                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4326                 done
4327         fi
4328 }
4329 run_test 39h "write, utime within one second, stat ============="
4330
4331 test_39i() {
4332         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4333
4334         touch $DIR1/$tfile
4335         sleep 1
4336
4337         echo hello >> $DIR1/$tfile
4338         local mtime1=`stat -c %Y $DIR1/$tfile`
4339
4340         mv $DIR1/$tfile $DIR1/$tfile-1
4341
4342         for (( i=0; i < 2; i++ )) ; do
4343                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4344
4345                 [ "$mtime1" = "$mtime2" ] || \
4346                         error "lost mtime: $mtime2, should be $mtime1"
4347
4348                 cancel_lru_locks $OSC
4349                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4350         done
4351 }
4352 run_test 39i "write, rename, stat =============================="
4353
4354 test_39j() {
4355         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4356
4357         start_full_debug_logging
4358         touch $DIR1/$tfile
4359         sleep 1
4360
4361         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4362         lctl set_param fail_loc=0x80000412
4363         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4364                 error "multiop failed"
4365         local multipid=$!
4366         local mtime1=`stat -c %Y $DIR1/$tfile`
4367
4368         mv $DIR1/$tfile $DIR1/$tfile-1
4369
4370         kill -USR1 $multipid
4371         wait $multipid || error "multiop close failed"
4372
4373         for (( i=0; i < 2; i++ )) ; do
4374                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4375                 [ "$mtime1" = "$mtime2" ] ||
4376                         error "mtime is lost on close: $mtime2, " \
4377                               "should be $mtime1"
4378
4379                 cancel_lru_locks
4380                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4381         done
4382         lctl set_param fail_loc=0
4383         stop_full_debug_logging
4384 }
4385 run_test 39j "write, rename, close, stat ======================="
4386
4387 test_39k() {
4388         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4389
4390         touch $DIR1/$tfile
4391         sleep 1
4392
4393         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4394         local multipid=$!
4395         local mtime1=`stat -c %Y $DIR1/$tfile`
4396
4397         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4398
4399         kill -USR1 $multipid
4400         wait $multipid || error "multiop close failed"
4401
4402         for (( i=0; i < 2; i++ )) ; do
4403                 local mtime2=`stat -c %Y $DIR1/$tfile`
4404
4405                 [ "$mtime2" = $TEST_39_MTIME ] || \
4406                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4407
4408                 cancel_lru_locks
4409                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4410         done
4411 }
4412 run_test 39k "write, utime, close, stat ========================"
4413
4414 # this should be set to future
4415 TEST_39_ATIME=`date -d "1 year" +%s`
4416
4417 test_39l() {
4418         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4419         remote_mds_nodsh && skip "remote MDS with nodsh"
4420
4421         local atime_diff=$(do_facet $SINGLEMDS \
4422                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4423         rm -rf $DIR/$tdir
4424         mkdir -p $DIR/$tdir
4425
4426         # test setting directory atime to future
4427         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4428         local atime=$(stat -c %X $DIR/$tdir)
4429         [ "$atime" = $TEST_39_ATIME ] ||
4430                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4431
4432         # test setting directory atime from future to now
4433         local now=$(date +%s)
4434         touch -a -d @$now $DIR/$tdir
4435
4436         atime=$(stat -c %X $DIR/$tdir)
4437         [ "$atime" -eq "$now"  ] ||
4438                 error "atime is not updated from future: $atime, $now"
4439
4440         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4441         sleep 3
4442
4443         # test setting directory atime when now > dir atime + atime_diff
4444         local d1=$(date +%s)
4445         ls $DIR/$tdir
4446         local d2=$(date +%s)
4447         cancel_lru_locks mdc
4448         atime=$(stat -c %X $DIR/$tdir)
4449         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4450                 error "atime is not updated  : $atime, should be $d2"
4451
4452         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4453         sleep 3
4454
4455         # test not setting directory atime when now < dir atime + atime_diff
4456         ls $DIR/$tdir
4457         cancel_lru_locks mdc
4458         atime=$(stat -c %X $DIR/$tdir)
4459         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4460                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4461
4462         do_facet $SINGLEMDS \
4463                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4464 }
4465 run_test 39l "directory atime update ==========================="
4466
4467 test_39m() {
4468         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4469
4470         touch $DIR1/$tfile
4471         sleep 2
4472         local far_past_mtime=$(date -d "May 29 1953" +%s)
4473         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4474
4475         touch -m -d @$far_past_mtime $DIR1/$tfile
4476         touch -a -d @$far_past_atime $DIR1/$tfile
4477
4478         for (( i=0; i < 2; i++ )) ; do
4479                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4480                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4481                         error "atime or mtime set incorrectly"
4482
4483                 cancel_lru_locks $OSC
4484                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4485         done
4486 }
4487 run_test 39m "test atime and mtime before 1970"
4488
4489 test_39n() { # LU-3832
4490         remote_mds_nodsh && skip "remote MDS with nodsh"
4491
4492         local atime_diff=$(do_facet $SINGLEMDS \
4493                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4494         local atime0
4495         local atime1
4496         local atime2
4497
4498         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4499
4500         rm -rf $DIR/$tfile
4501         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4502         atime0=$(stat -c %X $DIR/$tfile)
4503
4504         sleep 5
4505         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4506         atime1=$(stat -c %X $DIR/$tfile)
4507
4508         sleep 5
4509         cancel_lru_locks mdc
4510         cancel_lru_locks osc
4511         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4512         atime2=$(stat -c %X $DIR/$tfile)
4513
4514         do_facet $SINGLEMDS \
4515                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4516
4517         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4518         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4519 }
4520 run_test 39n "check that O_NOATIME is honored"
4521
4522 test_39o() {
4523         TESTDIR=$DIR/$tdir/$tfile
4524         [ -e $TESTDIR ] && rm -rf $TESTDIR
4525         mkdir -p $TESTDIR
4526         cd $TESTDIR
4527         links1=2
4528         ls
4529         mkdir a b
4530         ls
4531         links2=$(stat -c %h .)
4532         [ $(($links1 + 2)) != $links2 ] &&
4533                 error "wrong links count $(($links1 + 2)) != $links2"
4534         rmdir b
4535         links3=$(stat -c %h .)
4536         [ $(($links1 + 1)) != $links3 ] &&
4537                 error "wrong links count $links1 != $links3"
4538         return 0
4539 }
4540 run_test 39o "directory cached attributes updated after create"
4541
4542 test_39p() {
4543         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4544
4545         local MDTIDX=1
4546         TESTDIR=$DIR/$tdir/$tdir
4547         [ -e $TESTDIR ] && rm -rf $TESTDIR
4548         test_mkdir -p $TESTDIR
4549         cd $TESTDIR
4550         links1=2
4551         ls
4552         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4553         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4554         ls
4555         links2=$(stat -c %h .)
4556         [ $(($links1 + 2)) != $links2 ] &&
4557                 error "wrong links count $(($links1 + 2)) != $links2"
4558         rmdir remote_dir2
4559         links3=$(stat -c %h .)
4560         [ $(($links1 + 1)) != $links3 ] &&
4561                 error "wrong links count $links1 != $links3"
4562         return 0
4563 }
4564 run_test 39p "remote directory cached attributes updated after create ========"
4565
4566 test_39r() {
4567         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
4568                 skip "no atime update on old OST"
4569         if [ "$ost1_FSTYPE" != ldiskfs ]; then
4570                 skip_env "ldiskfs only test"
4571         fi
4572
4573         local saved_adiff
4574         saved_adiff=$(do_facet ost1 \
4575                 lctl get_param -n obdfilter.*OST0000.atime_diff)
4576         stack_trap "do_facet ost1 \
4577                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
4578
4579         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
4580
4581         $LFS setstripe -i 0 $DIR/$tfile
4582         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
4583                 error "can't write initial file"
4584         cancel_lru_locks osc
4585
4586         # exceed atime_diff and access file
4587         sleep 6
4588         dd if=$DIR/$tfile of=/dev/null || error "can't udpate atime"
4589
4590         local atime_cli=$(stat -c %X $DIR/$tfile)
4591         echo "client atime: $atime_cli"
4592         # allow atime update to be written to device
4593         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
4594         sleep 5
4595
4596         local ostdev=$(ostdevname 1)
4597         local fid=($(lfs getstripe -y $DIR/$tfile |
4598                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
4599         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
4600         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
4601
4602         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
4603         local atime_ost=$(do_facet ost1 "$cmd" |&
4604                           awk -F'[: ]' '/atime:/ { print $4 }')
4605         (( atime_cli == atime_ost )) ||
4606                 error "atime on client $atime_cli != ost $atime_ost"
4607 }
4608 run_test 39r "lazy atime update on OST"
4609
4610 test_39q() { # LU-8041
4611         local testdir=$DIR/$tdir
4612         mkdir -p $testdir
4613         multiop_bg_pause $testdir D_c || error "multiop failed"
4614         local multipid=$!
4615         cancel_lru_locks mdc
4616         kill -USR1 $multipid
4617         local atime=$(stat -c %X $testdir)
4618         [ "$atime" -ne 0 ] || error "atime is zero"
4619 }
4620 run_test 39q "close won't zero out atime"
4621
4622 test_40() {
4623         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
4624         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
4625                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
4626         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
4627                 error "$tfile is not 4096 bytes in size"
4628 }
4629 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
4630
4631 test_41() {
4632         # bug 1553
4633         small_write $DIR/f41 18
4634 }
4635 run_test 41 "test small file write + fstat ====================="
4636
4637 count_ost_writes() {
4638         lctl get_param -n ${OSC}.*.stats |
4639                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
4640                         END { printf("%0.0f", writes) }'
4641 }
4642
4643 # decent default
4644 WRITEBACK_SAVE=500
4645 DIRTY_RATIO_SAVE=40
4646 MAX_DIRTY_RATIO=50
4647 BG_DIRTY_RATIO_SAVE=10
4648 MAX_BG_DIRTY_RATIO=25
4649
4650 start_writeback() {
4651         trap 0
4652         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
4653         # dirty_ratio, dirty_background_ratio
4654         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4655                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
4656                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
4657                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
4658         else
4659                 # if file not here, we are a 2.4 kernel
4660                 kill -CONT `pidof kupdated`
4661         fi
4662 }
4663
4664 stop_writeback() {
4665         # setup the trap first, so someone cannot exit the test at the
4666         # exact wrong time and mess up a machine
4667         trap start_writeback EXIT
4668         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
4669         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4670                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
4671                 sysctl -w vm.dirty_writeback_centisecs=0
4672                 sysctl -w vm.dirty_writeback_centisecs=0
4673                 # save and increase /proc/sys/vm/dirty_ratio
4674                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
4675                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
4676                 # save and increase /proc/sys/vm/dirty_background_ratio
4677                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
4678                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
4679         else
4680                 # if file not here, we are a 2.4 kernel
4681                 kill -STOP `pidof kupdated`
4682         fi
4683 }
4684
4685 # ensure that all stripes have some grant before we test client-side cache
4686 setup_test42() {
4687         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
4688                 dd if=/dev/zero of=$i bs=4k count=1
4689                 rm $i
4690         done
4691 }
4692
4693 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
4694 # file truncation, and file removal.
4695 test_42a() {
4696         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4697
4698         setup_test42
4699         cancel_lru_locks $OSC
4700         stop_writeback
4701         sync; sleep 1; sync # just to be safe
4702         BEFOREWRITES=`count_ost_writes`
4703         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
4704         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
4705         AFTERWRITES=`count_ost_writes`
4706         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
4707                 error "$BEFOREWRITES < $AFTERWRITES"
4708         start_writeback
4709 }
4710 run_test 42a "ensure that we don't flush on close"
4711
4712 test_42b() {
4713         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4714
4715         setup_test42
4716         cancel_lru_locks $OSC
4717         stop_writeback
4718         sync
4719         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
4720         BEFOREWRITES=$(count_ost_writes)
4721         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
4722         AFTERWRITES=$(count_ost_writes)
4723         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4724                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
4725         fi
4726         BEFOREWRITES=$(count_ost_writes)
4727         sync || error "sync: $?"
4728         AFTERWRITES=$(count_ost_writes)
4729         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4730                 error "$BEFOREWRITES < $AFTERWRITES on sync"
4731         fi
4732         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
4733         start_writeback
4734         return 0
4735 }
4736 run_test 42b "test destroy of file with cached dirty data ======"
4737
4738 # if these tests just want to test the effect of truncation,
4739 # they have to be very careful.  consider:
4740 # - the first open gets a {0,EOF}PR lock
4741 # - the first write conflicts and gets a {0, count-1}PW
4742 # - the rest of the writes are under {count,EOF}PW
4743 # - the open for truncate tries to match a {0,EOF}PR
4744 #   for the filesize and cancels the PWs.
4745 # any number of fixes (don't get {0,EOF} on open, match
4746 # composite locks, do smarter file size management) fix
4747 # this, but for now we want these tests to verify that
4748 # the cancellation with truncate intent works, so we
4749 # start the file with a full-file pw lock to match against
4750 # until the truncate.
4751 trunc_test() {
4752         test=$1
4753         file=$DIR/$test
4754         offset=$2
4755         cancel_lru_locks $OSC
4756         stop_writeback
4757         # prime the file with 0,EOF PW to match
4758         touch $file
4759         $TRUNCATE $file 0
4760         sync; sync
4761         # now the real test..
4762         dd if=/dev/zero of=$file bs=1024 count=100
4763         BEFOREWRITES=`count_ost_writes`
4764         $TRUNCATE $file $offset
4765         cancel_lru_locks $OSC
4766         AFTERWRITES=`count_ost_writes`
4767         start_writeback
4768 }
4769
4770 test_42c() {
4771         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4772
4773         trunc_test 42c 1024
4774         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
4775                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
4776         rm $file
4777 }
4778 run_test 42c "test partial truncate of file with cached dirty data"
4779
4780 test_42d() {
4781         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4782
4783         trunc_test 42d 0
4784         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
4785                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
4786         rm $file
4787 }
4788 run_test 42d "test complete truncate of file with cached dirty data"
4789
4790 test_42e() { # bug22074
4791         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4792
4793         local TDIR=$DIR/${tdir}e
4794         local pages=16 # hardcoded 16 pages, don't change it.
4795         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
4796         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
4797         local max_dirty_mb
4798         local warmup_files
4799
4800         test_mkdir $DIR/${tdir}e
4801         $LFS setstripe -c 1 $TDIR
4802         createmany -o $TDIR/f $files
4803
4804         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
4805
4806         # we assume that with $OSTCOUNT files, at least one of them will
4807         # be allocated on OST0.
4808         warmup_files=$((OSTCOUNT * max_dirty_mb))
4809         createmany -o $TDIR/w $warmup_files
4810
4811         # write a large amount of data into one file and sync, to get good
4812         # avail_grant number from OST.
4813         for ((i=0; i<$warmup_files; i++)); do
4814                 idx=$($LFS getstripe -i $TDIR/w$i)
4815                 [ $idx -ne 0 ] && continue
4816                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
4817                 break
4818         done
4819         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
4820         sync
4821         $LCTL get_param $proc_osc0/cur_dirty_bytes
4822         $LCTL get_param $proc_osc0/cur_grant_bytes
4823
4824         # create as much dirty pages as we can while not to trigger the actual
4825         # RPCs directly. but depends on the env, VFS may trigger flush during this
4826         # period, hopefully we are good.
4827         for ((i=0; i<$warmup_files; i++)); do
4828                 idx=$($LFS getstripe -i $TDIR/w$i)
4829                 [ $idx -ne 0 ] && continue
4830                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
4831         done
4832         $LCTL get_param $proc_osc0/cur_dirty_bytes
4833         $LCTL get_param $proc_osc0/cur_grant_bytes
4834
4835         # perform the real test
4836         $LCTL set_param $proc_osc0/rpc_stats 0
4837         for ((;i<$files; i++)); do
4838                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
4839                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
4840         done
4841         sync
4842         $LCTL get_param $proc_osc0/rpc_stats
4843
4844         local percent=0
4845         local have_ppr=false
4846         $LCTL get_param $proc_osc0/rpc_stats |
4847                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
4848                         # skip lines until we are at the RPC histogram data
4849                         [ "$PPR" == "pages" ] && have_ppr=true && continue
4850                         $have_ppr || continue
4851
4852                         # we only want the percent stat for < 16 pages
4853                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
4854
4855                         percent=$((percent + WPCT))
4856                         if [[ $percent -gt 15 ]]; then
4857                                 error "less than 16-pages write RPCs" \
4858                                       "$percent% > 15%"
4859                                 break
4860                         fi
4861                 done
4862         rm -rf $TDIR
4863 }
4864 run_test 42e "verify sub-RPC writes are not done synchronously"
4865
4866 test_43A() { # was test_43
4867         test_mkdir $DIR/$tdir
4868         cp -p /bin/ls $DIR/$tdir/$tfile
4869         $MULTIOP $DIR/$tdir/$tfile Ow_c &
4870         pid=$!
4871         # give multiop a chance to open
4872         sleep 1
4873
4874         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
4875         kill -USR1 $pid
4876 }
4877 run_test 43A "execution of file opened for write should return -ETXTBSY"
4878
4879 test_43a() {
4880         test_mkdir $DIR/$tdir
4881         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4882         $DIR/$tdir/sleep 60 &
4883         SLEEP_PID=$!
4884         # Make sure exec of $tdir/sleep wins race with truncate
4885         sleep 1
4886         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
4887         kill $SLEEP_PID
4888 }
4889 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
4890
4891 test_43b() {
4892         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4893
4894         test_mkdir $DIR/$tdir
4895         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4896         $DIR/$tdir/sleep 60 &
4897         SLEEP_PID=$!
4898         # Make sure exec of $tdir/sleep wins race with truncate
4899         sleep 1
4900         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
4901         kill $SLEEP_PID
4902 }
4903 run_test 43b "truncate of file being executed should return -ETXTBSY"
4904
4905 test_43c() {
4906         local testdir="$DIR/$tdir"
4907         test_mkdir $testdir
4908         cp $SHELL $testdir/
4909         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
4910                 ( cd $testdir && md5sum -c )
4911 }
4912 run_test 43c "md5sum of copy into lustre"
4913
4914 test_44A() { # was test_44
4915         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4916
4917         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
4918         dd if=$DIR/f1 bs=4k count=1 > /dev/null
4919 }
4920 run_test 44A "zero length read from a sparse stripe"
4921
4922 test_44a() {
4923         local nstripe=$($LCTL lov_getconfig $DIR | grep default_stripe_count: |
4924                 awk '{ print $2 }')
4925         [ -z "$nstripe" ] && skip "can't get stripe info"
4926         [[ $nstripe -gt $OSTCOUNT ]] &&
4927                 skip "Wrong default_stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
4928
4929         local stride=$($LCTL lov_getconfig $DIR | grep default_stripe_size: |
4930                 awk '{ print $2 }')
4931         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
4932                 nstripe=$($LCTL lov_getconfig $DIR | grep obd_count: |
4933                         awk '{ print $2 }')
4934         fi
4935
4936         OFFSETS="0 $((stride/2)) $((stride-1))"
4937         for offset in $OFFSETS; do
4938                 for i in $(seq 0 $((nstripe-1))); do
4939                         local GLOBALOFFSETS=""
4940                         # size in Bytes
4941                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
4942                         local myfn=$DIR/d44a-$size
4943                         echo "--------writing $myfn at $size"
4944                         ll_sparseness_write $myfn $size ||
4945                                 error "ll_sparseness_write"
4946                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
4947                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4948                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4949
4950                         for j in $(seq 0 $((nstripe-1))); do
4951                                 # size in Bytes
4952                                 size=$((((j + $nstripe )*$stride + $offset)))
4953                                 ll_sparseness_write $myfn $size ||
4954                                         error "ll_sparseness_write"
4955                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
4956                         done
4957                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4958                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4959                         rm -f $myfn
4960                 done
4961         done
4962 }
4963 run_test 44a "test sparse pwrite ==============================="
4964
4965 dirty_osc_total() {
4966         tot=0
4967         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
4968                 tot=$(($tot + $d))
4969         done
4970         echo $tot
4971 }
4972 do_dirty_record() {
4973         before=`dirty_osc_total`
4974         echo executing "\"$*\""
4975         eval $*
4976         after=`dirty_osc_total`
4977         echo before $before, after $after
4978 }
4979 test_45() {
4980         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4981
4982         f="$DIR/f45"
4983         # Obtain grants from OST if it supports it
4984         echo blah > ${f}_grant
4985         stop_writeback
4986         sync
4987         do_dirty_record "echo blah > $f"
4988         [[ $before -eq $after ]] && error "write wasn't cached"
4989         do_dirty_record "> $f"
4990         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
4991         do_dirty_record "echo blah > $f"
4992         [[ $before -eq $after ]] && error "write wasn't cached"
4993         do_dirty_record "sync"
4994         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
4995         do_dirty_record "echo blah > $f"
4996         [[ $before -eq $after ]] && error "write wasn't cached"
4997         do_dirty_record "cancel_lru_locks osc"
4998         [[ $before -gt $after ]] ||
4999                 error "lock cancellation didn't lower dirty count"
5000         start_writeback
5001 }
5002 run_test 45 "osc io page accounting ============================"
5003
5004 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5005 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5006 # objects offset and an assert hit when an rpc was built with 1023's mapped
5007 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5008 test_46() {
5009         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5010
5011         f="$DIR/f46"
5012         stop_writeback
5013         sync
5014         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5015         sync
5016         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5017         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5018         sync
5019         start_writeback
5020 }
5021 run_test 46 "dirtying a previously written page ================"
5022
5023 # test_47 is removed "Device nodes check" is moved to test_28
5024
5025 test_48a() { # bug 2399
5026         [ "$mds1_FSTYPE" = "zfs" ] &&
5027         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5028                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5029
5030         test_mkdir $DIR/$tdir
5031         cd $DIR/$tdir
5032         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5033         test_mkdir $DIR/$tdir
5034         touch foo || error "'touch foo' failed after recreating cwd"
5035         test_mkdir bar
5036         touch .foo || error "'touch .foo' failed after recreating cwd"
5037         test_mkdir .bar
5038         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5039         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5040         cd . || error "'cd .' failed after recreating cwd"
5041         mkdir . && error "'mkdir .' worked after recreating cwd"
5042         rmdir . && error "'rmdir .' worked after recreating cwd"
5043         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5044         cd .. || error "'cd ..' failed after recreating cwd"
5045 }
5046 run_test 48a "Access renamed working dir (should return errors)="
5047
5048 test_48b() { # bug 2399
5049         rm -rf $DIR/$tdir
5050         test_mkdir $DIR/$tdir
5051         cd $DIR/$tdir
5052         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5053         touch foo && error "'touch foo' worked after removing cwd"
5054         mkdir foo && error "'mkdir foo' worked after removing cwd"
5055         touch .foo && error "'touch .foo' worked after removing cwd"
5056         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5057         ls . > /dev/null && error "'ls .' worked after removing cwd"
5058         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5059         mkdir . && error "'mkdir .' worked after removing cwd"
5060         rmdir . && error "'rmdir .' worked after removing cwd"
5061         ln -s . foo && error "'ln -s .' worked after removing cwd"
5062         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5063 }
5064 run_test 48b "Access removed working dir (should return errors)="
5065
5066 test_48c() { # bug 2350
5067         #lctl set_param debug=-1
5068         #set -vx
5069         rm -rf $DIR/$tdir
5070         test_mkdir -p $DIR/$tdir/dir
5071         cd $DIR/$tdir/dir
5072         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5073         $TRACE touch foo && error "touch foo worked after removing cwd"
5074         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5075         touch .foo && error "touch .foo worked after removing cwd"
5076         mkdir .foo && error "mkdir .foo worked after removing cwd"
5077         $TRACE ls . && error "'ls .' worked after removing cwd"
5078         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5079         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5080         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5081         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5082         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5083 }
5084 run_test 48c "Access removed working subdir (should return errors)"
5085
5086 test_48d() { # bug 2350
5087         #lctl set_param debug=-1
5088         #set -vx
5089         rm -rf $DIR/$tdir
5090         test_mkdir -p $DIR/$tdir/dir
5091         cd $DIR/$tdir/dir
5092         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5093         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5094         $TRACE touch foo && error "'touch foo' worked after removing parent"
5095         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5096         touch .foo && error "'touch .foo' worked after removing parent"
5097         mkdir .foo && error "mkdir .foo worked after removing parent"
5098         $TRACE ls . && error "'ls .' worked after removing parent"
5099         $TRACE ls .. && error "'ls ..' worked after removing parent"
5100         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5101         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5102         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5103         true
5104 }
5105 run_test 48d "Access removed parent subdir (should return errors)"
5106
5107 test_48e() { # bug 4134
5108         #lctl set_param debug=-1
5109         #set -vx
5110         rm -rf $DIR/$tdir
5111         test_mkdir -p $DIR/$tdir/dir
5112         cd $DIR/$tdir/dir
5113         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5114         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5115         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5116         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5117         # On a buggy kernel addition of "touch foo" after cd .. will
5118         # produce kernel oops in lookup_hash_it
5119         touch ../foo && error "'cd ..' worked after recreate parent"
5120         cd $DIR
5121         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5122 }
5123 run_test 48e "Access to recreated parent subdir (should return errors)"
5124
5125 test_49() { # LU-1030
5126         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5127         remote_ost_nodsh && skip "remote OST with nodsh"
5128
5129         # get ost1 size - $FSNAME-OST0000
5130         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5131                 awk '{ print $4 }')
5132         # write 800M at maximum
5133         [[ $ost1_size -lt 2 ]] && ost1_size=2
5134         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5135
5136         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5137         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5138         local dd_pid=$!
5139
5140         # change max_pages_per_rpc while writing the file
5141         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5142         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5143         # loop until dd process exits
5144         while ps ax -opid | grep -wq $dd_pid; do
5145                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5146                 sleep $((RANDOM % 5 + 1))
5147         done
5148         # restore original max_pages_per_rpc
5149         $LCTL set_param $osc1_mppc=$orig_mppc
5150         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5151 }
5152 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5153
5154 test_50() {
5155         # bug 1485
5156         test_mkdir $DIR/$tdir
5157         cd $DIR/$tdir
5158         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5159 }
5160 run_test 50 "special situations: /proc symlinks  ==============="
5161
5162 test_51a() {    # was test_51
5163         # bug 1516 - create an empty entry right after ".." then split dir
5164         test_mkdir -c1 $DIR/$tdir
5165         touch $DIR/$tdir/foo
5166         $MCREATE $DIR/$tdir/bar
5167         rm $DIR/$tdir/foo
5168         createmany -m $DIR/$tdir/longfile 201
5169         FNUM=202
5170         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5171                 $MCREATE $DIR/$tdir/longfile$FNUM
5172                 FNUM=$(($FNUM + 1))
5173                 echo -n "+"
5174         done
5175         echo
5176         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5177 }
5178 run_test 51a "special situations: split htree with empty entry =="
5179
5180 cleanup_print_lfs_df () {
5181         trap 0
5182         $LFS df
5183         $LFS df -i
5184 }
5185
5186 test_51b() {
5187         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5188
5189         local dir=$DIR/$tdir
5190         local nrdirs=$((65536 + 100))
5191
5192         # cleanup the directory
5193         rm -fr $dir
5194
5195         test_mkdir -c1 $dir
5196
5197         $LFS df
5198         $LFS df -i
5199         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5200         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5201         [[ $numfree -lt $nrdirs ]] &&
5202                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5203
5204         # need to check free space for the directories as well
5205         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5206         numfree=$(( blkfree / $(fs_inode_ksize) ))
5207         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5208
5209         trap cleanup_print_lfs_df EXIT
5210
5211         # create files
5212         createmany -d $dir/d $nrdirs || {
5213                 unlinkmany $dir/d $nrdirs
5214                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5215         }
5216
5217         # really created :
5218         nrdirs=$(ls -U $dir | wc -l)
5219
5220         # unlink all but 100 subdirectories, then check it still works
5221         local left=100
5222         local delete=$((nrdirs - left))
5223
5224         $LFS df
5225         $LFS df -i
5226
5227         # for ldiskfs the nlink count should be 1, but this is OSD specific
5228         # and so this is listed for informational purposes only
5229         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5230         unlinkmany -d $dir/d $delete ||
5231                 error "unlink of first $delete subdirs failed"
5232
5233         echo "nlink between: $(stat -c %h $dir)"
5234         local found=$(ls -U $dir | wc -l)
5235         [ $found -ne $left ] &&
5236                 error "can't find subdirs: found only $found, expected $left"
5237
5238         unlinkmany -d $dir/d $delete $left ||
5239                 error "unlink of second $left subdirs failed"
5240         # regardless of whether the backing filesystem tracks nlink accurately
5241         # or not, the nlink count shouldn't be more than "." and ".." here
5242         local after=$(stat -c %h $dir)
5243         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5244                 echo "nlink after: $after"
5245
5246         cleanup_print_lfs_df
5247 }
5248 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5249
5250 test_51d() {
5251         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5252         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5253
5254         test_mkdir $DIR/$tdir
5255         createmany -o $DIR/$tdir/t- 1000
5256         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5257         for N in $(seq 0 $((OSTCOUNT - 1))); do
5258                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
5259                         END { printf("%0.0f", objs) }' $TMP/$tfile)
5260                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5261                         '($1 == '$N') { objs += 1 } \
5262                         END { printf("%0.0f", objs) }')
5263                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
5264         done
5265         unlinkmany $DIR/$tdir/t- 1000
5266
5267         NLAST=0
5268         for N in $(seq 1 $((OSTCOUNT - 1))); do
5269                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
5270                         error "OST $N has less objects vs OST $NLAST" \
5271                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5272                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
5273                         error "OST $N has less objects vs OST $NLAST" \
5274                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5275
5276                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
5277                         error "OST $N has less #0 objects vs OST $NLAST" \
5278                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5279                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
5280                         error "OST $N has less #0 objects vs OST $NLAST" \
5281                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5282                 NLAST=$N
5283         done
5284         rm -f $TMP/$tfile
5285 }
5286 run_test 51d "check object distribution"
5287
5288 test_51e() {
5289         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5290                 skip_env "ldiskfs only test"
5291         fi
5292
5293         test_mkdir -c1 $DIR/$tdir
5294         test_mkdir -c1 $DIR/$tdir/d0
5295
5296         touch $DIR/$tdir/d0/foo
5297         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5298                 error "file exceed 65000 nlink limit!"
5299         unlinkmany $DIR/$tdir/d0/f- 65001
5300         return 0
5301 }
5302 run_test 51e "check file nlink limit"
5303
5304 test_51f() {
5305         test_mkdir $DIR/$tdir
5306
5307         local max=100000
5308         local ulimit_old=$(ulimit -n)
5309         local spare=20 # number of spare fd's for scripts/libraries, etc.
5310         local mdt=$($LFS getstripe -m $DIR/$tdir)
5311         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5312
5313         echo "MDT$mdt numfree=$numfree, max=$max"
5314         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5315         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5316                 while ! ulimit -n $((numfree + spare)); do
5317                         numfree=$((numfree * 3 / 4))
5318                 done
5319                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5320         else
5321                 echo "left ulimit at $ulimit_old"
5322         fi
5323
5324         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5325                 unlinkmany $DIR/$tdir/f $numfree
5326                 error "create+open $numfree files in $DIR/$tdir failed"
5327         }
5328         ulimit -n $ulimit_old
5329
5330         # if createmany exits at 120s there will be fewer than $numfree files
5331         unlinkmany $DIR/$tdir/f $numfree || true
5332 }
5333 run_test 51f "check many open files limit"
5334
5335 test_52a() {
5336         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5337         test_mkdir $DIR/$tdir
5338         touch $DIR/$tdir/foo
5339         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5340         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5341         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5342         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5343         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5344                                         error "link worked"
5345         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5346         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5347         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5348                                                      error "lsattr"
5349         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5350         cp -r $DIR/$tdir $TMP/
5351         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5352 }
5353 run_test 52a "append-only flag test (should return errors)"
5354
5355 test_52b() {
5356         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5357         test_mkdir $DIR/$tdir
5358         touch $DIR/$tdir/foo
5359         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5360         cat test > $DIR/$tdir/foo && error "cat test worked"
5361         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5362         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5363         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5364                                         error "link worked"
5365         echo foo >> $DIR/$tdir/foo && error "echo worked"
5366         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5367         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5368         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5369         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5370                                                         error "lsattr"
5371         chattr -i $DIR/$tdir/foo || error "chattr failed"
5372
5373         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5374 }
5375 run_test 52b "immutable flag test (should return errors) ======="
5376
5377 test_53() {
5378         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5379         remote_mds_nodsh && skip "remote MDS with nodsh"
5380         remote_ost_nodsh && skip "remote OST with nodsh"
5381
5382         local param
5383         local param_seq
5384         local ostname
5385         local mds_last
5386         local mds_last_seq
5387         local ost_last
5388         local ost_last_seq
5389         local ost_last_id
5390         local ostnum
5391         local node
5392         local found=false
5393         local support_last_seq=true
5394
5395         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5396                 support_last_seq=false
5397
5398         # only test MDT0000
5399         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5400         local value
5401         for value in $(do_facet $SINGLEMDS \
5402                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5403                 param=$(echo ${value[0]} | cut -d "=" -f1)
5404                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5405
5406                 if $support_last_seq; then
5407                         param_seq=$(echo $param |
5408                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5409                         mds_last_seq=$(do_facet $SINGLEMDS \
5410                                        $LCTL get_param -n $param_seq)
5411                 fi
5412                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5413
5414                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5415                 node=$(facet_active_host ost$((ostnum+1)))
5416                 param="obdfilter.$ostname.last_id"
5417                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5418                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5419                         ost_last_id=$ost_last
5420
5421                         if $support_last_seq; then
5422                                 ost_last_id=$(echo $ost_last |
5423                                               awk -F':' '{print $2}' |
5424                                               sed -e "s/^0x//g")
5425                                 ost_last_seq=$(echo $ost_last |
5426                                                awk -F':' '{print $1}')
5427                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5428                         fi
5429
5430                         if [[ $ost_last_id != $mds_last ]]; then
5431                                 error "$ost_last_id != $mds_last"
5432                         else
5433                                 found=true
5434                                 break
5435                         fi
5436                 done
5437         done
5438         $found || error "can not match last_seq/last_id for $mdtosc"
5439         return 0
5440 }
5441 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5442
5443 test_54a() {
5444         perl -MSocket -e ';' || skip "no Socket perl module installed"
5445
5446         $SOCKETSERVER $DIR/socket ||
5447                 error "$SOCKETSERVER $DIR/socket failed: $?"
5448         $SOCKETCLIENT $DIR/socket ||
5449                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5450         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5451 }
5452 run_test 54a "unix domain socket test =========================="
5453
5454 test_54b() {
5455         f="$DIR/f54b"
5456         mknod $f c 1 3
5457         chmod 0666 $f
5458         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5459 }
5460 run_test 54b "char device works in lustre ======================"
5461
5462 find_loop_dev() {
5463         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5464         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5465         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5466
5467         for i in $(seq 3 7); do
5468                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5469                 LOOPDEV=$LOOPBASE$i
5470                 LOOPNUM=$i
5471                 break
5472         done
5473 }
5474
5475 cleanup_54c() {
5476         local rc=0
5477         loopdev="$DIR/loop54c"
5478
5479         trap 0
5480         $UMOUNT $DIR/$tdir || rc=$?
5481         losetup -d $loopdev || true
5482         losetup -d $LOOPDEV || true
5483         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5484         return $rc
5485 }
5486
5487 test_54c() {
5488         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5489
5490         loopdev="$DIR/loop54c"
5491
5492         find_loop_dev
5493         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5494         trap cleanup_54c EXIT
5495         mknod $loopdev b 7 $LOOPNUM
5496         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5497         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5498         losetup $loopdev $DIR/$tfile ||
5499                 error "can't set up $loopdev for $DIR/$tfile"
5500         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5501         test_mkdir $DIR/$tdir
5502         mount -t ext2 $loopdev $DIR/$tdir ||
5503                 error "error mounting $loopdev on $DIR/$tdir"
5504         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5505                 error "dd write"
5506         df $DIR/$tdir
5507         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5508                 error "dd read"
5509         cleanup_54c
5510 }
5511 run_test 54c "block device works in lustre ====================="
5512
5513 test_54d() {
5514         f="$DIR/f54d"
5515         string="aaaaaa"
5516         mknod $f p
5517         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5518 }
5519 run_test 54d "fifo device works in lustre ======================"
5520
5521 test_54e() {
5522         f="$DIR/f54e"
5523         string="aaaaaa"
5524         cp -aL /dev/console $f
5525         echo $string > $f || error "echo $string to $f failed"
5526 }
5527 run_test 54e "console/tty device works in lustre ======================"
5528
5529 test_56a() {
5530         local numfiles=3
5531         local dir=$DIR/$tdir
5532
5533         rm -rf $dir
5534         test_mkdir -p $dir/dir
5535         for i in $(seq $numfiles); do
5536                 touch $dir/file$i
5537                 touch $dir/dir/file$i
5538         done
5539
5540         local numcomp=$($LFS getstripe --component-count $dir)
5541
5542         [[ $numcomp == 0 ]] && numcomp=1
5543
5544         # test lfs getstripe with --recursive
5545         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5546
5547         [[ $filenum -eq $((numfiles * 2)) ]] ||
5548                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5549         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5550         [[ $filenum -eq $numfiles ]] ||
5551                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5552         echo "$LFS getstripe showed obdidx or l_ost_idx"
5553
5554         # test lfs getstripe with file instead of dir
5555         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5556         [[ $filenum -eq 1 ]] ||
5557                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5558         echo "$LFS getstripe file1 passed"
5559
5560         #test lfs getstripe with --verbose
5561         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5562         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5563                 error "$LFS getstripe --verbose $dir: "\
5564                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5565         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5566                 error "$LFS getstripe $dir: showed lmm_magic"
5567
5568         #test lfs getstripe with -v prints lmm_fid
5569         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5570         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5571                 error "$LFS getstripe -v $dir: "\
5572                       "got $filenum want $((numfiles * numcomp)) lmm_fid"
5573         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5574                 error "$LFS getstripe $dir: showed lmm_fid by default"
5575         echo "$LFS getstripe --verbose passed"
5576
5577         #check for FID information
5578         local fid1=$($LFS getstripe --fid $dir/file1)
5579         local fid2=$($LFS getstripe --verbose $dir/file1 |
5580                      awk '/lmm_fid: / { print $2; exit; }')
5581         local fid3=$($LFS path2fid $dir/file1)
5582
5583         [ "$fid1" != "$fid2" ] &&
5584                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5585         [ "$fid1" != "$fid3" ] &&
5586                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5587         echo "$LFS getstripe --fid passed"
5588
5589         #test lfs getstripe with --obd
5590         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
5591                 error "$LFS getstripe --obd wrong_uuid: should return error"
5592
5593         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5594
5595         local ostidx=1
5596         local obduuid=$(ostuuid_from_index $ostidx)
5597         local found=$($LFS getstripe -r --obd $obduuid $dir |
5598                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
5599
5600         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
5601         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
5602                 ((filenum--))
5603         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
5604                 ((filenum--))
5605
5606         [[ $found -eq $filenum ]] ||
5607                 error "$LFS getstripe --obd: found $found expect $filenum"
5608         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
5609                 sed '/^[         ]*'${ostidx}'[  ]/d' |
5610                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
5611                 error "$LFS getstripe --obd: should not show file on other obd"
5612         echo "$LFS getstripe --obd passed"
5613 }
5614 run_test 56a "check $LFS getstripe"
5615
5616 test_56b() {
5617         local dir=$DIR/$tdir
5618         local numdirs=3
5619
5620         test_mkdir $dir
5621         for i in $(seq $numdirs); do
5622                 test_mkdir $dir/dir$i
5623         done
5624
5625         # test lfs getdirstripe default mode is non-recursion, which is
5626         # different from lfs getstripe
5627         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
5628
5629         [[ $dircnt -eq 1 ]] ||
5630                 error "$LFS getdirstripe: found $dircnt, not 1"
5631         dircnt=$($LFS getdirstripe --recursive $dir |
5632                 grep -c lmv_stripe_count)
5633         [[ $dircnt -eq $((numdirs + 1)) ]] ||
5634                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
5635 }
5636 run_test 56b "check $LFS getdirstripe"
5637
5638 test_56c() {
5639         remote_ost_nodsh && skip "remote OST with nodsh"
5640
5641         local ost_idx=0
5642         local ost_name=$(ostname_from_index $ost_idx)
5643         local old_status=$(ost_dev_status $ost_idx)
5644         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
5645
5646         [[ -z "$old_status" ]] ||
5647                 skip_env "OST $ost_name is in $old_status status"
5648
5649         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
5650         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
5651                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
5652         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
5653                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
5654                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
5655         fi
5656
5657         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
5658                 error "$LFS df -v showing inactive devices"
5659         sleep_maxage
5660
5661         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
5662
5663         [[ "$new_status" =~ "D" ]] ||
5664                 error "$ost_name status is '$new_status', missing 'D'"
5665         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
5666                 [[ "$new_status" =~ "N" ]] ||
5667                         error "$ost_name status is '$new_status', missing 'N'"
5668         fi
5669         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
5670                 [[ "$new_status" =~ "f" ]] ||
5671                         error "$ost_name status is '$new_status', missing 'f'"
5672         fi
5673
5674         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
5675         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
5676                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
5677         [[ -z "$p" ]] && restore_lustre_params < $p || true
5678         sleep_maxage
5679
5680         new_status=$(ost_dev_status $ost_idx)
5681         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
5682                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
5683         # can't check 'f' as devices may actually be on flash
5684 }
5685 run_test 56c "check 'lfs df' showing device status"
5686
5687 test_56d() {
5688         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
5689         local osts=$($LFS df -v $MOUNT | grep -c OST)
5690
5691         $LFS df $MOUNT
5692
5693         (( mdts == MDSCOUNT )) ||
5694                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
5695         (( osts == OSTCOUNT )) ||
5696                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
5697 }
5698 run_test 56d "'lfs df -v' prints only configured devices"
5699
5700 NUMFILES=3
5701 NUMDIRS=3
5702 setup_56() {
5703         local local_tdir="$1"
5704         local local_numfiles="$2"
5705         local local_numdirs="$3"
5706         local dir_params="$4"
5707         local dir_stripe_params="$5"
5708
5709         if [ ! -d "$local_tdir" ] ; then
5710                 test_mkdir -p $dir_stripe_params $local_tdir
5711                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
5712                 for i in $(seq $local_numfiles) ; do
5713                         touch $local_tdir/file$i
5714                 done
5715                 for i in $(seq $local_numdirs) ; do
5716                         test_mkdir $dir_stripe_params $local_tdir/dir$i
5717                         for j in $(seq $local_numfiles) ; do
5718                                 touch $local_tdir/dir$i/file$j
5719                         done
5720                 done
5721         fi
5722 }
5723
5724 setup_56_special() {
5725         local local_tdir=$1
5726         local local_numfiles=$2
5727         local local_numdirs=$3
5728
5729         setup_56 $local_tdir $local_numfiles $local_numdirs
5730
5731         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
5732                 for i in $(seq $local_numfiles) ; do
5733                         mknod $local_tdir/loop${i}b b 7 $i
5734                         mknod $local_tdir/null${i}c c 1 3
5735                         ln -s $local_tdir/file1 $local_tdir/link${i}
5736                 done
5737                 for i in $(seq $local_numdirs) ; do
5738                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
5739                         mknod $local_tdir/dir$i/null${i}c c 1 3
5740                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
5741                 done
5742         fi
5743 }
5744
5745 test_56g() {
5746         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5747         local expected=$(($NUMDIRS + 2))
5748
5749         setup_56 $dir $NUMFILES $NUMDIRS
5750
5751         # test lfs find with -name
5752         for i in $(seq $NUMFILES) ; do
5753                 local nums=$($LFS find -name "*$i" $dir | wc -l)
5754
5755                 [ $nums -eq $expected ] ||
5756                         error "lfs find -name '*$i' $dir wrong: "\
5757                               "found $nums, expected $expected"
5758         done
5759 }
5760 run_test 56g "check lfs find -name"
5761
5762 test_56h() {
5763         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5764         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
5765
5766         setup_56 $dir $NUMFILES $NUMDIRS
5767
5768         # test lfs find with ! -name
5769         for i in $(seq $NUMFILES) ; do
5770                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
5771
5772                 [ $nums -eq $expected ] ||
5773                         error "lfs find ! -name '*$i' $dir wrong: "\
5774                               "found $nums, expected $expected"
5775         done
5776 }
5777 run_test 56h "check lfs find ! -name"
5778
5779 test_56i() {
5780         local dir=$DIR/$tdir
5781
5782         test_mkdir $dir
5783
5784         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
5785         local out=$($cmd)
5786
5787         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
5788 }
5789 run_test 56i "check 'lfs find -ost UUID' skips directories"
5790
5791 test_56j() {
5792         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5793
5794         setup_56_special $dir $NUMFILES $NUMDIRS
5795
5796         local expected=$((NUMDIRS + 1))
5797         local cmd="$LFS find -type d $dir"
5798         local nums=$($cmd | wc -l)
5799
5800         [ $nums -eq $expected ] ||
5801                 error "'$cmd' wrong: found $nums, expected $expected"
5802 }
5803 run_test 56j "check lfs find -type d"
5804
5805 test_56k() {
5806         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5807
5808         setup_56_special $dir $NUMFILES $NUMDIRS
5809
5810         local expected=$(((NUMDIRS + 1) * NUMFILES))
5811         local cmd="$LFS find -type f $dir"
5812         local nums=$($cmd | wc -l)
5813
5814         [ $nums -eq $expected ] ||
5815                 error "'$cmd' wrong: found $nums, expected $expected"
5816 }
5817 run_test 56k "check lfs find -type f"
5818
5819 test_56l() {
5820         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5821
5822         setup_56_special $dir $NUMFILES $NUMDIRS
5823
5824         local expected=$((NUMDIRS + NUMFILES))
5825         local cmd="$LFS find -type b $dir"
5826         local nums=$($cmd | wc -l)
5827
5828         [ $nums -eq $expected ] ||
5829                 error "'$cmd' wrong: found $nums, expected $expected"
5830 }
5831 run_test 56l "check lfs find -type b"
5832
5833 test_56m() {
5834         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5835
5836         setup_56_special $dir $NUMFILES $NUMDIRS
5837
5838         local expected=$((NUMDIRS + NUMFILES))
5839         local cmd="$LFS find -type c $dir"
5840         local nums=$($cmd | wc -l)
5841         [ $nums -eq $expected ] ||
5842                 error "'$cmd' wrong: found $nums, expected $expected"
5843 }
5844 run_test 56m "check lfs find -type c"
5845
5846 test_56n() {
5847         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5848         setup_56_special $dir $NUMFILES $NUMDIRS
5849
5850         local expected=$((NUMDIRS + NUMFILES))
5851         local cmd="$LFS find -type l $dir"
5852         local nums=$($cmd | wc -l)
5853
5854         [ $nums -eq $expected ] ||
5855                 error "'$cmd' wrong: found $nums, expected $expected"
5856 }
5857 run_test 56n "check lfs find -type l"
5858
5859 test_56o() {
5860         local dir=$DIR/$tdir
5861
5862         setup_56 $dir $NUMFILES $NUMDIRS
5863         utime $dir/file1 > /dev/null || error "utime (1)"
5864         utime $dir/file2 > /dev/null || error "utime (2)"
5865         utime $dir/dir1 > /dev/null || error "utime (3)"
5866         utime $dir/dir2 > /dev/null || error "utime (4)"
5867         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
5868         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
5869
5870         local expected=4
5871         local nums=$($LFS find -mtime +0 $dir | wc -l)
5872
5873         [ $nums -eq $expected ] ||
5874                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
5875
5876         expected=12
5877         cmd="$LFS find -mtime 0 $dir"
5878         nums=$($cmd | wc -l)
5879         [ $nums -eq $expected ] ||
5880                 error "'$cmd' wrong: found $nums, expected $expected"
5881 }
5882 run_test 56o "check lfs find -mtime for old files"
5883
5884 test_56ob() {
5885         local dir=$DIR/$tdir
5886         local expected=1
5887         local count=0
5888
5889         # just to make sure there is something that won't be found
5890         test_mkdir $dir
5891         touch $dir/$tfile.now
5892
5893         for age in year week day hour min; do
5894                 count=$((count + 1))
5895
5896                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
5897                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
5898                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
5899
5900                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
5901                 local nums=$($cmd | wc -l)
5902                 [ $nums -eq $expected ] ||
5903                         error "'$cmd' wrong: found $nums, expected $expected"
5904
5905                 cmd="$LFS find $dir -atime $count${age:0:1}"
5906                 nums=$($cmd | wc -l)
5907                 [ $nums -eq $expected ] ||
5908                         error "'$cmd' wrong: found $nums, expected $expected"
5909         done
5910
5911         sleep 2
5912         cmd="$LFS find $dir -ctime +1s -type f"
5913         nums=$($cmd | wc -l)
5914         (( $nums == $count * 2 + 1)) ||
5915                 error "'$cmd' wrong: found $nums, expected $((expected*2+1))"
5916 }
5917 run_test 56ob "check lfs find -atime -mtime -ctime with units"
5918
5919 test_newerXY_base() {
5920         local x=$1
5921         local y=$2
5922         local dir=$DIR/$tdir
5923         local ref
5924         local negref
5925
5926         if [ $y == "t" ]; then
5927                 if [ $x == "b" ]; then
5928                         ref="\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\""
5929                 else
5930                         ref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
5931                 fi
5932         else
5933                 ref=$DIR/$tfile.newer.$x$y
5934                 touch $ref || error "touch $ref failed"
5935         fi
5936         sleep 2
5937         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
5938         sleep 2
5939         if [ $y == "t" ]; then
5940                 if [ $x == "b" ]; then
5941                         negref="\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\""
5942                 else
5943                         negref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
5944                 fi
5945         else
5946                 negref=$DIR/$tfile.negnewer.$x$y
5947                 touch $negref || error "touch $negref failed"
5948         fi
5949
5950         local cmd="$LFS find $dir -newer$x$y $ref"
5951         local nums=$(eval $cmd | wc -l)
5952         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
5953
5954         [ $nums -eq $expected ] ||
5955                 error "'$cmd' wrong: found $nums, expected $expected"
5956
5957         cmd="$LFS find $dir ! -newer$x$y $negref"
5958         nums=$(eval $cmd | wc -l)
5959         [ $nums -eq $expected ] ||
5960                 error "'$cmd' wrong: found $nums, expected $expected"
5961
5962         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
5963         nums=$(eval $cmd | wc -l)
5964         [ $nums -eq $expected ] ||
5965                 error "'$cmd' wrong: found $nums, expected $expected"
5966
5967         rm -rf $DIR/*
5968 }
5969
5970 test_56oc() {
5971         test_newerXY_base "b" "t"
5972         test_newerXY_base "a" "a"
5973         test_newerXY_base "a" "m"
5974         test_newerXY_base "a" "c"
5975         test_newerXY_base "m" "a"
5976         test_newerXY_base "m" "m"
5977         test_newerXY_base "m" "c"
5978         test_newerXY_base "c" "a"
5979         test_newerXY_base "c" "m"
5980         test_newerXY_base "c" "c"
5981         test_newerXY_base "b" "b"
5982         test_newerXY_base "a" "t"
5983         test_newerXY_base "m" "t"
5984         test_newerXY_base "c" "t"
5985         test_newerXY_base "b" "t"
5986 }
5987 run_test 56oc "check lfs find -newerXY work"
5988
5989 btime_supported() {
5990         local dir=$DIR/$tdir
5991         local rc
5992
5993         mkdir -p $dir
5994         touch $dir/$tfile
5995         $LFS find $dir -btime -1d -type f
5996         rc=$?
5997         rm -rf $dir
5998         return $rc
5999 }
6000
6001 test_56od() {
6002         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6003                 ! btime_supported && skip "btime unsupported on MDS"
6004
6005         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6006                 ! btime_supported && skip "btime unsupported on clients"
6007
6008         local dir=$DIR/$tdir
6009         local ref=$DIR/$tfile.ref
6010         local negref=$DIR/$tfile.negref
6011
6012         mkdir $dir || error "mkdir $dir failed"
6013         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6014         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6015         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6016         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6017         touch $ref || error "touch $ref failed"
6018         # sleep 3 seconds at least
6019         sleep 3
6020
6021         local before=$(do_facet mds1 date +%s)
6022         local skew=$(($(date +%s) - before + 1))
6023
6024         if (( skew < 0 && skew > -5 )); then
6025                 sleep $((0 - skew + 1))
6026                 skew=0
6027         fi
6028
6029         # Set the dir stripe params to limit files all on MDT0,
6030         # otherwise we need to calc the max clock skew between
6031         # the client and MDTs.
6032         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6033         sleep 2
6034         touch $negref || error "touch $negref failed"
6035
6036         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6037         local nums=$($cmd | wc -l)
6038         local expected=$(((NUMFILES + 1) * NUMDIRS))
6039
6040         [ $nums -eq $expected ] ||
6041                 error "'$cmd' wrong: found $nums, expected $expected"
6042
6043         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6044         nums=$($cmd | wc -l)
6045         expected=$((NUMFILES + 1))
6046         [ $nums -eq $expected ] ||
6047                 error "'$cmd' wrong: found $nums, expected $expected"
6048
6049         [ $skew -lt 0 ] && return
6050
6051         local after=$(do_facet mds1 date +%s)
6052         local age=$((after - before + 1 + skew))
6053
6054         cmd="$LFS find $dir -btime -${age}s -type f"
6055         nums=$($cmd | wc -l)
6056         expected=$(((NUMFILES + 1) * NUMDIRS))
6057
6058         echo "Clock skew between client and server: $skew, age:$age"
6059         [ $nums -eq $expected ] ||
6060                 error "'$cmd' wrong: found $nums, expected $expected"
6061
6062         expected=$(($NUMDIRS + 1))
6063         cmd="$LFS find $dir -btime -${age}s -type d"
6064         nums=$($cmd | wc -l)
6065         [ $nums -eq $expected ] ||
6066                 error "'$cmd' wrong: found $nums, expected $expected"
6067         rm -f $ref $negref || error "Failed to remove $ref $negref"
6068 }
6069 run_test 56od "check lfs find -btime with units"
6070
6071 test_56p() {
6072         [ $RUNAS_ID -eq $UID ] &&
6073                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6074
6075         local dir=$DIR/$tdir
6076
6077         setup_56 $dir $NUMFILES $NUMDIRS
6078         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6079
6080         local expected=$NUMFILES
6081         local cmd="$LFS find -uid $RUNAS_ID $dir"
6082         local nums=$($cmd | wc -l)
6083
6084         [ $nums -eq $expected ] ||
6085                 error "'$cmd' wrong: found $nums, expected $expected"
6086
6087         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6088         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6089         nums=$($cmd | wc -l)
6090         [ $nums -eq $expected ] ||
6091                 error "'$cmd' wrong: found $nums, expected $expected"
6092 }
6093 run_test 56p "check lfs find -uid and ! -uid"
6094
6095 test_56q() {
6096         [ $RUNAS_ID -eq $UID ] &&
6097                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6098
6099         local dir=$DIR/$tdir
6100
6101         setup_56 $dir $NUMFILES $NUMDIRS
6102         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6103
6104         local expected=$NUMFILES
6105         local cmd="$LFS find -gid $RUNAS_GID $dir"
6106         local nums=$($cmd | wc -l)
6107
6108         [ $nums -eq $expected ] ||
6109                 error "'$cmd' wrong: found $nums, expected $expected"
6110
6111         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6112         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6113         nums=$($cmd | wc -l)
6114         [ $nums -eq $expected ] ||
6115                 error "'$cmd' wrong: found $nums, expected $expected"
6116 }
6117 run_test 56q "check lfs find -gid and ! -gid"
6118
6119 test_56r() {
6120         local dir=$DIR/$tdir
6121
6122         setup_56 $dir $NUMFILES $NUMDIRS
6123
6124         local expected=12
6125         local cmd="$LFS find -size 0 -type f -lazy $dir"
6126         local nums=$($cmd | wc -l)
6127
6128         [ $nums -eq $expected ] ||
6129                 error "'$cmd' wrong: found $nums, expected $expected"
6130         cmd="$LFS find -size 0 -type f $dir"
6131         nums=$($cmd | wc -l)
6132         [ $nums -eq $expected ] ||
6133                 error "'$cmd' wrong: found $nums, expected $expected"
6134
6135         expected=0
6136         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6137         nums=$($cmd | wc -l)
6138         [ $nums -eq $expected ] ||
6139                 error "'$cmd' wrong: found $nums, expected $expected"
6140         cmd="$LFS find ! -size 0 -type f $dir"
6141         nums=$($cmd | wc -l)
6142         [ $nums -eq $expected ] ||
6143                 error "'$cmd' wrong: found $nums, expected $expected"
6144
6145         echo "test" > $dir/$tfile
6146         echo "test2" > $dir/$tfile.2 && sync
6147         expected=1
6148         cmd="$LFS find -size 5 -type f -lazy $dir"
6149         nums=$($cmd | wc -l)
6150         [ $nums -eq $expected ] ||
6151                 error "'$cmd' wrong: found $nums, expected $expected"
6152         cmd="$LFS find -size 5 -type f $dir"
6153         nums=$($cmd | wc -l)
6154         [ $nums -eq $expected ] ||
6155                 error "'$cmd' wrong: found $nums, expected $expected"
6156
6157         expected=1
6158         cmd="$LFS find -size +5 -type f -lazy $dir"
6159         nums=$($cmd | wc -l)
6160         [ $nums -eq $expected ] ||
6161                 error "'$cmd' wrong: found $nums, expected $expected"
6162         cmd="$LFS find -size +5 -type f $dir"
6163         nums=$($cmd | wc -l)
6164         [ $nums -eq $expected ] ||
6165                 error "'$cmd' wrong: found $nums, expected $expected"
6166
6167         expected=2
6168         cmd="$LFS find -size +0 -type f -lazy $dir"
6169         nums=$($cmd | wc -l)
6170         [ $nums -eq $expected ] ||
6171                 error "'$cmd' wrong: found $nums, expected $expected"
6172         cmd="$LFS find -size +0 -type f $dir"
6173         nums=$($cmd | wc -l)
6174         [ $nums -eq $expected ] ||
6175                 error "'$cmd' wrong: found $nums, expected $expected"
6176
6177         expected=2
6178         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6179         nums=$($cmd | wc -l)
6180         [ $nums -eq $expected ] ||
6181                 error "'$cmd' wrong: found $nums, expected $expected"
6182         cmd="$LFS find ! -size -5 -type f $dir"
6183         nums=$($cmd | wc -l)
6184         [ $nums -eq $expected ] ||
6185                 error "'$cmd' wrong: found $nums, expected $expected"
6186
6187         expected=12
6188         cmd="$LFS find -size -5 -type f -lazy $dir"
6189         nums=$($cmd | wc -l)
6190         [ $nums -eq $expected ] ||
6191                 error "'$cmd' wrong: found $nums, expected $expected"
6192         cmd="$LFS find -size -5 -type f $dir"
6193         nums=$($cmd | wc -l)
6194         [ $nums -eq $expected ] ||
6195                 error "'$cmd' wrong: found $nums, expected $expected"
6196 }
6197 run_test 56r "check lfs find -size works"
6198
6199 test_56ra_sub() {
6200         local expected=$1
6201         local glimpses=$2
6202         local cmd="$3"
6203
6204         cancel_lru_locks $OSC
6205
6206         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6207         local nums=$($cmd | wc -l)
6208
6209         [ $nums -eq $expected ] ||
6210                 error "'$cmd' wrong: found $nums, expected $expected"
6211
6212         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6213
6214         if (( rpcs_before + glimpses != rpcs_after )); then
6215                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6216                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6217
6218                 if [[ $glimpses == 0 ]]; then
6219                         error "'$cmd' should not send glimpse RPCs to OST"
6220                 else
6221                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6222                 fi
6223         fi
6224 }
6225
6226 test_56ra() {
6227         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6228                 skip "MDS < 2.12.58 doesn't return LSOM data"
6229         local dir=$DIR/$tdir
6230
6231         [[ $OSC == "mdc" ]] && skip "DoM files" && return
6232
6233         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6234         # open and close all files to ensure LSOM is updated
6235         cancel_lru_locks $OSC
6236         find $dir -type f | xargs cat > /dev/null
6237
6238         #   expect_found  glimpse_rpcs  command_to_run
6239         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6240         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6241         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6242         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6243
6244         echo "test" > $dir/$tfile
6245         echo "test2" > $dir/$tfile.2 && sync
6246         cancel_lru_locks $OSC
6247         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6248
6249         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6250         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6251         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6252         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6253
6254         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6255         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6256         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6257         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6258         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6259         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6260 }
6261 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6262
6263 test_56rb() {
6264         local dir=$DIR/$tdir
6265         local tmp=$TMP/$tfile.log
6266         local mdt_idx;
6267
6268         test_mkdir -p $dir || error "failed to mkdir $dir"
6269         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6270                 error "failed to setstripe $dir/$tfile"
6271         mdt_idx=$($LFS getdirstripe -i $dir)
6272         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6273
6274         stack_trap "rm -f $tmp" EXIT
6275         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6276         ! grep -q obd_uuid $tmp ||
6277                 error "failed to find --size +100K --ost 0 $dir"
6278         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6279         ! grep -q obd_uuid $tmp ||
6280                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6281 }
6282 run_test 56rb "check lfs find --size --ost/--mdt works"
6283
6284 test_56s() { # LU-611 #LU-9369
6285         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6286
6287         local dir=$DIR/$tdir
6288         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6289
6290         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6291         for i in $(seq $NUMDIRS); do
6292                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6293         done
6294
6295         local expected=$NUMDIRS
6296         local cmd="$LFS find -c $OSTCOUNT $dir"
6297         local nums=$($cmd | wc -l)
6298
6299         [ $nums -eq $expected ] || {
6300                 $LFS getstripe -R $dir
6301                 error "'$cmd' wrong: found $nums, expected $expected"
6302         }
6303
6304         expected=$((NUMDIRS + onestripe))
6305         cmd="$LFS find -stripe-count +0 -type f $dir"
6306         nums=$($cmd | wc -l)
6307         [ $nums -eq $expected ] || {
6308                 $LFS getstripe -R $dir
6309                 error "'$cmd' wrong: found $nums, expected $expected"
6310         }
6311
6312         expected=$onestripe
6313         cmd="$LFS find -stripe-count 1 -type f $dir"
6314         nums=$($cmd | wc -l)
6315         [ $nums -eq $expected ] || {
6316                 $LFS getstripe -R $dir
6317                 error "'$cmd' wrong: found $nums, expected $expected"
6318         }
6319
6320         cmd="$LFS find -stripe-count -2 -type f $dir"
6321         nums=$($cmd | wc -l)
6322         [ $nums -eq $expected ] || {
6323                 $LFS getstripe -R $dir
6324                 error "'$cmd' wrong: found $nums, expected $expected"
6325         }
6326
6327         expected=0
6328         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6329         nums=$($cmd | wc -l)
6330         [ $nums -eq $expected ] || {
6331                 $LFS getstripe -R $dir
6332                 error "'$cmd' wrong: found $nums, expected $expected"
6333         }
6334 }
6335 run_test 56s "check lfs find -stripe-count works"
6336
6337 test_56t() { # LU-611 #LU-9369
6338         local dir=$DIR/$tdir
6339
6340         setup_56 $dir 0 $NUMDIRS
6341         for i in $(seq $NUMDIRS); do
6342                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6343         done
6344
6345         local expected=$NUMDIRS
6346         local cmd="$LFS find -S 8M $dir"
6347         local nums=$($cmd | wc -l)
6348
6349         [ $nums -eq $expected ] || {
6350                 $LFS getstripe -R $dir
6351                 error "'$cmd' wrong: found $nums, expected $expected"
6352         }
6353         rm -rf $dir
6354
6355         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6356
6357         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6358
6359         expected=$(((NUMDIRS + 1) * NUMFILES))
6360         cmd="$LFS find -stripe-size 512k -type f $dir"
6361         nums=$($cmd | wc -l)
6362         [ $nums -eq $expected ] ||
6363                 error "'$cmd' wrong: found $nums, expected $expected"
6364
6365         cmd="$LFS find -stripe-size +320k -type f $dir"
6366         nums=$($cmd | wc -l)
6367         [ $nums -eq $expected ] ||
6368                 error "'$cmd' wrong: found $nums, expected $expected"
6369
6370         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6371         cmd="$LFS find -stripe-size +200k -type f $dir"
6372         nums=$($cmd | wc -l)
6373         [ $nums -eq $expected ] ||
6374                 error "'$cmd' wrong: found $nums, expected $expected"
6375
6376         cmd="$LFS find -stripe-size -640k -type f $dir"
6377         nums=$($cmd | wc -l)
6378         [ $nums -eq $expected ] ||
6379                 error "'$cmd' wrong: found $nums, expected $expected"
6380
6381         expected=4
6382         cmd="$LFS find -stripe-size 256k -type f $dir"
6383         nums=$($cmd | wc -l)
6384         [ $nums -eq $expected ] ||
6385                 error "'$cmd' wrong: found $nums, expected $expected"
6386
6387         cmd="$LFS find -stripe-size -320k -type f $dir"
6388         nums=$($cmd | wc -l)
6389         [ $nums -eq $expected ] ||
6390                 error "'$cmd' wrong: found $nums, expected $expected"
6391
6392         expected=0
6393         cmd="$LFS find -stripe-size 1024k -type f $dir"
6394         nums=$($cmd | wc -l)
6395         [ $nums -eq $expected ] ||
6396                 error "'$cmd' wrong: found $nums, expected $expected"
6397 }
6398 run_test 56t "check lfs find -stripe-size works"
6399
6400 test_56u() { # LU-611
6401         local dir=$DIR/$tdir
6402
6403         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6404
6405         if [[ $OSTCOUNT -gt 1 ]]; then
6406                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6407                 onestripe=4
6408         else
6409                 onestripe=0
6410         fi
6411
6412         local expected=$(((NUMDIRS + 1) * NUMFILES))
6413         local cmd="$LFS find -stripe-index 0 -type f $dir"
6414         local nums=$($cmd | wc -l)
6415
6416         [ $nums -eq $expected ] ||
6417                 error "'$cmd' wrong: found $nums, expected $expected"
6418
6419         expected=$onestripe
6420         cmd="$LFS find -stripe-index 1 -type f $dir"
6421         nums=$($cmd | wc -l)
6422         [ $nums -eq $expected ] ||
6423                 error "'$cmd' wrong: found $nums, expected $expected"
6424
6425         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6426         nums=$($cmd | wc -l)
6427         [ $nums -eq $expected ] ||
6428                 error "'$cmd' wrong: found $nums, expected $expected"
6429
6430         expected=0
6431         # This should produce an error and not return any files
6432         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
6433         nums=$($cmd 2>/dev/null | wc -l)
6434         [ $nums -eq $expected ] ||
6435                 error "'$cmd' wrong: found $nums, expected $expected"
6436
6437         if [[ $OSTCOUNT -gt 1 ]]; then
6438                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
6439                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
6440                 nums=$($cmd | wc -l)
6441                 [ $nums -eq $expected ] ||
6442                         error "'$cmd' wrong: found $nums, expected $expected"
6443         fi
6444 }
6445 run_test 56u "check lfs find -stripe-index works"
6446
6447 test_56v() {
6448         local mdt_idx=0
6449         local dir=$DIR/$tdir
6450
6451         setup_56 $dir $NUMFILES $NUMDIRS
6452
6453         UUID=$(mdtuuid_from_index $mdt_idx $dir)
6454         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
6455
6456         for file in $($LFS find -m $UUID $dir); do
6457                 file_midx=$($LFS getstripe -m $file)
6458                 [ $file_midx -eq $mdt_idx ] ||
6459                         error "lfs find -m $UUID != getstripe -m $file_midx"
6460         done
6461 }
6462 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
6463
6464 test_56w() {
6465         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6466         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6467
6468         local dir=$DIR/$tdir
6469
6470         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
6471
6472         local stripe_size=$($LFS getstripe -S -d $dir) ||
6473                 error "$LFS getstripe -S -d $dir failed"
6474         stripe_size=${stripe_size%% *}
6475
6476         local file_size=$((stripe_size * OSTCOUNT))
6477         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
6478         local required_space=$((file_num * file_size))
6479         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
6480                            head -n1)
6481         [[ $free_space -le $((required_space / 1024)) ]] &&
6482                 skip_env "need $required_space, have $free_space kbytes"
6483
6484         local dd_bs=65536
6485         local dd_count=$((file_size / dd_bs))
6486
6487         # write data into the files
6488         local i
6489         local j
6490         local file
6491
6492         for i in $(seq $NUMFILES); do
6493                 file=$dir/file$i
6494                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6495                         error "write data into $file failed"
6496         done
6497         for i in $(seq $NUMDIRS); do
6498                 for j in $(seq $NUMFILES); do
6499                         file=$dir/dir$i/file$j
6500                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6501                                 error "write data into $file failed"
6502                 done
6503         done
6504
6505         # $LFS_MIGRATE will fail if hard link migration is unsupported
6506         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
6507                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
6508                         error "creating links to $dir/dir1/file1 failed"
6509         fi
6510
6511         local expected=-1
6512
6513         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
6514
6515         # lfs_migrate file
6516         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
6517
6518         echo "$cmd"
6519         eval $cmd || error "$cmd failed"
6520
6521         check_stripe_count $dir/file1 $expected
6522
6523         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
6524         then
6525                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
6526                 # OST 1 if it is on OST 0. This file is small enough to
6527                 # be on only one stripe.
6528                 file=$dir/migr_1_ost
6529                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
6530                         error "write data into $file failed"
6531                 local obdidx=$($LFS getstripe -i $file)
6532                 local oldmd5=$(md5sum $file)
6533                 local newobdidx=0
6534
6535                 [[ $obdidx -eq 0 ]] && newobdidx=1
6536                 cmd="$LFS migrate -i $newobdidx $file"
6537                 echo $cmd
6538                 eval $cmd || error "$cmd failed"
6539
6540                 local realobdix=$($LFS getstripe -i $file)
6541                 local newmd5=$(md5sum $file)
6542
6543                 [[ $newobdidx -ne $realobdix ]] &&
6544                         error "new OST is different (was=$obdidx, "\
6545                               "wanted=$newobdidx, got=$realobdix)"
6546                 [[ "$oldmd5" != "$newmd5" ]] &&
6547                         error "md5sum differ: $oldmd5, $newmd5"
6548         fi
6549
6550         # lfs_migrate dir
6551         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
6552         echo "$cmd"
6553         eval $cmd || error "$cmd failed"
6554
6555         for j in $(seq $NUMFILES); do
6556                 check_stripe_count $dir/dir1/file$j $expected
6557         done
6558
6559         # lfs_migrate works with lfs find
6560         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
6561              $LFS_MIGRATE -y -c $expected"
6562         echo "$cmd"
6563         eval $cmd || error "$cmd failed"
6564
6565         for i in $(seq 2 $NUMFILES); do
6566                 check_stripe_count $dir/file$i $expected
6567         done
6568         for i in $(seq 2 $NUMDIRS); do
6569                 for j in $(seq $NUMFILES); do
6570                 check_stripe_count $dir/dir$i/file$j $expected
6571                 done
6572         done
6573 }
6574 run_test 56w "check lfs_migrate -c stripe_count works"
6575
6576 test_56wb() {
6577         local file1=$DIR/$tdir/file1
6578         local create_pool=false
6579         local initial_pool=$($LFS getstripe -p $DIR)
6580         local pool_list=()
6581         local pool=""
6582
6583         echo -n "Creating test dir..."
6584         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6585         echo "done."
6586
6587         echo -n "Creating test file..."
6588         touch $file1 || error "cannot create file"
6589         echo "done."
6590
6591         echo -n "Detecting existing pools..."
6592         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
6593
6594         if [ ${#pool_list[@]} -gt 0 ]; then
6595                 echo "${pool_list[@]}"
6596                 for thispool in "${pool_list[@]}"; do
6597                         if [[ -z "$initial_pool" ||
6598                               "$initial_pool" != "$thispool" ]]; then
6599                                 pool="$thispool"
6600                                 echo "Using existing pool '$pool'"
6601                                 break
6602                         fi
6603                 done
6604         else
6605                 echo "none detected."
6606         fi
6607         if [ -z "$pool" ]; then
6608                 pool=${POOL:-testpool}
6609                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
6610                 echo -n "Creating pool '$pool'..."
6611                 create_pool=true
6612                 pool_add $pool &> /dev/null ||
6613                         error "pool_add failed"
6614                 echo "done."
6615
6616                 echo -n "Adding target to pool..."
6617                 pool_add_targets $pool 0 0 1 &> /dev/null ||
6618                         error "pool_add_targets failed"
6619                 echo "done."
6620         fi
6621
6622         echo -n "Setting pool using -p option..."
6623         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
6624                 error "migrate failed rc = $?"
6625         echo "done."
6626
6627         echo -n "Verifying test file is in pool after migrating..."
6628         [ "$($LFS getstripe -p $file1)" = $pool ] ||
6629                 error "file was not migrated to pool $pool"
6630         echo "done."
6631
6632         echo -n "Removing test file from pool '$pool'..."
6633         # "lfs migrate $file" won't remove the file from the pool
6634         # until some striping information is changed.
6635         $LFS migrate -c 1 $file1 &> /dev/null ||
6636                 error "cannot remove from pool"
6637         [ "$($LFS getstripe -p $file1)" ] &&
6638                 error "pool still set"
6639         echo "done."
6640
6641         echo -n "Setting pool using --pool option..."
6642         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
6643                 error "migrate failed rc = $?"
6644         echo "done."
6645
6646         # Clean up
6647         rm -f $file1
6648         if $create_pool; then
6649                 destroy_test_pools 2> /dev/null ||
6650                         error "destroy test pools failed"
6651         fi
6652 }
6653 run_test 56wb "check lfs_migrate pool support"
6654
6655 test_56wc() {
6656         local file1="$DIR/$tdir/file1"
6657         local parent_ssize
6658         local parent_scount
6659         local cur_ssize
6660         local cur_scount
6661         local orig_ssize
6662
6663         echo -n "Creating test dir..."
6664         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6665         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
6666                 error "cannot set stripe by '-S 1M -c 1'"
6667         echo "done"
6668
6669         echo -n "Setting initial stripe for test file..."
6670         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
6671                 error "cannot set stripe"
6672         cur_ssize=$($LFS getstripe -S "$file1")
6673         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
6674         echo "done."
6675
6676         # File currently set to -S 512K -c 1
6677
6678         # Ensure -c and -S options are rejected when -R is set
6679         echo -n "Verifying incompatible options are detected..."
6680         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
6681                 error "incompatible -c and -R options not detected"
6682         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
6683                 error "incompatible -S and -R options not detected"
6684         echo "done."
6685
6686         # Ensure unrecognized options are passed through to 'lfs migrate'
6687         echo -n "Verifying -S option is passed through to lfs migrate..."
6688         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
6689                 error "migration failed"
6690         cur_ssize=$($LFS getstripe -S "$file1")
6691         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
6692         echo "done."
6693
6694         # File currently set to -S 1M -c 1
6695
6696         # Ensure long options are supported
6697         echo -n "Verifying long options supported..."
6698         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
6699                 error "long option without argument not supported"
6700         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
6701                 error "long option with argument not supported"
6702         cur_ssize=$($LFS getstripe -S "$file1")
6703         [ $cur_ssize -eq 524288 ] ||
6704                 error "migrate --stripe-size $cur_ssize != 524288"
6705         echo "done."
6706
6707         # File currently set to -S 512K -c 1
6708
6709         if [ "$OSTCOUNT" -gt 1 ]; then
6710                 echo -n "Verifying explicit stripe count can be set..."
6711                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
6712                         error "migrate failed"
6713                 cur_scount=$($LFS getstripe -c "$file1")
6714                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
6715                 echo "done."
6716         fi
6717
6718         # File currently set to -S 512K -c 1 or -S 512K -c 2
6719
6720         # Ensure parent striping is used if -R is set, and no stripe
6721         # count or size is specified
6722         echo -n "Setting stripe for parent directory..."
6723         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6724                 error "cannot set stripe '-S 2M -c 1'"
6725         echo "done."
6726
6727         echo -n "Verifying restripe option uses parent stripe settings..."
6728         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
6729         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
6730         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
6731                 error "migrate failed"
6732         cur_ssize=$($LFS getstripe -S "$file1")
6733         [ $cur_ssize -eq $parent_ssize ] ||
6734                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
6735         cur_scount=$($LFS getstripe -c "$file1")
6736         [ $cur_scount -eq $parent_scount ] ||
6737                 error "migrate -R stripe_count $cur_scount != $parent_scount"
6738         echo "done."
6739
6740         # File currently set to -S 1M -c 1
6741
6742         # Ensure striping is preserved if -R is not set, and no stripe
6743         # count or size is specified
6744         echo -n "Verifying striping size preserved when not specified..."
6745         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
6746         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6747                 error "cannot set stripe on parent directory"
6748         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6749                 error "migrate failed"
6750         cur_ssize=$($LFS getstripe -S "$file1")
6751         [ $cur_ssize -eq $orig_ssize ] ||
6752                 error "migrate by default $cur_ssize != $orig_ssize"
6753         echo "done."
6754
6755         # Ensure file name properly detected when final option has no argument
6756         echo -n "Verifying file name properly detected..."
6757         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6758                 error "file name interpreted as option argument"
6759         echo "done."
6760
6761         # Clean up
6762         rm -f "$file1"
6763 }
6764 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
6765
6766 test_56wd() {
6767         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6768
6769         local file1=$DIR/$tdir/file1
6770
6771         echo -n "Creating test dir..."
6772         test_mkdir $DIR/$tdir || error "cannot create dir"
6773         echo "done."
6774
6775         echo -n "Creating test file..."
6776         touch $file1
6777         echo "done."
6778
6779         # Ensure 'lfs migrate' will fail by using a non-existent option,
6780         # and make sure rsync is not called to recover
6781         echo -n "Make sure --no-rsync option works..."
6782         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
6783                 grep -q 'refusing to fall back to rsync' ||
6784                 error "rsync was called with --no-rsync set"
6785         echo "done."
6786
6787         # Ensure rsync is called without trying 'lfs migrate' first
6788         echo -n "Make sure --rsync option works..."
6789         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
6790                 grep -q 'falling back to rsync' &&
6791                 error "lfs migrate was called with --rsync set"
6792         echo "done."
6793
6794         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
6795         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
6796                 grep -q 'at the same time' ||
6797                 error "--rsync and --no-rsync accepted concurrently"
6798         echo "done."
6799
6800         # Clean up
6801         rm -f $file1
6802 }
6803 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
6804
6805 test_56we() {
6806         local td=$DIR/$tdir
6807         local tf=$td/$tfile
6808
6809         test_mkdir $td || error "cannot create $td"
6810         touch $tf || error "cannot touch $tf"
6811
6812         echo -n "Make sure --non-direct|-D works..."
6813         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
6814                 grep -q "lfs migrate --non-direct" ||
6815                 error "--non-direct option cannot work correctly"
6816         $LFS_MIGRATE -y -D -v $tf 2>&1 |
6817                 grep -q "lfs migrate -D" ||
6818                 error "-D option cannot work correctly"
6819         echo "done."
6820 }
6821 run_test 56we "check lfs_migrate --non-direct|-D support"
6822
6823 test_56x() {
6824         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6825         check_swap_layouts_support
6826
6827         local dir=$DIR/$tdir
6828         local ref1=/etc/passwd
6829         local file1=$dir/file1
6830
6831         test_mkdir $dir || error "creating dir $dir"
6832         $LFS setstripe -c 2 $file1
6833         cp $ref1 $file1
6834         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
6835         stripe=$($LFS getstripe -c $file1)
6836         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6837         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6838
6839         # clean up
6840         rm -f $file1
6841 }
6842 run_test 56x "lfs migration support"
6843
6844 test_56xa() {
6845         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6846         check_swap_layouts_support
6847
6848         local dir=$DIR/$tdir/$testnum
6849
6850         test_mkdir -p $dir
6851
6852         local ref1=/etc/passwd
6853         local file1=$dir/file1
6854
6855         $LFS setstripe -c 2 $file1
6856         cp $ref1 $file1
6857         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
6858
6859         local stripe=$($LFS getstripe -c $file1)
6860
6861         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6862         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6863
6864         # clean up
6865         rm -f $file1
6866 }
6867 run_test 56xa "lfs migration --block support"
6868
6869 check_migrate_links() {
6870         local dir="$1"
6871         local file1="$dir/file1"
6872         local begin="$2"
6873         local count="$3"
6874         local runas="$4"
6875         local total_count=$(($begin + $count - 1))
6876         local symlink_count=10
6877         local uniq_count=10
6878
6879         if [ ! -f "$file1" ]; then
6880                 echo -n "creating initial file..."
6881                 $LFS setstripe -c 1 -S "512k" "$file1" ||
6882                         error "cannot setstripe initial file"
6883                 echo "done"
6884
6885                 echo -n "creating symlinks..."
6886                 for s in $(seq 1 $symlink_count); do
6887                         ln -s "$file1" "$dir/slink$s" ||
6888                                 error "cannot create symlinks"
6889                 done
6890                 echo "done"
6891
6892                 echo -n "creating nonlinked files..."
6893                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
6894                         error "cannot create nonlinked files"
6895                 echo "done"
6896         fi
6897
6898         # create hard links
6899         if [ ! -f "$dir/file$total_count" ]; then
6900                 echo -n "creating hard links $begin:$total_count..."
6901                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
6902                         /dev/null || error "cannot create hard links"
6903                 echo "done"
6904         fi
6905
6906         echo -n "checking number of hard links listed in xattrs..."
6907         local fid=$($LFS getstripe -F "$file1")
6908         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
6909
6910         echo "${#paths[*]}"
6911         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
6912                         skip "hard link list has unexpected size, skipping test"
6913         fi
6914         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
6915                         error "link names should exceed xattrs size"
6916         fi
6917
6918         echo -n "migrating files..."
6919         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
6920         local rc=$?
6921         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
6922         echo "done"
6923
6924         # make sure all links have been properly migrated
6925         echo -n "verifying files..."
6926         fid=$($LFS getstripe -F "$file1") ||
6927                 error "cannot get fid for file $file1"
6928         for i in $(seq 2 $total_count); do
6929                 local fid2=$($LFS getstripe -F $dir/file$i)
6930
6931                 [ "$fid2" == "$fid" ] ||
6932                         error "migrated hard link has mismatched FID"
6933         done
6934
6935         # make sure hard links were properly detected, and migration was
6936         # performed only once for the entire link set; nonlinked files should
6937         # also be migrated
6938         local actual=$(grep -c 'done' <<< "$migrate_out")
6939         local expected=$(($uniq_count + 1))
6940
6941         [ "$actual" -eq  "$expected" ] ||
6942                 error "hard links individually migrated ($actual != $expected)"
6943
6944         # make sure the correct number of hard links are present
6945         local hardlinks=$(stat -c '%h' "$file1")
6946
6947         [ $hardlinks -eq $total_count ] ||
6948                 error "num hard links $hardlinks != $total_count"
6949         echo "done"
6950
6951         return 0
6952 }
6953
6954 test_56xb() {
6955         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
6956                 skip "Need MDS version at least 2.10.55"
6957
6958         local dir="$DIR/$tdir"
6959
6960         test_mkdir "$dir" || error "cannot create dir $dir"
6961
6962         echo "testing lfs migrate mode when all links fit within xattrs"
6963         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
6964
6965         echo "testing rsync mode when all links fit within xattrs"
6966         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
6967
6968         echo "testing lfs migrate mode when all links do not fit within xattrs"
6969         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
6970
6971         echo "testing rsync mode when all links do not fit within xattrs"
6972         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
6973
6974         chown -R $RUNAS_ID $dir
6975         echo "testing non-root lfs migrate mode when not all links are in xattr"
6976         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
6977
6978         # clean up
6979         rm -rf $dir
6980 }
6981 run_test 56xb "lfs migration hard link support"
6982
6983 test_56xc() {
6984         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6985
6986         local dir="$DIR/$tdir"
6987
6988         test_mkdir "$dir" || error "cannot create dir $dir"
6989
6990         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
6991         echo -n "Setting initial stripe for 20MB test file..."
6992         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
6993                 error "cannot setstripe 20MB file"
6994         echo "done"
6995         echo -n "Sizing 20MB test file..."
6996         truncate "$dir/20mb" 20971520 || error "cannot create 20MB test file"
6997         echo "done"
6998         echo -n "Verifying small file autostripe count is 1..."
6999         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7000                 error "cannot migrate 20MB file"
7001         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7002                 error "cannot get stripe for $dir/20mb"
7003         [ $stripe_count -eq 1 ] ||
7004                 error "unexpected stripe count $stripe_count for 20MB file"
7005         rm -f "$dir/20mb"
7006         echo "done"
7007
7008         # Test 2: File is small enough to fit within the available space on
7009         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7010         # have at least an additional 1KB for each desired stripe for test 3
7011         echo -n "Setting stripe for 1GB test file..."
7012         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7013         echo "done"
7014         echo -n "Sizing 1GB test file..."
7015         # File size is 1GB + 3KB
7016         truncate "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7017         echo "done"
7018
7019         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7020         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7021         if (( avail > 524288 * OSTCOUNT )); then
7022                 echo -n "Migrating 1GB file..."
7023                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7024                         error "cannot migrate 1GB file"
7025                 echo "done"
7026                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7027                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7028                         error "cannot getstripe for 1GB file"
7029                 [ $stripe_count -eq 2 ] ||
7030                         error "unexpected stripe count $stripe_count != 2"
7031                 echo "done"
7032         fi
7033
7034         # Test 3: File is too large to fit within the available space on
7035         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7036         if [ $OSTCOUNT -ge 3 ]; then
7037                 # The required available space is calculated as
7038                 # file size (1GB + 3KB) / OST count (3).
7039                 local kb_per_ost=349526
7040
7041                 echo -n "Migrating 1GB file with limit..."
7042                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7043                         error "cannot migrate 1GB file with limit"
7044                 echo "done"
7045
7046                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7047                 echo -n "Verifying 1GB autostripe count with limited space..."
7048                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7049                         error "unexpected stripe count $stripe_count (min 3)"
7050                 echo "done"
7051         fi
7052
7053         # clean up
7054         rm -rf $dir
7055 }
7056 run_test 56xc "lfs migration autostripe"
7057
7058 test_56xd() {
7059         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7060
7061         local dir=$DIR/$tdir
7062         local f_mgrt=$dir/$tfile.mgrt
7063         local f_yaml=$dir/$tfile.yaml
7064         local f_copy=$dir/$tfile.copy
7065         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7066         local layout_copy="-c 2 -S 2M -i 1"
7067         local yamlfile=$dir/yamlfile
7068         local layout_before;
7069         local layout_after;
7070
7071         test_mkdir "$dir" || error "cannot create dir $dir"
7072         $LFS setstripe $layout_yaml $f_yaml ||
7073                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7074         $LFS getstripe --yaml $f_yaml > $yamlfile
7075         $LFS setstripe $layout_copy $f_copy ||
7076                 error "cannot setstripe $f_copy with layout $layout_copy"
7077         touch $f_mgrt
7078         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7079
7080         # 1. test option --yaml
7081         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7082                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7083         layout_before=$(get_layout_param $f_yaml)
7084         layout_after=$(get_layout_param $f_mgrt)
7085         [ "$layout_after" == "$layout_before" ] ||
7086                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7087
7088         # 2. test option --copy
7089         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7090                 error "cannot migrate $f_mgrt with --copy $f_copy"
7091         layout_before=$(get_layout_param $f_copy)
7092         layout_after=$(get_layout_param $f_mgrt)
7093         [ "$layout_after" == "$layout_before" ] ||
7094                 error "lfs_migrate --copy: $layout_after != $layout_before"
7095 }
7096 run_test 56xd "check lfs_migrate --yaml and --copy support"
7097
7098 test_56xe() {
7099         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7100
7101         local dir=$DIR/$tdir
7102         local f_comp=$dir/$tfile
7103         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7104         local layout_before=""
7105         local layout_after=""
7106
7107         test_mkdir "$dir" || error "cannot create dir $dir"
7108         $LFS setstripe $layout $f_comp ||
7109                 error "cannot setstripe $f_comp with layout $layout"
7110         layout_before=$(get_layout_param $f_comp)
7111         dd if=/dev/zero of=$f_comp bs=1M count=4
7112
7113         # 1. migrate a comp layout file by lfs_migrate
7114         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7115         layout_after=$(get_layout_param $f_comp)
7116         [ "$layout_before" == "$layout_after" ] ||
7117                 error "lfs_migrate: $layout_before != $layout_after"
7118
7119         # 2. migrate a comp layout file by lfs migrate
7120         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7121         layout_after=$(get_layout_param $f_comp)
7122         [ "$layout_before" == "$layout_after" ] ||
7123                 error "lfs migrate: $layout_before != $layout_after"
7124 }
7125 run_test 56xe "migrate a composite layout file"
7126
7127 test_56xf() {
7128         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7129
7130         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7131                 skip "Need server version at least 2.13.53"
7132
7133         local dir=$DIR/$tdir
7134         local f_comp=$dir/$tfile
7135         local layout="-E 1M -c1 -E -1 -c2"
7136         local fid_before=""
7137         local fid_after=""
7138
7139         test_mkdir "$dir" || error "cannot create dir $dir"
7140         $LFS setstripe $layout $f_comp ||
7141                 error "cannot setstripe $f_comp with layout $layout"
7142         fid_before=$($LFS getstripe --fid $f_comp)
7143         dd if=/dev/zero of=$f_comp bs=1M count=4
7144
7145         # 1. migrate a comp layout file to a comp layout
7146         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7147         fid_after=$($LFS getstripe --fid $f_comp)
7148         [ "$fid_before" == "$fid_after" ] ||
7149                 error "comp-to-comp migrate: $fid_before != $fid_after"
7150
7151         # 2. migrate a comp layout file to a plain layout
7152         $LFS migrate -c2 $f_comp ||
7153                 error "cannot migrate $f_comp by lfs migrate"
7154         fid_after=$($LFS getstripe --fid $f_comp)
7155         [ "$fid_before" == "$fid_after" ] ||
7156                 error "comp-to-plain migrate: $fid_before != $fid_after"
7157
7158         # 3. migrate a plain layout file to a comp layout
7159         $LFS migrate $layout $f_comp ||
7160                 error "cannot migrate $f_comp by lfs migrate"
7161         fid_after=$($LFS getstripe --fid $f_comp)
7162         [ "$fid_before" == "$fid_after" ] ||
7163                 error "plain-to-comp migrate: $fid_before != $fid_after"
7164 }
7165 run_test 56xf "FID is not lost during migration of a composite layout file"
7166
7167 test_56y() {
7168         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7169                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7170
7171         local res=""
7172         local dir=$DIR/$tdir
7173         local f1=$dir/file1
7174         local f2=$dir/file2
7175
7176         test_mkdir -p $dir || error "creating dir $dir"
7177         touch $f1 || error "creating std file $f1"
7178         $MULTIOP $f2 H2c || error "creating released file $f2"
7179
7180         # a directory can be raid0, so ask only for files
7181         res=$($LFS find $dir -L raid0 -type f | wc -l)
7182         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7183
7184         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7185         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7186
7187         # only files can be released, so no need to force file search
7188         res=$($LFS find $dir -L released)
7189         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7190
7191         res=$($LFS find $dir -type f \! -L released)
7192         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7193 }
7194 run_test 56y "lfs find -L raid0|released"
7195
7196 test_56z() { # LU-4824
7197         # This checks to make sure 'lfs find' continues after errors
7198         # There are two classes of errors that should be caught:
7199         # - If multiple paths are provided, all should be searched even if one
7200         #   errors out
7201         # - If errors are encountered during the search, it should not terminate
7202         #   early
7203         local dir=$DIR/$tdir
7204         local i
7205
7206         test_mkdir $dir
7207         for i in d{0..9}; do
7208                 test_mkdir $dir/$i
7209                 touch $dir/$i/$tfile
7210         done
7211         $LFS find $DIR/non_existent_dir $dir &&
7212                 error "$LFS find did not return an error"
7213         # Make a directory unsearchable. This should NOT be the last entry in
7214         # directory order.  Arbitrarily pick the 6th entry
7215         chmod 700 $($LFS find $dir -type d | sed '6!d')
7216
7217         $RUNAS $LFS find $DIR/non_existent $dir
7218         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7219
7220         # The user should be able to see 10 directories and 9 files
7221         (( count == 19 )) ||
7222                 error "$LFS find found $count != 19 entries after error"
7223 }
7224 run_test 56z "lfs find should continue after an error"
7225
7226 test_56aa() { # LU-5937
7227         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7228
7229         local dir=$DIR/$tdir
7230
7231         mkdir $dir
7232         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7233
7234         createmany -o $dir/striped_dir/${tfile}- 1024
7235         local dirs=$($LFS find --size +8k $dir/)
7236
7237         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7238 }
7239 run_test 56aa "lfs find --size under striped dir"
7240
7241 test_56ab() { # LU-10705
7242         test_mkdir $DIR/$tdir
7243         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7244         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7245         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7246         # Flush writes to ensure valid blocks.  Need to be more thorough for
7247         # ZFS, since blocks are not allocated/returned to client immediately.
7248         sync_all_data
7249         wait_zfs_commit ost1 2
7250         cancel_lru_locks osc
7251         ls -ls $DIR/$tdir
7252
7253         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7254
7255         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7256
7257         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7258         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7259
7260         rm -f $DIR/$tdir/$tfile.[123]
7261 }
7262 run_test 56ab "lfs find --blocks"
7263
7264 test_56ba() {
7265         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
7266                 skip "Need MDS version at least 2.10.50"
7267
7268         # Create composite files with one component
7269         local dir=$DIR/$tdir
7270
7271         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
7272         # Create composite files with three components
7273         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
7274         # Create non-composite files
7275         createmany -o $dir/${tfile}- 10
7276
7277         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
7278
7279         [[ $nfiles == 10 ]] ||
7280                 error "lfs find -E 1M found $nfiles != 10 files"
7281
7282         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
7283         [[ $nfiles == 25 ]] ||
7284                 error "lfs find ! -E 1M found $nfiles != 25 files"
7285
7286         # All files have a component that starts at 0
7287         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
7288         [[ $nfiles == 35 ]] ||
7289                 error "lfs find --component-start 0 - $nfiles != 35 files"
7290
7291         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
7292         [[ $nfiles == 15 ]] ||
7293                 error "lfs find --component-start 2M - $nfiles != 15 files"
7294
7295         # All files created here have a componenet that does not starts at 2M
7296         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
7297         [[ $nfiles == 35 ]] ||
7298                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
7299
7300         # Find files with a specified number of components
7301         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
7302         [[ $nfiles == 15 ]] ||
7303                 error "lfs find --component-count 3 - $nfiles != 15 files"
7304
7305         # Remember non-composite files have a component count of zero
7306         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
7307         [[ $nfiles == 10 ]] ||
7308                 error "lfs find --component-count 0 - $nfiles != 10 files"
7309
7310         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
7311         [[ $nfiles == 20 ]] ||
7312                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
7313
7314         # All files have a flag called "init"
7315         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
7316         [[ $nfiles == 35 ]] ||
7317                 error "lfs find --component-flags init - $nfiles != 35 files"
7318
7319         # Multi-component files will have a component not initialized
7320         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
7321         [[ $nfiles == 15 ]] ||
7322                 error "lfs find !--component-flags init - $nfiles != 15 files"
7323
7324         rm -rf $dir
7325
7326 }
7327 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
7328
7329 test_56ca() {
7330         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
7331                 skip "Need MDS version at least 2.10.57"
7332
7333         local td=$DIR/$tdir
7334         local tf=$td/$tfile
7335         local dir
7336         local nfiles
7337         local cmd
7338         local i
7339         local j
7340
7341         # create mirrored directories and mirrored files
7342         mkdir $td || error "mkdir $td failed"
7343         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
7344         createmany -o $tf- 10 || error "create $tf- failed"
7345
7346         for i in $(seq 2); do
7347                 dir=$td/dir$i
7348                 mkdir $dir || error "mkdir $dir failed"
7349                 $LFS mirror create -N$((3 + i)) $dir ||
7350                         error "create mirrored dir $dir failed"
7351                 createmany -o $dir/$tfile- 10 ||
7352                         error "create $dir/$tfile- failed"
7353         done
7354
7355         # change the states of some mirrored files
7356         echo foo > $tf-6
7357         for i in $(seq 2); do
7358                 dir=$td/dir$i
7359                 for j in $(seq 4 9); do
7360                         echo foo > $dir/$tfile-$j
7361                 done
7362         done
7363
7364         # find mirrored files with specific mirror count
7365         cmd="$LFS find --mirror-count 3 --type f $td"
7366         nfiles=$($cmd | wc -l)
7367         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
7368
7369         cmd="$LFS find ! --mirror-count 3 --type f $td"
7370         nfiles=$($cmd | wc -l)
7371         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
7372
7373         cmd="$LFS find --mirror-count +2 --type f $td"
7374         nfiles=$($cmd | wc -l)
7375         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7376
7377         cmd="$LFS find --mirror-count -6 --type f $td"
7378         nfiles=$($cmd | wc -l)
7379         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7380
7381         # find mirrored files with specific file state
7382         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
7383         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
7384
7385         cmd="$LFS find --mirror-state=ro --type f $td"
7386         nfiles=$($cmd | wc -l)
7387         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
7388
7389         cmd="$LFS find ! --mirror-state=ro --type f $td"
7390         nfiles=$($cmd | wc -l)
7391         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7392
7393         cmd="$LFS find --mirror-state=wp --type f $td"
7394         nfiles=$($cmd | wc -l)
7395         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7396
7397         cmd="$LFS find ! --mirror-state=sp --type f $td"
7398         nfiles=$($cmd | wc -l)
7399         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7400 }
7401 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
7402
7403 test_57a() {
7404         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7405         # note test will not do anything if MDS is not local
7406         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7407                 skip_env "ldiskfs only test"
7408         fi
7409         remote_mds_nodsh && skip "remote MDS with nodsh"
7410
7411         local MNTDEV="osd*.*MDT*.mntdev"
7412         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
7413         [ -z "$DEV" ] && error "can't access $MNTDEV"
7414         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
7415                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
7416                         error "can't access $DEV"
7417                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
7418                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
7419                 rm $TMP/t57a.dump
7420         done
7421 }
7422 run_test 57a "verify MDS filesystem created with large inodes =="
7423
7424 test_57b() {
7425         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7426         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7427                 skip_env "ldiskfs only test"
7428         fi
7429         remote_mds_nodsh && skip "remote MDS with nodsh"
7430
7431         local dir=$DIR/$tdir
7432         local filecount=100
7433         local file1=$dir/f1
7434         local fileN=$dir/f$filecount
7435
7436         rm -rf $dir || error "removing $dir"
7437         test_mkdir -c1 $dir
7438         local mdtidx=$($LFS getstripe -m $dir)
7439         local mdtname=MDT$(printf %04x $mdtidx)
7440         local facet=mds$((mdtidx + 1))
7441
7442         echo "mcreating $filecount files"
7443         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
7444
7445         # verify that files do not have EAs yet
7446         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
7447                 error "$file1 has an EA"
7448         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
7449                 error "$fileN has an EA"
7450
7451         sync
7452         sleep 1
7453         df $dir  #make sure we get new statfs data
7454         local mdsfree=$(do_facet $facet \
7455                         lctl get_param -n osd*.*$mdtname.kbytesfree)
7456         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7457         local file
7458
7459         echo "opening files to create objects/EAs"
7460         for file in $(seq -f $dir/f%g 1 $filecount); do
7461                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
7462                         error "opening $file"
7463         done
7464
7465         # verify that files have EAs now
7466         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
7467         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
7468
7469         sleep 1  #make sure we get new statfs data
7470         df $dir
7471         local mdsfree2=$(do_facet $facet \
7472                          lctl get_param -n osd*.*$mdtname.kbytesfree)
7473         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7474
7475         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
7476                 if [ "$mdsfree" != "$mdsfree2" ]; then
7477                         error "MDC before $mdcfree != after $mdcfree2"
7478                 else
7479                         echo "MDC before $mdcfree != after $mdcfree2"
7480                         echo "unable to confirm if MDS has large inodes"
7481                 fi
7482         fi
7483         rm -rf $dir
7484 }
7485 run_test 57b "default LOV EAs are stored inside large inodes ==="
7486
7487 test_58() {
7488         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7489         [ -z "$(which wiretest 2>/dev/null)" ] &&
7490                         skip_env "could not find wiretest"
7491
7492         wiretest
7493 }
7494 run_test 58 "verify cross-platform wire constants =============="
7495
7496 test_59() {
7497         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7498
7499         echo "touch 130 files"
7500         createmany -o $DIR/f59- 130
7501         echo "rm 130 files"
7502         unlinkmany $DIR/f59- 130
7503         sync
7504         # wait for commitment of removal
7505         wait_delete_completed
7506 }
7507 run_test 59 "verify cancellation of llog records async ========="
7508
7509 TEST60_HEAD="test_60 run $RANDOM"
7510 test_60a() {
7511         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7512         remote_mgs_nodsh && skip "remote MGS with nodsh"
7513         do_facet mgs "! which run-llog.sh &> /dev/null" &&
7514                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
7515                         skip_env "missing subtest run-llog.sh"
7516
7517         log "$TEST60_HEAD - from kernel mode"
7518         do_facet mgs "$LCTL dk > /dev/null"
7519         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
7520         do_facet mgs $LCTL dk > $TMP/$tfile
7521
7522         # LU-6388: test llog_reader
7523         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
7524         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
7525         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
7526                         skip_env "missing llog_reader"
7527         local fstype=$(facet_fstype mgs)
7528         [ $fstype != ldiskfs -a $fstype != zfs ] &&
7529                 skip_env "Only for ldiskfs or zfs type mgs"
7530
7531         local mntpt=$(facet_mntpt mgs)
7532         local mgsdev=$(mgsdevname 1)
7533         local fid_list
7534         local fid
7535         local rec_list
7536         local rec
7537         local rec_type
7538         local obj_file
7539         local path
7540         local seq
7541         local oid
7542         local pass=true
7543
7544         #get fid and record list
7545         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
7546                 tail -n 4))
7547         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
7548                 tail -n 4))
7549         #remount mgs as ldiskfs or zfs type
7550         stop mgs || error "stop mgs failed"
7551         mount_fstype mgs || error "remount mgs failed"
7552         for ((i = 0; i < ${#fid_list[@]}; i++)); do
7553                 fid=${fid_list[i]}
7554                 rec=${rec_list[i]}
7555                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
7556                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
7557                 oid=$((16#$oid))
7558
7559                 case $fstype in
7560                         ldiskfs )
7561                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
7562                         zfs )
7563                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
7564                 esac
7565                 echo "obj_file is $obj_file"
7566                 do_facet mgs $llog_reader $obj_file
7567
7568                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
7569                         awk '{ print $3 }' | sed -e "s/^type=//g")
7570                 if [ $rec_type != $rec ]; then
7571                         echo "FAILED test_60a wrong record type $rec_type," \
7572                               "should be $rec"
7573                         pass=false
7574                         break
7575                 fi
7576
7577                 #check obj path if record type is LLOG_LOGID_MAGIC
7578                 if [ "$rec" == "1064553b" ]; then
7579                         path=$(do_facet mgs $llog_reader $obj_file |
7580                                 grep "path=" | awk '{ print $NF }' |
7581                                 sed -e "s/^path=//g")
7582                         if [ $obj_file != $mntpt/$path ]; then
7583                                 echo "FAILED test_60a wrong obj path" \
7584                                       "$montpt/$path, should be $obj_file"
7585                                 pass=false
7586                                 break
7587                         fi
7588                 fi
7589         done
7590         rm -f $TMP/$tfile
7591         #restart mgs before "error", otherwise it will block the next test
7592         stop mgs || error "stop mgs failed"
7593         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
7594         $pass || error "test failed, see FAILED test_60a messages for specifics"
7595 }
7596 run_test 60a "llog_test run from kernel module and test llog_reader"
7597
7598 test_60b() { # bug 6411
7599         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7600
7601         dmesg > $DIR/$tfile
7602         LLOG_COUNT=$(do_facet mgs dmesg |
7603                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
7604                           /llog_[a-z]*.c:[0-9]/ {
7605                                 if (marker)
7606                                         from_marker++
7607                                 from_begin++
7608                           }
7609                           END {
7610                                 if (marker)
7611                                         print from_marker
7612                                 else
7613                                         print from_begin
7614                           }")
7615
7616         [[ $LLOG_COUNT -gt 120 ]] &&
7617                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
7618 }
7619 run_test 60b "limit repeated messages from CERROR/CWARN"
7620
7621 test_60c() {
7622         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7623
7624         echo "create 5000 files"
7625         createmany -o $DIR/f60c- 5000
7626 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
7627         lctl set_param fail_loc=0x80000137
7628         unlinkmany $DIR/f60c- 5000
7629         lctl set_param fail_loc=0
7630 }
7631 run_test 60c "unlink file when mds full"
7632
7633 test_60d() {
7634         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7635
7636         SAVEPRINTK=$(lctl get_param -n printk)
7637         # verify "lctl mark" is even working"
7638         MESSAGE="test message ID $RANDOM $$"
7639         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7640         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
7641
7642         lctl set_param printk=0 || error "set lnet.printk failed"
7643         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
7644         MESSAGE="new test message ID $RANDOM $$"
7645         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
7646         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7647         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
7648
7649         lctl set_param -n printk="$SAVEPRINTK"
7650 }
7651 run_test 60d "test printk console message masking"
7652
7653 test_60e() {
7654         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7655         remote_mds_nodsh && skip "remote MDS with nodsh"
7656
7657         touch $DIR/$tfile
7658 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
7659         do_facet mds1 lctl set_param fail_loc=0x15b
7660         rm $DIR/$tfile
7661 }
7662 run_test 60e "no space while new llog is being created"
7663
7664 test_60g() {
7665         local pid
7666         local i
7667
7668         test_mkdir -c $MDSCOUNT $DIR/$tdir
7669
7670         (
7671                 local index=0
7672                 while true; do
7673                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
7674                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
7675                                 2>/dev/null
7676                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
7677                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
7678                         index=$((index + 1))
7679                 done
7680         ) &
7681
7682         pid=$!
7683
7684         for i in {0..100}; do
7685                 # define OBD_FAIL_OSD_TXN_START    0x19a
7686                 local index=$((i % MDSCOUNT + 1))
7687
7688                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
7689                         > /dev/null
7690                 usleep 100
7691         done
7692
7693         kill -9 $pid
7694
7695         for i in $(seq $MDSCOUNT); do
7696                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
7697         done
7698
7699         mkdir $DIR/$tdir/new || error "mkdir failed"
7700         rmdir $DIR/$tdir/new || error "rmdir failed"
7701
7702         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
7703                 -t namespace
7704         for i in $(seq $MDSCOUNT); do
7705                 wait_update_facet mds$i "$LCTL get_param -n \
7706                         mdd.$(facet_svc mds$i).lfsck_namespace |
7707                         awk '/^status/ { print \\\$2 }'" "completed"
7708         done
7709
7710         ls -R $DIR/$tdir || error "ls failed"
7711         rm -rf $DIR/$tdir || error "rmdir failed"
7712 }
7713 run_test 60g "transaction abort won't cause MDT hung"
7714
7715 test_60h() {
7716         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
7717                 skip "Need MDS version at least 2.12.52"
7718         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
7719
7720         local f
7721
7722         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
7723         #define OBD_FAIL_MDS_STRIPE_FID          0x189
7724         for fail_loc in 0x80000188 0x80000189; do
7725                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
7726                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
7727                         error "mkdir $dir-$fail_loc failed"
7728                 for i in {0..10}; do
7729                         # create may fail on missing stripe
7730                         echo $i > $DIR/$tdir-$fail_loc/$i
7731                 done
7732                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7733                         error "getdirstripe $tdir-$fail_loc failed"
7734                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
7735                         error "migrate $tdir-$fail_loc failed"
7736                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7737                         error "getdirstripe $tdir-$fail_loc failed"
7738                 pushd $DIR/$tdir-$fail_loc
7739                 for f in *; do
7740                         echo $f | cmp $f - || error "$f data mismatch"
7741                 done
7742                 popd
7743                 rm -rf $DIR/$tdir-$fail_loc
7744         done
7745 }
7746 run_test 60h "striped directory with missing stripes can be accessed"
7747
7748 test_61a() {
7749         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7750
7751         f="$DIR/f61"
7752         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
7753         cancel_lru_locks osc
7754         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
7755         sync
7756 }
7757 run_test 61a "mmap() writes don't make sync hang ================"
7758
7759 test_61b() {
7760         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
7761 }
7762 run_test 61b "mmap() of unstriped file is successful"
7763
7764 # bug 2330 - insufficient obd_match error checking causes LBUG
7765 test_62() {
7766         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7767
7768         f="$DIR/f62"
7769         echo foo > $f
7770         cancel_lru_locks osc
7771         lctl set_param fail_loc=0x405
7772         cat $f && error "cat succeeded, expect -EIO"
7773         lctl set_param fail_loc=0
7774 }
7775 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
7776 # match every page all of the time.
7777 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
7778
7779 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
7780 # Though this test is irrelevant anymore, it helped to reveal some
7781 # other grant bugs (LU-4482), let's keep it.
7782 test_63a() {   # was test_63
7783         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7784
7785         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
7786
7787         for i in `seq 10` ; do
7788                 dd if=/dev/zero of=$DIR/f63 bs=8k &
7789                 sleep 5
7790                 kill $!
7791                 sleep 1
7792         done
7793
7794         rm -f $DIR/f63 || true
7795 }
7796 run_test 63a "Verify oig_wait interruption does not crash ======="
7797
7798 # bug 2248 - async write errors didn't return to application on sync
7799 # bug 3677 - async write errors left page locked
7800 test_63b() {
7801         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7802
7803         debugsave
7804         lctl set_param debug=-1
7805
7806         # ensure we have a grant to do async writes
7807         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
7808         rm $DIR/$tfile
7809
7810         sync    # sync lest earlier test intercept the fail_loc
7811
7812         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
7813         lctl set_param fail_loc=0x80000406
7814         $MULTIOP $DIR/$tfile Owy && \
7815                 error "sync didn't return ENOMEM"
7816         sync; sleep 2; sync     # do a real sync this time to flush page
7817         lctl get_param -n llite.*.dump_page_cache | grep locked && \
7818                 error "locked page left in cache after async error" || true
7819         debugrestore
7820 }
7821 run_test 63b "async write errors should be returned to fsync ==="
7822
7823 test_64a () {
7824         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7825
7826         lfs df $DIR
7827         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
7828 }
7829 run_test 64a "verify filter grant calculations (in kernel) ====="
7830
7831 test_64b () {
7832         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7833
7834         sh oos.sh $MOUNT || error "oos.sh failed: $?"
7835 }
7836 run_test 64b "check out-of-space detection on client"
7837
7838 test_64c() {
7839         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
7840 }
7841 run_test 64c "verify grant shrink"
7842
7843 import_param() {
7844         local tgt=$1
7845         local param=$2
7846
7847         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
7848 }
7849
7850 # this does exactly what osc_request.c:osc_announce_cached() does in
7851 # order to calculate max amount of grants to ask from server
7852 want_grant() {
7853         local tgt=$1
7854
7855         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
7856         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
7857
7858         ((rpc_in_flight++));
7859         nrpages=$((nrpages * rpc_in_flight))
7860
7861         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
7862
7863         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
7864
7865         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
7866         local undirty=$((nrpages * PAGE_SIZE))
7867
7868         local max_extent_pages
7869         max_extent_pages=$(import_param $tgt grant_max_extent_size)
7870         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
7871         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
7872         local grant_extent_tax
7873         grant_extent_tax=$(import_param $tgt grant_extent_tax)
7874
7875         undirty=$((undirty + nrextents * grant_extent_tax))
7876
7877         echo $undirty
7878 }
7879
7880 # this is size of unit for grant allocation. It should be equal to
7881 # what tgt_grant.c:tgt_grant_chunk() calculates
7882 grant_chunk() {
7883         local tgt=$1
7884         local max_brw_size
7885         local grant_extent_tax
7886
7887         max_brw_size=$(import_param $tgt max_brw_size)
7888
7889         grant_extent_tax=$(import_param $tgt grant_extent_tax)
7890
7891         echo $(((max_brw_size + grant_extent_tax) * 2))
7892 }
7893
7894 test_64d() {
7895         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
7896                 skip "OST < 2.10.55 doesn't limit grants enough"
7897
7898         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
7899
7900         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
7901                 skip "no grant_param connect flag"
7902
7903         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
7904
7905         $LCTL set_param -n -n debug="$OLDDEBUG" || true
7906         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
7907
7908
7909         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
7910         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
7911
7912         $LFS setstripe $DIR/$tfile -i 0 -c 1
7913         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
7914         ddpid=$!
7915
7916         while kill -0 $ddpid; do
7917                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
7918
7919                 if [[ $cur_grant -gt $max_cur_granted ]]; then
7920                         kill $ddpid
7921                         error "cur_grant $cur_grant > $max_cur_granted"
7922                 fi
7923
7924                 sleep 1
7925         done
7926 }
7927 run_test 64d "check grant limit exceed"
7928
7929 check_grants() {
7930         local tgt=$1
7931         local expected=$2
7932         local msg=$3
7933         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
7934
7935         ((cur_grants == expected)) ||
7936                 error "$msg: grants mismatch: $cur_grants, expected $expected"
7937 }
7938
7939 round_up_p2() {
7940         echo $((($1 + $2 - 1) & ~($2 - 1)))
7941 }
7942
7943 test_64e() {
7944         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7945         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
7946                 skip "Need OSS version at least 2.11.56"
7947
7948         # Remount client to reset grant
7949         remount_client $MOUNT || error "failed to remount client"
7950         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
7951
7952         local init_grants=$(import_param $osc_tgt initial_grant)
7953
7954         check_grants $osc_tgt $init_grants "init grants"
7955
7956         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
7957         local max_brw_size=$(import_param $osc_tgt max_brw_size)
7958         local gbs=$(import_param $osc_tgt grant_block_size)
7959
7960         # write random number of bytes from max_brw_size / 4 to max_brw_size
7961         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
7962         # align for direct io
7963         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
7964         # round to grant consumption unit
7965         local wb_round_up=$(round_up_p2 $write_bytes gbs)
7966
7967         local grants=$((wb_round_up + extent_tax))
7968
7969         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
7970
7971         # define OBD_FAIL_TGT_NO_GRANT 0x725
7972         # make the server not grant more back
7973         do_facet ost1 $LCTL set_param fail_loc=0x725
7974         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
7975
7976         do_facet ost1 $LCTL set_param fail_loc=0
7977
7978         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
7979
7980         rm -f $DIR/$tfile || error "rm failed"
7981
7982         # Remount client to reset grant
7983         remount_client $MOUNT || error "failed to remount client"
7984         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
7985
7986         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
7987
7988         # define OBD_FAIL_TGT_NO_GRANT 0x725
7989         # make the server not grant more back
7990         do_facet ost1 $LCTL set_param fail_loc=0x725
7991         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
7992         do_facet ost1 $LCTL set_param fail_loc=0
7993
7994         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
7995 }
7996 run_test 64e "check grant consumption (no grant allocation)"
7997
7998 test_64f() {
7999         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8000
8001         # Remount client to reset grant
8002         remount_client $MOUNT || error "failed to remount client"
8003         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8004
8005         local init_grants=$(import_param $osc_tgt initial_grant)
8006         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8007         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8008         local gbs=$(import_param $osc_tgt grant_block_size)
8009         local chunk=$(grant_chunk $osc_tgt)
8010
8011         # write random number of bytes from max_brw_size / 4 to max_brw_size
8012         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8013         # align for direct io
8014         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8015         # round to grant consumption unit
8016         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8017
8018         local grants=$((wb_round_up + extent_tax))
8019
8020         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8021         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8022                 error "error writing to $DIR/$tfile"
8023
8024         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8025                 "direct io with grant allocation"
8026
8027         rm -f $DIR/$tfile || error "rm failed"
8028
8029         # Remount client to reset grant
8030         remount_client $MOUNT || error "failed to remount client"
8031         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8032
8033         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8034
8035         local cmd="oO_WRONLY:w${write_bytes}_yc"
8036
8037         $MULTIOP $DIR/$tfile $cmd &
8038         MULTIPID=$!
8039         sleep 1
8040
8041         check_grants $osc_tgt $((init_grants - grants)) \
8042                 "buffered io, not write rpc"
8043
8044         kill -USR1 $MULTIPID
8045         wait
8046
8047         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8048                 "buffered io, one RPC"
8049 }
8050 run_test 64f "check grant consumption (with grant allocation)"
8051
8052 # bug 1414 - set/get directories' stripe info
8053 test_65a() {
8054         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8055
8056         test_mkdir $DIR/$tdir
8057         touch $DIR/$tdir/f1
8058         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
8059 }
8060 run_test 65a "directory with no stripe info"
8061
8062 test_65b() {
8063         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8064
8065         test_mkdir $DIR/$tdir
8066         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8067
8068         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8069                                                 error "setstripe"
8070         touch $DIR/$tdir/f2
8071         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
8072 }
8073 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
8074
8075 test_65c() {
8076         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8077         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
8078
8079         test_mkdir $DIR/$tdir
8080         local stripesize=$($LFS getstripe -S $DIR/$tdir)
8081
8082         $LFS setstripe -S $((stripesize * 4)) -i 1 \
8083                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
8084         touch $DIR/$tdir/f3
8085         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
8086 }
8087 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
8088
8089 test_65d() {
8090         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8091
8092         test_mkdir $DIR/$tdir
8093         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
8094         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8095
8096         if [[ $STRIPECOUNT -le 0 ]]; then
8097                 sc=1
8098         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
8099                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
8100                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
8101         else
8102                 sc=$(($STRIPECOUNT - 1))
8103         fi
8104         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
8105         touch $DIR/$tdir/f4 $DIR/$tdir/f5
8106         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
8107                 error "lverify failed"
8108 }
8109 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
8110
8111 test_65e() {
8112         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8113
8114         test_mkdir $DIR/$tdir
8115
8116         $LFS setstripe $DIR/$tdir || error "setstripe"
8117         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8118                                         error "no stripe info failed"
8119         touch $DIR/$tdir/f6
8120         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
8121 }
8122 run_test 65e "directory setstripe defaults"
8123
8124 test_65f() {
8125         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8126
8127         test_mkdir $DIR/${tdir}f
8128         $RUNAS $LFS setstripe $DIR/${tdir}f &&
8129                 error "setstripe succeeded" || true
8130 }
8131 run_test 65f "dir setstripe permission (should return error) ==="
8132
8133 test_65g() {
8134         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8135
8136         test_mkdir $DIR/$tdir
8137         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8138
8139         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8140                 error "setstripe -S failed"
8141         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
8142         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8143                 error "delete default stripe failed"
8144 }
8145 run_test 65g "directory setstripe -d"
8146
8147 test_65h() {
8148         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8149
8150         test_mkdir $DIR/$tdir
8151         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8152
8153         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8154                 error "setstripe -S failed"
8155         test_mkdir $DIR/$tdir/dd1
8156         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
8157                 error "stripe info inherit failed"
8158 }
8159 run_test 65h "directory stripe info inherit ===================="
8160
8161 test_65i() {
8162         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8163
8164         save_layout_restore_at_exit $MOUNT
8165
8166         # bug6367: set non-default striping on root directory
8167         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
8168
8169         # bug12836: getstripe on -1 default directory striping
8170         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
8171
8172         # bug12836: getstripe -v on -1 default directory striping
8173         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
8174
8175         # bug12836: new find on -1 default directory striping
8176         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
8177 }
8178 run_test 65i "various tests to set root directory striping"
8179
8180 test_65j() { # bug6367
8181         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8182
8183         sync; sleep 1
8184
8185         # if we aren't already remounting for each test, do so for this test
8186         if [ "$I_MOUNTED" = "yes" ]; then
8187                 cleanup || error "failed to unmount"
8188                 setup
8189         fi
8190
8191         save_layout_restore_at_exit $MOUNT
8192
8193         $LFS setstripe -d $MOUNT || error "setstripe failed"
8194 }
8195 run_test 65j "set default striping on root directory (bug 6367)="
8196
8197 cleanup_65k() {
8198         rm -rf $DIR/$tdir
8199         wait_delete_completed
8200         do_facet $SINGLEMDS "lctl set_param -n \
8201                 osp.$ost*MDT0000.max_create_count=$max_count"
8202         do_facet $SINGLEMDS "lctl set_param -n \
8203                 osp.$ost*MDT0000.create_count=$count"
8204         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8205         echo $INACTIVE_OSC "is Activate"
8206
8207         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8208 }
8209
8210 test_65k() { # bug11679
8211         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8212         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8213         remote_mds_nodsh && skip "remote MDS with nodsh"
8214
8215         local disable_precreate=true
8216         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
8217                 disable_precreate=false
8218
8219         echo "Check OST status: "
8220         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
8221                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
8222
8223         for OSC in $MDS_OSCS; do
8224                 echo $OSC "is active"
8225                 do_facet $SINGLEMDS lctl --device %$OSC activate
8226         done
8227
8228         for INACTIVE_OSC in $MDS_OSCS; do
8229                 local ost=$(osc_to_ost $INACTIVE_OSC)
8230                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
8231                                lov.*md*.target_obd |
8232                                awk -F: /$ost/'{ print $1 }' | head -n 1)
8233
8234                 mkdir -p $DIR/$tdir
8235                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
8236                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
8237
8238                 echo "Deactivate: " $INACTIVE_OSC
8239                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
8240
8241                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
8242                               osp.$ost*MDT0000.create_count")
8243                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
8244                                   osp.$ost*MDT0000.max_create_count")
8245                 $disable_precreate &&
8246                         do_facet $SINGLEMDS "lctl set_param -n \
8247                                 osp.$ost*MDT0000.max_create_count=0"
8248
8249                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
8250                         [ -f $DIR/$tdir/$idx ] && continue
8251                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
8252                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
8253                                 { cleanup_65k;
8254                                   error "setstripe $idx should succeed"; }
8255                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
8256                 done
8257                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
8258                 rmdir $DIR/$tdir
8259
8260                 do_facet $SINGLEMDS "lctl set_param -n \
8261                         osp.$ost*MDT0000.max_create_count=$max_count"
8262                 do_facet $SINGLEMDS "lctl set_param -n \
8263                         osp.$ost*MDT0000.create_count=$count"
8264                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8265                 echo $INACTIVE_OSC "is Activate"
8266
8267                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8268         done
8269 }
8270 run_test 65k "validate manual striping works properly with deactivated OSCs"
8271
8272 test_65l() { # bug 12836
8273         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8274
8275         test_mkdir -p $DIR/$tdir/test_dir
8276         $LFS setstripe -c -1 $DIR/$tdir/test_dir
8277         $LFS find -mtime -1 $DIR/$tdir >/dev/null
8278 }
8279 run_test 65l "lfs find on -1 stripe dir ========================"
8280
8281 test_65m() {
8282         local layout=$(save_layout $MOUNT)
8283         $RUNAS $LFS setstripe -c 2 $MOUNT && {
8284                 restore_layout $MOUNT $layout
8285                 error "setstripe should fail by non-root users"
8286         }
8287         true
8288 }
8289 run_test 65m "normal user can't set filesystem default stripe"
8290
8291 test_65n() {
8292         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
8293         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
8294                 skip "Need MDS version at least 2.12.50"
8295         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8296
8297         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8298         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
8299         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
8300
8301         local root_layout=$(save_layout $MOUNT)
8302         stack_trap "restore_layout $MOUNT $root_layout" EXIT
8303
8304         # new subdirectory under root directory should not inherit
8305         # the default layout from root
8306         local dir1=$MOUNT/$tdir-1
8307         mkdir $dir1 || error "mkdir $dir1 failed"
8308         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
8309                 error "$dir1 shouldn't have LOV EA"
8310
8311         # delete the default layout on root directory
8312         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
8313
8314         local dir2=$MOUNT/$tdir-2
8315         mkdir $dir2 || error "mkdir $dir2 failed"
8316         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
8317                 error "$dir2 shouldn't have LOV EA"
8318
8319         # set a new striping pattern on root directory
8320         local def_stripe_size=$($LFS getstripe -S $MOUNT)
8321         local new_def_stripe_size=$((def_stripe_size * 2))
8322         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
8323                 error "set stripe size on $MOUNT failed"
8324
8325         # new file created in $dir2 should inherit the new stripe size from
8326         # the filesystem default
8327         local file2=$dir2/$tfile-2
8328         touch $file2 || error "touch $file2 failed"
8329
8330         local file2_stripe_size=$($LFS getstripe -S $file2)
8331         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
8332                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
8333
8334         local dir3=$MOUNT/$tdir-3
8335         mkdir $dir3 || error "mkdir $dir3 failed"
8336         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
8337         # the root layout, which is the actual default layout that will be used
8338         # when new files are created in $dir3.
8339         local dir3_layout=$(get_layout_param $dir3)
8340         local root_dir_layout=$(get_layout_param $MOUNT)
8341         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
8342                 error "$dir3 should show the default layout from $MOUNT"
8343
8344         # set OST pool on root directory
8345         local pool=$TESTNAME
8346         pool_add $pool || error "add $pool failed"
8347         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8348                 error "add targets to $pool failed"
8349
8350         $LFS setstripe -p $pool $MOUNT ||
8351                 error "set OST pool on $MOUNT failed"
8352
8353         # new file created in $dir3 should inherit the pool from
8354         # the filesystem default
8355         local file3=$dir3/$tfile-3
8356         touch $file3 || error "touch $file3 failed"
8357
8358         local file3_pool=$($LFS getstripe -p $file3)
8359         [[ "$file3_pool" = "$pool" ]] ||
8360                 error "$file3 didn't inherit OST pool $pool"
8361
8362         local dir4=$MOUNT/$tdir-4
8363         mkdir $dir4 || error "mkdir $dir4 failed"
8364         local dir4_layout=$(get_layout_param $dir4)
8365         root_dir_layout=$(get_layout_param $MOUNT)
8366         echo "$LFS getstripe -d $dir4"
8367         $LFS getstripe -d $dir4
8368         echo "$LFS getstripe -d $MOUNT"
8369         $LFS getstripe -d $MOUNT
8370         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
8371                 error "$dir4 should show the default layout from $MOUNT"
8372
8373         # new file created in $dir4 should inherit the pool from
8374         # the filesystem default
8375         local file4=$dir4/$tfile-4
8376         touch $file4 || error "touch $file4 failed"
8377
8378         local file4_pool=$($LFS getstripe -p $file4)
8379         [[ "$file4_pool" = "$pool" ]] ||
8380                 error "$file4 didn't inherit OST pool $pool"
8381
8382         # new subdirectory under non-root directory should inherit
8383         # the default layout from its parent directory
8384         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
8385                 error "set directory layout on $dir4 failed"
8386
8387         local dir5=$dir4/$tdir-5
8388         mkdir $dir5 || error "mkdir $dir5 failed"
8389
8390         dir4_layout=$(get_layout_param $dir4)
8391         local dir5_layout=$(get_layout_param $dir5)
8392         [[ "$dir4_layout" = "$dir5_layout" ]] ||
8393                 error "$dir5 should inherit the default layout from $dir4"
8394
8395         # though subdir under ROOT doesn't inherit default layout, but
8396         # its sub dir/file should be created with default layout.
8397         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
8398         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
8399                 skip "Need MDS version at least 2.12.59"
8400
8401         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
8402         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
8403         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
8404
8405         if [ $default_lmv_hash == "none" ]; then
8406                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
8407         else
8408                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
8409                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
8410         fi
8411
8412         $LFS setdirstripe -D -c 2 $MOUNT ||
8413                 error "setdirstripe -D -c 2 failed"
8414         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
8415         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
8416         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
8417 }
8418 run_test 65n "don't inherit default layout from root for new subdirectories"
8419
8420 # bug 2543 - update blocks count on client
8421 test_66() {
8422         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8423
8424         COUNT=${COUNT:-8}
8425         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
8426         sync; sync_all_data; sync; sync_all_data
8427         cancel_lru_locks osc
8428         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
8429         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
8430 }
8431 run_test 66 "update inode blocks count on client ==============="
8432
8433 meminfo() {
8434         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
8435 }
8436
8437 swap_used() {
8438         swapon -s | awk '($1 == "'$1'") { print $4 }'
8439 }
8440
8441 # bug5265, obdfilter oa2dentry return -ENOENT
8442 # #define OBD_FAIL_SRV_ENOENT 0x217
8443 test_69() {
8444         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8445         remote_ost_nodsh && skip "remote OST with nodsh"
8446
8447         f="$DIR/$tfile"
8448         $LFS setstripe -c 1 -i 0 $f
8449
8450         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
8451
8452         do_facet ost1 lctl set_param fail_loc=0x217
8453         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
8454         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
8455
8456         do_facet ost1 lctl set_param fail_loc=0
8457         $DIRECTIO write $f 0 2 || error "write error"
8458
8459         cancel_lru_locks osc
8460         $DIRECTIO read $f 0 1 || error "read error"
8461
8462         do_facet ost1 lctl set_param fail_loc=0x217
8463         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
8464
8465         do_facet ost1 lctl set_param fail_loc=0
8466         rm -f $f
8467 }
8468 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
8469
8470 test_71() {
8471         test_mkdir $DIR/$tdir
8472         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
8473         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
8474 }
8475 run_test 71 "Running dbench on lustre (don't segment fault) ===="
8476
8477 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
8478         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8479         [ "$RUNAS_ID" = "$UID" ] &&
8480                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8481         # Check that testing environment is properly set up. Skip if not
8482         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
8483                 skip_env "User $RUNAS_ID does not exist - skipping"
8484
8485         touch $DIR/$tfile
8486         chmod 777 $DIR/$tfile
8487         chmod ug+s $DIR/$tfile
8488         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
8489                 error "$RUNAS dd $DIR/$tfile failed"
8490         # See if we are still setuid/sgid
8491         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8492                 error "S/gid is not dropped on write"
8493         # Now test that MDS is updated too
8494         cancel_lru_locks mdc
8495         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8496                 error "S/gid is not dropped on MDS"
8497         rm -f $DIR/$tfile
8498 }
8499 run_test 72a "Test that remove suid works properly (bug5695) ===="
8500
8501 test_72b() { # bug 24226 -- keep mode setting when size is not changing
8502         local perm
8503
8504         [ "$RUNAS_ID" = "$UID" ] &&
8505                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8506         [ "$RUNAS_ID" -eq 0 ] &&
8507                 skip_env "RUNAS_ID = 0 -- skipping"
8508         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8509         # Check that testing environment is properly set up. Skip if not
8510         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
8511                 skip_env "User $RUNAS_ID does not exist - skipping"
8512
8513         touch $DIR/${tfile}-f{g,u}
8514         test_mkdir $DIR/${tfile}-dg
8515         test_mkdir $DIR/${tfile}-du
8516         chmod 770 $DIR/${tfile}-{f,d}{g,u}
8517         chmod g+s $DIR/${tfile}-{f,d}g
8518         chmod u+s $DIR/${tfile}-{f,d}u
8519         for perm in 777 2777 4777; do
8520                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
8521                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
8522                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
8523                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
8524         done
8525         true
8526 }
8527 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
8528
8529 # bug 3462 - multiple simultaneous MDC requests
8530 test_73() {
8531         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8532
8533         test_mkdir $DIR/d73-1
8534         test_mkdir $DIR/d73-2
8535         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
8536         pid1=$!
8537
8538         lctl set_param fail_loc=0x80000129
8539         $MULTIOP $DIR/d73-1/f73-2 Oc &
8540         sleep 1
8541         lctl set_param fail_loc=0
8542
8543         $MULTIOP $DIR/d73-2/f73-3 Oc &
8544         pid3=$!
8545
8546         kill -USR1 $pid1
8547         wait $pid1 || return 1
8548
8549         sleep 25
8550
8551         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
8552         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
8553         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
8554
8555         rm -rf $DIR/d73-*
8556 }
8557 run_test 73 "multiple MDC requests (should not deadlock)"
8558
8559 test_74a() { # bug 6149, 6184
8560         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8561
8562         touch $DIR/f74a
8563         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8564         #
8565         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8566         # will spin in a tight reconnection loop
8567         $LCTL set_param fail_loc=0x8000030e
8568         # get any lock that won't be difficult - lookup works.
8569         ls $DIR/f74a
8570         $LCTL set_param fail_loc=0
8571         rm -f $DIR/f74a
8572         true
8573 }
8574 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
8575
8576 test_74b() { # bug 13310
8577         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8578
8579         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8580         #
8581         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8582         # will spin in a tight reconnection loop
8583         $LCTL set_param fail_loc=0x8000030e
8584         # get a "difficult" lock
8585         touch $DIR/f74b
8586         $LCTL set_param fail_loc=0
8587         rm -f $DIR/f74b
8588         true
8589 }
8590 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
8591
8592 test_74c() {
8593         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8594
8595         #define OBD_FAIL_LDLM_NEW_LOCK
8596         $LCTL set_param fail_loc=0x319
8597         touch $DIR/$tfile && error "touch successful"
8598         $LCTL set_param fail_loc=0
8599         true
8600 }
8601 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
8602
8603 num_inodes() {
8604         awk '/lustre_inode_cache/ {print $2; exit}' /proc/slabinfo
8605 }
8606
8607 test_76() { # Now for bug 20433, added originally in bug 1443
8608         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8609
8610         cancel_lru_locks osc
8611         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
8612         local before=$(num_inodes)
8613         local count=$((512 * cpus))
8614         [ "$SLOW" = "no" ] && count=$((64 * cpus))
8615
8616         echo "before inodes: $before"
8617         for i in $(seq $count); do
8618                 touch $DIR/$tfile
8619                 rm -f $DIR/$tfile
8620         done
8621         cancel_lru_locks osc
8622         local after=$(num_inodes)
8623         echo "after inodes: $after"
8624         while (( after > before + 8 * ${cpus:-1} )); do
8625                 sleep 1
8626                 after=$(num_inodes)
8627                 wait=$((wait + 1))
8628                 (( wait % 5 == 0 )) && echo "wait $wait seconds inodes: $after"
8629                 if (( wait > 30 )); then
8630                         error "inode slab grew from $before to $after"
8631                 fi
8632         done
8633 }
8634 run_test 76 "confirm clients recycle inodes properly ===="
8635
8636
8637 export ORIG_CSUM=""
8638 set_checksums()
8639 {
8640         # Note: in sptlrpc modes which enable its own bulk checksum, the
8641         # original crc32_le bulk checksum will be automatically disabled,
8642         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
8643         # will be checked by sptlrpc code against sptlrpc bulk checksum.
8644         # In this case set_checksums() will not be no-op, because sptlrpc
8645         # bulk checksum will be enabled all through the test.
8646
8647         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
8648         lctl set_param -n osc.*.checksums $1
8649         return 0
8650 }
8651
8652 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8653                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
8654 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8655                              tr -d [] | head -n1)}
8656 set_checksum_type()
8657 {
8658         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
8659         rc=$?
8660         log "set checksum type to $1, rc = $rc"
8661         return $rc
8662 }
8663
8664 get_osc_checksum_type()
8665 {
8666         # arugment 1: OST name, like OST0000
8667         ost=$1
8668         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
8669                         sed 's/.*\[\(.*\)\].*/\1/g')
8670         rc=$?
8671         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
8672         echo $checksum_type
8673 }
8674
8675 F77_TMP=$TMP/f77-temp
8676 F77SZ=8
8677 setup_f77() {
8678         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
8679                 error "error writing to $F77_TMP"
8680 }
8681
8682 test_77a() { # bug 10889
8683         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8684         $GSS && skip_env "could not run with gss"
8685
8686         [ ! -f $F77_TMP ] && setup_f77
8687         set_checksums 1
8688         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
8689         set_checksums 0
8690         rm -f $DIR/$tfile
8691 }
8692 run_test 77a "normal checksum read/write operation"
8693
8694 test_77b() { # bug 10889
8695         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8696         $GSS && skip_env "could not run with gss"
8697
8698         [ ! -f $F77_TMP ] && setup_f77
8699         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8700         $LCTL set_param fail_loc=0x80000409
8701         set_checksums 1
8702
8703         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8704                 error "dd error: $?"
8705         $LCTL set_param fail_loc=0
8706
8707         for algo in $CKSUM_TYPES; do
8708                 cancel_lru_locks osc
8709                 set_checksum_type $algo
8710                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8711                 $LCTL set_param fail_loc=0x80000408
8712                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
8713                 $LCTL set_param fail_loc=0
8714         done
8715         set_checksums 0
8716         set_checksum_type $ORIG_CSUM_TYPE
8717         rm -f $DIR/$tfile
8718 }
8719 run_test 77b "checksum error on client write, read"
8720
8721 cleanup_77c() {
8722         trap 0
8723         set_checksums 0
8724         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
8725         $check_ost &&
8726                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
8727         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
8728         $check_ost && [ -n "$ost_file_prefix" ] &&
8729                 do_facet ost1 rm -f ${ost_file_prefix}\*
8730 }
8731
8732 test_77c() {
8733         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8734         $GSS && skip_env "could not run with gss"
8735         remote_ost_nodsh && skip "remote OST with nodsh"
8736
8737         local bad1
8738         local osc_file_prefix
8739         local osc_file
8740         local check_ost=false
8741         local ost_file_prefix
8742         local ost_file
8743         local orig_cksum
8744         local dump_cksum
8745         local fid
8746
8747         # ensure corruption will occur on first OSS/OST
8748         $LFS setstripe -i 0 $DIR/$tfile
8749
8750         [ ! -f $F77_TMP ] && setup_f77
8751         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8752                 error "dd write error: $?"
8753         fid=$($LFS path2fid $DIR/$tfile)
8754
8755         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
8756         then
8757                 check_ost=true
8758                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
8759                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
8760         else
8761                 echo "OSS do not support bulk pages dump upon error"
8762         fi
8763
8764         osc_file_prefix=$($LCTL get_param -n debug_path)
8765         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
8766
8767         trap cleanup_77c EXIT
8768
8769         set_checksums 1
8770         # enable bulk pages dump upon error on Client
8771         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
8772         # enable bulk pages dump upon error on OSS
8773         $check_ost &&
8774                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
8775
8776         # flush Client cache to allow next read to reach OSS
8777         cancel_lru_locks osc
8778
8779         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
8780         $LCTL set_param fail_loc=0x80000408
8781         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
8782         $LCTL set_param fail_loc=0
8783
8784         rm -f $DIR/$tfile
8785
8786         # check cksum dump on Client
8787         osc_file=$(ls ${osc_file_prefix}*)
8788         [ -n "$osc_file" ] || error "no checksum dump file on Client"
8789         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
8790         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
8791         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
8792         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
8793                      cksum)
8794         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
8795         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8796                 error "dump content does not match on Client"
8797
8798         $check_ost || skip "No need to check cksum dump on OSS"
8799
8800         # check cksum dump on OSS
8801         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
8802         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
8803         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
8804         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
8805         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8806                 error "dump content does not match on OSS"
8807
8808         cleanup_77c
8809 }
8810 run_test 77c "checksum error on client read with debug"
8811
8812 test_77d() { # bug 10889
8813         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8814         $GSS && skip_env "could not run with gss"
8815
8816         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8817         $LCTL set_param fail_loc=0x80000409
8818         set_checksums 1
8819         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8820                 error "direct write: rc=$?"
8821         $LCTL set_param fail_loc=0
8822         set_checksums 0
8823
8824         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8825         $LCTL set_param fail_loc=0x80000408
8826         set_checksums 1
8827         cancel_lru_locks osc
8828         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8829                 error "direct read: rc=$?"
8830         $LCTL set_param fail_loc=0
8831         set_checksums 0
8832 }
8833 run_test 77d "checksum error on OST direct write, read"
8834
8835 test_77f() { # bug 10889
8836         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8837         $GSS && skip_env "could not run with gss"
8838
8839         set_checksums 1
8840         for algo in $CKSUM_TYPES; do
8841                 cancel_lru_locks osc
8842                 set_checksum_type $algo
8843                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8844                 $LCTL set_param fail_loc=0x409
8845                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
8846                         error "direct write succeeded"
8847                 $LCTL set_param fail_loc=0
8848         done
8849         set_checksum_type $ORIG_CSUM_TYPE
8850         set_checksums 0
8851 }
8852 run_test 77f "repeat checksum error on write (expect error)"
8853
8854 test_77g() { # bug 10889
8855         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8856         $GSS && skip_env "could not run with gss"
8857         remote_ost_nodsh && skip "remote OST with nodsh"
8858
8859         [ ! -f $F77_TMP ] && setup_f77
8860
8861         local file=$DIR/$tfile
8862         stack_trap "rm -f $file" EXIT
8863
8864         $LFS setstripe -c 1 -i 0 $file
8865         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
8866         do_facet ost1 lctl set_param fail_loc=0x8000021a
8867         set_checksums 1
8868         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
8869                 error "write error: rc=$?"
8870         do_facet ost1 lctl set_param fail_loc=0
8871         set_checksums 0
8872
8873         cancel_lru_locks osc
8874         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
8875         do_facet ost1 lctl set_param fail_loc=0x8000021b
8876         set_checksums 1
8877         cmp $F77_TMP $file || error "file compare failed"
8878         do_facet ost1 lctl set_param fail_loc=0
8879         set_checksums 0
8880 }
8881 run_test 77g "checksum error on OST write, read"
8882
8883 test_77k() { # LU-10906
8884         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8885         $GSS && skip_env "could not run with gss"
8886
8887         local cksum_param="osc.$FSNAME*.checksums"
8888         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
8889         local checksum
8890         local i
8891
8892         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
8893         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
8894         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
8895
8896         for i in 0 1; do
8897                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
8898                         error "failed to set checksum=$i on MGS"
8899                 wait_update $HOSTNAME "$get_checksum" $i
8900                 #remount
8901                 echo "remount client, checksum should be $i"
8902                 remount_client $MOUNT || error "failed to remount client"
8903                 checksum=$(eval $get_checksum)
8904                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
8905         done
8906         # remove persistent param to avoid races with checksum mountopt below
8907         do_facet mgs $LCTL set_param -P -d $cksum_param ||
8908                 error "failed to delete checksum on MGS"
8909
8910         for opt in "checksum" "nochecksum"; do
8911                 #remount with mount option
8912                 echo "remount client with option $opt, checksum should be $i"
8913                 umount_client $MOUNT || error "failed to umount client"
8914                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
8915                         error "failed to mount client with option '$opt'"
8916                 checksum=$(eval $get_checksum)
8917                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
8918                 i=$((i - 1))
8919         done
8920
8921         remount_client $MOUNT || error "failed to remount client"
8922 }
8923 run_test 77k "enable/disable checksum correctly"
8924
8925 test_77l() {
8926         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8927         $GSS && skip_env "could not run with gss"
8928
8929         set_checksums 1
8930         stack_trap "set_checksums $ORIG_CSUM" EXIT
8931         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
8932
8933         set_checksum_type invalid && error "unexpected success of invalid checksum type"
8934
8935         $LFS setstripe -c 1 -i 0 $DIR/$tfile
8936         for algo in $CKSUM_TYPES; do
8937                 set_checksum_type $algo || error "fail to set checksum type $algo"
8938                 osc_algo=$(get_osc_checksum_type OST0000)
8939                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
8940
8941                 # no locks, no reqs to let the connection idle
8942                 cancel_lru_locks osc
8943                 lru_resize_disable osc
8944                 wait_osc_import_state client ost1 IDLE
8945
8946                 # ensure ost1 is connected
8947                 stat $DIR/$tfile >/dev/null || error "can't stat"
8948                 wait_osc_import_state client ost1 FULL
8949
8950                 osc_algo=$(get_osc_checksum_type OST0000)
8951                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
8952         done
8953         return 0
8954 }
8955 run_test 77l "preferred checksum type is remembered after reconnected"
8956
8957 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
8958 rm -f $F77_TMP
8959 unset F77_TMP
8960
8961 cleanup_test_78() {
8962         trap 0
8963         rm -f $DIR/$tfile
8964 }
8965
8966 test_78() { # bug 10901
8967         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8968         remote_ost || skip_env "local OST"
8969
8970         NSEQ=5
8971         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
8972         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
8973         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
8974         echo "MemTotal: $MEMTOTAL"
8975
8976         # reserve 256MB of memory for the kernel and other running processes,
8977         # and then take 1/2 of the remaining memory for the read/write buffers.
8978         if [ $MEMTOTAL -gt 512 ] ;then
8979                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
8980         else
8981                 # for those poor memory-starved high-end clusters...
8982                 MEMTOTAL=$((MEMTOTAL / 2))
8983         fi
8984         echo "Mem to use for directio: $MEMTOTAL"
8985
8986         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
8987         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
8988         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
8989         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
8990                 head -n1)
8991         echo "Smallest OST: $SMALLESTOST"
8992         [[ $SMALLESTOST -lt 10240 ]] &&
8993                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
8994
8995         trap cleanup_test_78 EXIT
8996
8997         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
8998                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
8999
9000         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
9001         echo "File size: $F78SIZE"
9002         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
9003         for i in $(seq 1 $NSEQ); do
9004                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
9005                 echo directIO rdwr round $i of $NSEQ
9006                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
9007         done
9008
9009         cleanup_test_78
9010 }
9011 run_test 78 "handle large O_DIRECT writes correctly ============"
9012
9013 test_79() { # bug 12743
9014         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9015
9016         wait_delete_completed
9017
9018         BKTOTAL=$(calc_osc_kbytes kbytestotal)
9019         BKFREE=$(calc_osc_kbytes kbytesfree)
9020         BKAVAIL=$(calc_osc_kbytes kbytesavail)
9021
9022         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
9023         DFTOTAL=`echo $STRING | cut -d, -f1`
9024         DFUSED=`echo $STRING  | cut -d, -f2`
9025         DFAVAIL=`echo $STRING | cut -d, -f3`
9026         DFFREE=$(($DFTOTAL - $DFUSED))
9027
9028         ALLOWANCE=$((64 * $OSTCOUNT))
9029
9030         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
9031            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
9032                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
9033         fi
9034         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
9035            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
9036                 error "df free($DFFREE) mismatch OST free($BKFREE)"
9037         fi
9038         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
9039            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
9040                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
9041         fi
9042 }
9043 run_test 79 "df report consistency check ======================="
9044
9045 test_80() { # bug 10718
9046         remote_ost_nodsh && skip "remote OST with nodsh"
9047         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9048
9049         # relax strong synchronous semantics for slow backends like ZFS
9050         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
9051                 local soc="obdfilter.*.sync_lock_cancel"
9052                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9053
9054                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
9055                 if [ -z "$save" ]; then
9056                         soc="obdfilter.*.sync_on_lock_cancel"
9057                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9058                 fi
9059
9060                 if [ "$save" != "never" ]; then
9061                         local hosts=$(comma_list $(osts_nodes))
9062
9063                         do_nodes $hosts $LCTL set_param $soc=never
9064                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
9065                 fi
9066         fi
9067
9068         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
9069         sync; sleep 1; sync
9070         local before=$(date +%s)
9071         cancel_lru_locks osc
9072         local after=$(date +%s)
9073         local diff=$((after - before))
9074         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
9075
9076         rm -f $DIR/$tfile
9077 }
9078 run_test 80 "Page eviction is equally fast at high offsets too"
9079
9080 test_81a() { # LU-456
9081         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9082         remote_ost_nodsh && skip "remote OST with nodsh"
9083
9084         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9085         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
9086         do_facet ost1 lctl set_param fail_loc=0x80000228
9087
9088         # write should trigger a retry and success
9089         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9090         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9091         RC=$?
9092         if [ $RC -ne 0 ] ; then
9093                 error "write should success, but failed for $RC"
9094         fi
9095 }
9096 run_test 81a "OST should retry write when get -ENOSPC ==============="
9097
9098 test_81b() { # LU-456
9099         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9100         remote_ost_nodsh && skip "remote OST with nodsh"
9101
9102         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9103         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
9104         do_facet ost1 lctl set_param fail_loc=0x228
9105
9106         # write should retry several times and return -ENOSPC finally
9107         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9108         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9109         RC=$?
9110         ENOSPC=28
9111         if [ $RC -ne $ENOSPC ] ; then
9112                 error "dd should fail for -ENOSPC, but succeed."
9113         fi
9114 }
9115 run_test 81b "OST should return -ENOSPC when retry still fails ======="
9116
9117 test_82() { # LU-1031
9118         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10
9119         local gid1=14091995
9120         local gid2=16022000
9121
9122         multiop_bg_pause $DIR/$tfile OG${gid1}_g${gid1}c || return 1
9123         local MULTIPID1=$!
9124         multiop_bg_pause $DIR/$tfile O_G${gid2}r10g${gid2}c || return 2
9125         local MULTIPID2=$!
9126         kill -USR1 $MULTIPID2
9127         sleep 2
9128         if [[ `ps h -o comm -p $MULTIPID2` == "" ]]; then
9129                 error "First grouplock does not block second one"
9130         else
9131                 echo "Second grouplock blocks first one"
9132         fi
9133         kill -USR1 $MULTIPID1
9134         wait $MULTIPID1
9135         wait $MULTIPID2
9136 }
9137 run_test 82 "Basic grouplock test"
9138
9139 test_99() {
9140         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
9141
9142         test_mkdir $DIR/$tdir.cvsroot
9143         chown $RUNAS_ID $DIR/$tdir.cvsroot
9144
9145         cd $TMP
9146         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
9147
9148         cd /etc/init.d
9149         # some versions of cvs import exit(1) when asked to import links or
9150         # files they can't read.  ignore those files.
9151         local toignore=$(find . -type l -printf '-I %f\n' -o \
9152                          ! -perm /4 -printf '-I %f\n')
9153         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
9154                 $tdir.reposname vtag rtag
9155
9156         cd $DIR
9157         test_mkdir $DIR/$tdir.reposname
9158         chown $RUNAS_ID $DIR/$tdir.reposname
9159         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
9160
9161         cd $DIR/$tdir.reposname
9162         $RUNAS touch foo99
9163         $RUNAS cvs add -m 'addmsg' foo99
9164         $RUNAS cvs update
9165         $RUNAS cvs commit -m 'nomsg' foo99
9166         rm -fr $DIR/$tdir.cvsroot
9167 }
9168 run_test 99 "cvs strange file/directory operations"
9169
9170 test_100() {
9171         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9172         [[ "$NETTYPE" =~ tcp ]] ||
9173                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
9174         remote_ost_nodsh && skip "remote OST with nodsh"
9175         remote_mds_nodsh && skip "remote MDS with nodsh"
9176         remote_servers ||
9177                 skip "useless for local single node setup"
9178
9179         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
9180                 [ "$PROT" != "tcp" ] && continue
9181                 RPORT=$(echo $REMOTE | cut -d: -f2)
9182                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
9183
9184                 rc=0
9185                 LPORT=`echo $LOCAL | cut -d: -f2`
9186                 if [ $LPORT -ge 1024 ]; then
9187                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
9188                         netstat -tna
9189                         error_exit "local: $LPORT > 1024, remote: $RPORT"
9190                 fi
9191         done
9192         [ "$rc" = 0 ] || error_exit "privileged port not found" )
9193 }
9194 run_test 100 "check local port using privileged port ==========="
9195
9196 function get_named_value()
9197 {
9198     local tag
9199
9200     tag=$1
9201     while read ;do
9202         line=$REPLY
9203         case $line in
9204         $tag*)
9205             echo $line | sed "s/^$tag[ ]*//"
9206             break
9207             ;;
9208         esac
9209     done
9210 }
9211
9212 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
9213                    awk '/^max_cached_mb/ { print $2 }')
9214
9215 cleanup_101a() {
9216         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
9217         trap 0
9218 }
9219
9220 test_101a() {
9221         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9222
9223         local s
9224         local discard
9225         local nreads=10000
9226         local cache_limit=32
9227
9228         $LCTL set_param -n osc.*-osc*.rpc_stats 0
9229         trap cleanup_101a EXIT
9230         $LCTL set_param -n llite.*.read_ahead_stats 0
9231         $LCTL set_param -n llite.*.max_cached_mb $cache_limit
9232
9233         #
9234         # randomly read 10000 of 64K chunks from file 3x 32MB in size
9235         #
9236         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
9237         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
9238
9239         discard=0
9240         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
9241                 get_named_value 'read but discarded' | cut -d" " -f1); do
9242                         discard=$(($discard + $s))
9243         done
9244         cleanup_101a
9245
9246         $LCTL get_param osc.*-osc*.rpc_stats
9247         $LCTL get_param llite.*.read_ahead_stats
9248
9249         # Discard is generally zero, but sometimes a few random reads line up
9250         # and trigger larger readahead, which is wasted & leads to discards.
9251         if [[ $(($discard)) -gt $nreads ]]; then
9252                 error "too many ($discard) discarded pages"
9253         fi
9254         rm -f $DIR/$tfile || true
9255 }
9256 run_test 101a "check read-ahead for random reads"
9257
9258 setup_test101bc() {
9259         test_mkdir $DIR/$tdir
9260         local ssize=$1
9261         local FILE_LENGTH=$2
9262         STRIPE_OFFSET=0
9263
9264         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
9265
9266         local list=$(comma_list $(osts_nodes))
9267         set_osd_param $list '' read_cache_enable 0
9268         set_osd_param $list '' writethrough_cache_enable 0
9269
9270         trap cleanup_test101bc EXIT
9271         # prepare the read-ahead file
9272         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
9273
9274         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
9275                                 count=$FILE_SIZE_MB 2> /dev/null
9276
9277 }
9278
9279 cleanup_test101bc() {
9280         trap 0
9281         rm -rf $DIR/$tdir
9282         rm -f $DIR/$tfile
9283
9284         local list=$(comma_list $(osts_nodes))
9285         set_osd_param $list '' read_cache_enable 1
9286         set_osd_param $list '' writethrough_cache_enable 1
9287 }
9288
9289 calc_total() {
9290         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
9291 }
9292
9293 ra_check_101() {
9294         local READ_SIZE=$1
9295         local STRIPE_SIZE=$2
9296         local FILE_LENGTH=$3
9297         local RA_INC=1048576
9298         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
9299         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
9300                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
9301         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
9302                         get_named_value 'read but discarded' |
9303                         cut -d" " -f1 | calc_total)
9304         if [[ $DISCARD -gt $discard_limit ]]; then
9305                 $LCTL get_param llite.*.read_ahead_stats
9306                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
9307         else
9308                 echo "Read-ahead success for size ${READ_SIZE}"
9309         fi
9310 }
9311
9312 test_101b() {
9313         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9314         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9315
9316         local STRIPE_SIZE=1048576
9317         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
9318
9319         if [ $SLOW == "yes" ]; then
9320                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
9321         else
9322                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
9323         fi
9324
9325         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
9326
9327         # prepare the read-ahead file
9328         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9329         cancel_lru_locks osc
9330         for BIDX in 2 4 8 16 32 64 128 256
9331         do
9332                 local BSIZE=$((BIDX*4096))
9333                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
9334                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
9335                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
9336                 $LCTL set_param -n llite.*.read_ahead_stats 0
9337                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
9338                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
9339                 cancel_lru_locks osc
9340                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
9341         done
9342         cleanup_test101bc
9343         true
9344 }
9345 run_test 101b "check stride-io mode read-ahead ================="
9346
9347 test_101c() {
9348         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9349
9350         local STRIPE_SIZE=1048576
9351         local FILE_LENGTH=$((STRIPE_SIZE*100))
9352         local nreads=10000
9353         local rsize=65536
9354         local osc_rpc_stats
9355
9356         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9357
9358         cancel_lru_locks osc
9359         $LCTL set_param osc.*.rpc_stats 0
9360         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
9361         $LCTL get_param osc.*.rpc_stats
9362         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
9363                 local stats=$($LCTL get_param -n $osc_rpc_stats)
9364                 local lines=$(echo "$stats" | awk 'END {print NR;}')
9365                 local size
9366
9367                 if [ $lines -le 20 ]; then
9368                         echo "continue debug"
9369                         continue
9370                 fi
9371                 for size in 1 2 4 8; do
9372                         local rpc=$(echo "$stats" |
9373                                     awk '($1 == "'$size':") {print $2; exit; }')
9374                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
9375                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
9376                 done
9377                 echo "$osc_rpc_stats check passed!"
9378         done
9379         cleanup_test101bc
9380         true
9381 }
9382 run_test 101c "check stripe_size aligned read-ahead ================="
9383
9384 test_101d() {
9385         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9386
9387         local file=$DIR/$tfile
9388         local sz_MB=${FILESIZE_101d:-80}
9389         local ra_MB=${READAHEAD_MB:-40}
9390
9391         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
9392         [ $free_MB -lt $sz_MB ] &&
9393                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
9394
9395         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
9396         $LFS setstripe -c -1 $file || error "setstripe failed"
9397
9398         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
9399         echo Cancel LRU locks on lustre client to flush the client cache
9400         cancel_lru_locks osc
9401
9402         echo Disable read-ahead
9403         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9404         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9405         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_RA" EXIT
9406         $LCTL get_param -n llite.*.max_read_ahead_mb
9407
9408         echo "Reading the test file $file with read-ahead disabled"
9409         local sz_KB=$((sz_MB * 1024 / 4))
9410         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
9411         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
9412         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9413                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9414
9415         echo "Cancel LRU locks on lustre client to flush the client cache"
9416         cancel_lru_locks osc
9417         echo Enable read-ahead with ${ra_MB}MB
9418         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
9419
9420         echo "Reading the test file $file with read-ahead enabled"
9421         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9422                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9423
9424         echo "read-ahead disabled time read $raOFF"
9425         echo "read-ahead enabled time read $raON"
9426
9427         rm -f $file
9428         wait_delete_completed
9429
9430         # use awk for this check instead of bash because it handles decimals
9431         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
9432                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
9433 }
9434 run_test 101d "file read with and without read-ahead enabled"
9435
9436 test_101e() {
9437         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9438
9439         local file=$DIR/$tfile
9440         local size_KB=500  #KB
9441         local count=100
9442         local bsize=1024
9443
9444         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
9445         local need_KB=$((count * size_KB))
9446         [[ $free_KB -le $need_KB ]] &&
9447                 skip_env "Need free space $need_KB, have $free_KB"
9448
9449         echo "Creating $count ${size_KB}K test files"
9450         for ((i = 0; i < $count; i++)); do
9451                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
9452         done
9453
9454         echo "Cancel LRU locks on lustre client to flush the client cache"
9455         cancel_lru_locks $OSC
9456
9457         echo "Reset readahead stats"
9458         $LCTL set_param -n llite.*.read_ahead_stats 0
9459
9460         for ((i = 0; i < $count; i++)); do
9461                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
9462         done
9463
9464         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9465                      get_named_value 'misses' | cut -d" " -f1 | calc_total)
9466
9467         for ((i = 0; i < $count; i++)); do
9468                 rm -rf $file.$i 2>/dev/null
9469         done
9470
9471         #10000 means 20% reads are missing in readahead
9472         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
9473 }
9474 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
9475
9476 test_101f() {
9477         which iozone || skip_env "no iozone installed"
9478
9479         local old_debug=$($LCTL get_param debug)
9480         old_debug=${old_debug#*=}
9481         $LCTL set_param debug="reada mmap"
9482
9483         # create a test file
9484         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
9485
9486         echo Cancel LRU locks on lustre client to flush the client cache
9487         cancel_lru_locks osc
9488
9489         echo Reset readahead stats
9490         $LCTL set_param -n llite.*.read_ahead_stats 0
9491
9492         echo mmap read the file with small block size
9493         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
9494                 > /dev/null 2>&1
9495
9496         echo checking missing pages
9497         $LCTL get_param llite.*.read_ahead_stats
9498         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9499                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9500
9501         $LCTL set_param debug="$old_debug"
9502         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
9503         rm -f $DIR/$tfile
9504 }
9505 run_test 101f "check mmap read performance"
9506
9507 test_101g_brw_size_test() {
9508         local mb=$1
9509         local pages=$((mb * 1048576 / PAGE_SIZE))
9510         local file=$DIR/$tfile
9511
9512         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
9513                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
9514         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
9515                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
9516                         return 2
9517         done
9518
9519         stack_trap "rm -f $file" EXIT
9520         $LCTL set_param -n osc.*.rpc_stats=0
9521
9522         # 10 RPCs should be enough for the test
9523         local count=10
9524         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
9525                 { error "dd write ${mb} MB blocks failed"; return 3; }
9526         cancel_lru_locks osc
9527         dd of=/dev/null if=$file bs=${mb}M count=$count ||
9528                 { error "dd write ${mb} MB blocks failed"; return 4; }
9529
9530         # calculate number of full-sized read and write RPCs
9531         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
9532                 sed -n '/pages per rpc/,/^$/p' |
9533                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
9534                 END { print reads,writes }'))
9535         [ ${rpcs[0]} -ne $count ] && error "${rpcs[0]} != $count read RPCs" &&
9536                 return 5
9537         [ ${rpcs[1]} -ne $count ] && error "${rpcs[1]} != $count write RPCs" &&
9538                 return 6
9539
9540         return 0
9541 }
9542
9543 test_101g() {
9544         remote_ost_nodsh && skip "remote OST with nodsh"
9545
9546         local rpcs
9547         local osts=$(get_facets OST)
9548         local list=$(comma_list $(osts_nodes))
9549         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9550         local brw_size="obdfilter.*.brw_size"
9551
9552         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9553
9554         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
9555
9556         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
9557                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
9558                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
9559            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
9560                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
9561                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
9562
9563                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
9564                         suffix="M"
9565
9566                 if [[ $orig_mb -lt 16 ]]; then
9567                         save_lustre_params $osts "$brw_size" > $p
9568                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
9569                                 error "set 16MB RPC size failed"
9570
9571                         echo "remount client to enable new RPC size"
9572                         remount_client $MOUNT || error "remount_client failed"
9573                 fi
9574
9575                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
9576                 # should be able to set brw_size=12, but no rpc_stats for that
9577                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
9578         fi
9579
9580         test_101g_brw_size_test 4 || error "4MB RPC test failed"
9581
9582         if [[ $orig_mb -lt 16 ]]; then
9583                 restore_lustre_params < $p
9584                 remount_client $MOUNT || error "remount_client restore failed"
9585         fi
9586
9587         rm -f $p $DIR/$tfile
9588 }
9589 run_test 101g "Big bulk(4/16 MiB) readahead"
9590
9591 test_101h() {
9592         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9593
9594         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
9595                 error "dd 70M file failed"
9596         echo Cancel LRU locks on lustre client to flush the client cache
9597         cancel_lru_locks osc
9598
9599         echo "Reset readahead stats"
9600         $LCTL set_param -n llite.*.read_ahead_stats 0
9601
9602         echo "Read 10M of data but cross 64M bundary"
9603         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
9604         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9605                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9606         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
9607         rm -f $p $DIR/$tfile
9608 }
9609 run_test 101h "Readahead should cover current read window"
9610
9611 test_101i() {
9612         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
9613                 error "dd 10M file failed"
9614
9615         local max_per_file_mb=$($LCTL get_param -n \
9616                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
9617         cancel_lru_locks osc
9618         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
9619         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
9620                 error "set max_read_ahead_per_file_mb to 1 failed"
9621
9622         echo "Reset readahead stats"
9623         $LCTL set_param llite.*.read_ahead_stats=0
9624
9625         dd if=$DIR/$tfile of=/dev/null bs=2M
9626
9627         $LCTL get_param llite.*.read_ahead_stats
9628         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9629                      awk '/misses/ { print $2 }')
9630         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
9631         rm -f $DIR/$tfile
9632 }
9633 run_test 101i "allow current readahead to exceed reservation"
9634
9635 test_101j() {
9636         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
9637                 error "setstripe $DIR/$tfile failed"
9638         local file_size=$((1048576 * 16))
9639         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9640         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
9641
9642         echo Disable read-ahead
9643         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9644
9645         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
9646         for blk in $PAGE_SIZE 1048576 $file_size; do
9647                 cancel_lru_locks osc
9648                 echo "Reset readahead stats"
9649                 $LCTL set_param -n llite.*.read_ahead_stats=0
9650                 local count=$(($file_size / $blk))
9651                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
9652                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9653                              get_named_value 'failed to fast read' |
9654                              cut -d" " -f1 | calc_total)
9655                 $LCTL get_param -n llite.*.read_ahead_stats
9656                 [ $miss -eq $count ] || error "expected $count got $miss"
9657         done
9658
9659         rm -f $p $DIR/$tfile
9660 }
9661 run_test 101j "A complete read block should be submitted when no RA"
9662
9663 setup_test102() {
9664         test_mkdir $DIR/$tdir
9665         chown $RUNAS_ID $DIR/$tdir
9666         STRIPE_SIZE=65536
9667         STRIPE_OFFSET=1
9668         STRIPE_COUNT=$OSTCOUNT
9669         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
9670
9671         trap cleanup_test102 EXIT
9672         cd $DIR
9673         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
9674         cd $DIR/$tdir
9675         for num in 1 2 3 4; do
9676                 for count in $(seq 1 $STRIPE_COUNT); do
9677                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
9678                                 local size=`expr $STRIPE_SIZE \* $num`
9679                                 local file=file"$num-$idx-$count"
9680                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
9681                         done
9682                 done
9683         done
9684
9685         cd $DIR
9686         $1 tar cf $TMP/f102.tar $tdir --xattrs
9687 }
9688
9689 cleanup_test102() {
9690         trap 0
9691         rm -f $TMP/f102.tar
9692         rm -rf $DIR/d0.sanity/d102
9693 }
9694
9695 test_102a() {
9696         [ "$UID" != 0 ] && skip "must run as root"
9697         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
9698                 skip_env "must have user_xattr"
9699
9700         [ -z "$(which setfattr 2>/dev/null)" ] &&
9701                 skip_env "could not find setfattr"
9702
9703         local testfile=$DIR/$tfile
9704
9705         touch $testfile
9706         echo "set/get xattr..."
9707         setfattr -n trusted.name1 -v value1 $testfile ||
9708                 error "setfattr -n trusted.name1=value1 $testfile failed"
9709         getfattr -n trusted.name1 $testfile 2> /dev/null |
9710           grep "trusted.name1=.value1" ||
9711                 error "$testfile missing trusted.name1=value1"
9712
9713         setfattr -n user.author1 -v author1 $testfile ||
9714                 error "setfattr -n user.author1=author1 $testfile failed"
9715         getfattr -n user.author1 $testfile 2> /dev/null |
9716           grep "user.author1=.author1" ||
9717                 error "$testfile missing trusted.author1=author1"
9718
9719         echo "listxattr..."
9720         setfattr -n trusted.name2 -v value2 $testfile ||
9721                 error "$testfile unable to set trusted.name2"
9722         setfattr -n trusted.name3 -v value3 $testfile ||
9723                 error "$testfile unable to set trusted.name3"
9724         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
9725             grep "trusted.name" | wc -l) -eq 3 ] ||
9726                 error "$testfile missing 3 trusted.name xattrs"
9727
9728         setfattr -n user.author2 -v author2 $testfile ||
9729                 error "$testfile unable to set user.author2"
9730         setfattr -n user.author3 -v author3 $testfile ||
9731                 error "$testfile unable to set user.author3"
9732         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
9733             grep "user.author" | wc -l) -eq 3 ] ||
9734                 error "$testfile missing 3 user.author xattrs"
9735
9736         echo "remove xattr..."
9737         setfattr -x trusted.name1 $testfile ||
9738                 error "$testfile error deleting trusted.name1"
9739         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
9740                 error "$testfile did not delete trusted.name1 xattr"
9741
9742         setfattr -x user.author1 $testfile ||
9743                 error "$testfile error deleting user.author1"
9744         echo "set lustre special xattr ..."
9745         $LFS setstripe -c1 $testfile
9746         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
9747                 awk -F "=" '/trusted.lov/ { print $2 }' )
9748         setfattr -n "trusted.lov" -v $lovea $testfile ||
9749                 error "$testfile doesn't ignore setting trusted.lov again"
9750         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
9751                 error "$testfile allow setting invalid trusted.lov"
9752         rm -f $testfile
9753 }
9754 run_test 102a "user xattr test =================================="
9755
9756 check_102b_layout() {
9757         local layout="$*"
9758         local testfile=$DIR/$tfile
9759
9760         echo "test layout '$layout'"
9761         $LFS setstripe $layout $testfile || error "setstripe failed"
9762         $LFS getstripe -y $testfile
9763
9764         echo "get/set/list trusted.lov xattr ..." # b=10930
9765         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
9766         [[ "$value" =~ "trusted.lov" ]] ||
9767                 error "can't get trusted.lov from $testfile"
9768         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
9769                 error "getstripe failed"
9770
9771         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
9772
9773         value=$(cut -d= -f2 <<<$value)
9774         # LU-13168: truncated xattr should fail if short lov_user_md header
9775         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
9776                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
9777         for len in $lens; do
9778                 echo "setfattr $len $testfile.2"
9779                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
9780                         [ $len -lt 66 ] && error "short xattr len=$len worked"
9781         done
9782         local stripe_size=$($LFS getstripe -S $testfile.2)
9783         local stripe_count=$($LFS getstripe -c $testfile.2)
9784         [[ $stripe_size -eq 65536 ]] ||
9785                 error "stripe size $stripe_size != 65536"
9786         [[ $stripe_count -eq $stripe_count_orig ]] ||
9787                 error "stripe count $stripe_count != $stripe_count_orig"
9788         rm $testfile $testfile.2
9789 }
9790
9791 test_102b() {
9792         [ -z "$(which setfattr 2>/dev/null)" ] &&
9793                 skip_env "could not find setfattr"
9794         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9795
9796         # check plain layout
9797         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
9798
9799         # and also check composite layout
9800         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
9801
9802 }
9803 run_test 102b "getfattr/setfattr for trusted.lov EAs"
9804
9805 test_102c() {
9806         [ -z "$(which setfattr 2>/dev/null)" ] &&
9807                 skip_env "could not find setfattr"
9808         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9809
9810         # b10930: get/set/list lustre.lov xattr
9811         echo "get/set/list lustre.lov xattr ..."
9812         test_mkdir $DIR/$tdir
9813         chown $RUNAS_ID $DIR/$tdir
9814         local testfile=$DIR/$tdir/$tfile
9815         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
9816                 error "setstripe failed"
9817         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
9818                 error "getstripe failed"
9819         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
9820         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
9821
9822         local testfile2=${testfile}2
9823         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
9824                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
9825
9826         $RUNAS $MCREATE $testfile2
9827         $RUNAS setfattr -n lustre.lov -v $value $testfile2
9828         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
9829         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
9830         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
9831         [ $stripe_count -eq $STRIPECOUNT ] ||
9832                 error "stripe count $stripe_count != $STRIPECOUNT"
9833 }
9834 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
9835
9836 compare_stripe_info1() {
9837         local stripe_index_all_zero=true
9838
9839         for num in 1 2 3 4; do
9840                 for count in $(seq 1 $STRIPE_COUNT); do
9841                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
9842                                 local size=$((STRIPE_SIZE * num))
9843                                 local file=file"$num-$offset-$count"
9844                                 stripe_size=$($LFS getstripe -S $PWD/$file)
9845                                 [[ $stripe_size -ne $size ]] &&
9846                                     error "$file: size $stripe_size != $size"
9847                                 stripe_count=$($LFS getstripe -c $PWD/$file)
9848                                 # allow fewer stripes to be created, ORI-601
9849                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
9850                                     error "$file: count $stripe_count != $count"
9851                                 stripe_index=$($LFS getstripe -i $PWD/$file)
9852                                 [[ $stripe_index -ne 0 ]] &&
9853                                         stripe_index_all_zero=false
9854                         done
9855                 done
9856         done
9857         $stripe_index_all_zero &&
9858                 error "all files are being extracted starting from OST index 0"
9859         return 0
9860 }
9861
9862 have_xattrs_include() {
9863         tar --help | grep -q xattrs-include &&
9864                 echo --xattrs-include="lustre.*"
9865 }
9866
9867 test_102d() {
9868         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9869         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9870
9871         XINC=$(have_xattrs_include)
9872         setup_test102
9873         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
9874         cd $DIR/$tdir/$tdir
9875         compare_stripe_info1
9876 }
9877 run_test 102d "tar restore stripe info from tarfile,not keep osts"
9878
9879 test_102f() {
9880         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9881         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9882
9883         XINC=$(have_xattrs_include)
9884         setup_test102
9885         test_mkdir $DIR/$tdir.restore
9886         cd $DIR
9887         tar cf - --xattrs $tdir | tar xf - \
9888                 -C $DIR/$tdir.restore --xattrs $XINC
9889         cd $DIR/$tdir.restore/$tdir
9890         compare_stripe_info1
9891 }
9892 run_test 102f "tar copy files, not keep osts"
9893
9894 grow_xattr() {
9895         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
9896                 skip "must have user_xattr"
9897         [ -z "$(which setfattr 2>/dev/null)" ] &&
9898                 skip_env "could not find setfattr"
9899         [ -z "$(which getfattr 2>/dev/null)" ] &&
9900                 skip_env "could not find getfattr"
9901
9902         local xsize=${1:-1024}  # in bytes
9903         local file=$DIR/$tfile
9904         local value="$(generate_string $xsize)"
9905         local xbig=trusted.big
9906         local toobig=$2
9907
9908         touch $file
9909         log "save $xbig on $file"
9910         if [ -z "$toobig" ]
9911         then
9912                 setfattr -n $xbig -v $value $file ||
9913                         error "saving $xbig on $file failed"
9914         else
9915                 setfattr -n $xbig -v $value $file &&
9916                         error "saving $xbig on $file succeeded"
9917                 return 0
9918         fi
9919
9920         local orig=$(get_xattr_value $xbig $file)
9921         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
9922
9923         local xsml=trusted.sml
9924         log "save $xsml on $file"
9925         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
9926
9927         local new=$(get_xattr_value $xbig $file)
9928         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
9929
9930         log "grow $xsml on $file"
9931         setfattr -n $xsml -v "$value" $file ||
9932                 error "growing $xsml on $file failed"
9933
9934         new=$(get_xattr_value $xbig $file)
9935         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
9936         log "$xbig still valid after growing $xsml"
9937
9938         rm -f $file
9939 }
9940
9941 test_102h() { # bug 15777
9942         grow_xattr 1024
9943 }
9944 run_test 102h "grow xattr from inside inode to external block"
9945
9946 test_102ha() {
9947         large_xattr_enabled || skip_env "ea_inode feature disabled"
9948
9949         echo "setting xattr of max xattr size: $(max_xattr_size)"
9950         grow_xattr $(max_xattr_size)
9951
9952         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
9953         echo "This should fail:"
9954         grow_xattr $(($(max_xattr_size) + 10)) 1
9955 }
9956 run_test 102ha "grow xattr from inside inode to external inode"
9957
9958 test_102i() { # bug 17038
9959         [ -z "$(which getfattr 2>/dev/null)" ] &&
9960                 skip "could not find getfattr"
9961
9962         touch $DIR/$tfile
9963         ln -s $DIR/$tfile $DIR/${tfile}link
9964         getfattr -n trusted.lov $DIR/$tfile ||
9965                 error "lgetxattr on $DIR/$tfile failed"
9966         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
9967                 grep -i "no such attr" ||
9968                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
9969         rm -f $DIR/$tfile $DIR/${tfile}link
9970 }
9971 run_test 102i "lgetxattr test on symbolic link ============"
9972
9973 test_102j() {
9974         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9975         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9976
9977         XINC=$(have_xattrs_include)
9978         setup_test102 "$RUNAS"
9979         chown $RUNAS_ID $DIR/$tdir
9980         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
9981         cd $DIR/$tdir/$tdir
9982         compare_stripe_info1 "$RUNAS"
9983 }
9984 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
9985
9986 test_102k() {
9987         [ -z "$(which setfattr 2>/dev/null)" ] &&
9988                 skip "could not find setfattr"
9989
9990         touch $DIR/$tfile
9991         # b22187 just check that does not crash for regular file.
9992         setfattr -n trusted.lov $DIR/$tfile
9993         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
9994         local test_kdir=$DIR/$tdir
9995         test_mkdir $test_kdir
9996         local default_size=$($LFS getstripe -S $test_kdir)
9997         local default_count=$($LFS getstripe -c $test_kdir)
9998         local default_offset=$($LFS getstripe -i $test_kdir)
9999         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
10000                 error 'dir setstripe failed'
10001         setfattr -n trusted.lov $test_kdir
10002         local stripe_size=$($LFS getstripe -S $test_kdir)
10003         local stripe_count=$($LFS getstripe -c $test_kdir)
10004         local stripe_offset=$($LFS getstripe -i $test_kdir)
10005         [ $stripe_size -eq $default_size ] ||
10006                 error "stripe size $stripe_size != $default_size"
10007         [ $stripe_count -eq $default_count ] ||
10008                 error "stripe count $stripe_count != $default_count"
10009         [ $stripe_offset -eq $default_offset ] ||
10010                 error "stripe offset $stripe_offset != $default_offset"
10011         rm -rf $DIR/$tfile $test_kdir
10012 }
10013 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
10014
10015 test_102l() {
10016         [ -z "$(which getfattr 2>/dev/null)" ] &&
10017                 skip "could not find getfattr"
10018
10019         # LU-532 trusted. xattr is invisible to non-root
10020         local testfile=$DIR/$tfile
10021
10022         touch $testfile
10023
10024         echo "listxattr as user..."
10025         chown $RUNAS_ID $testfile
10026         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
10027             grep -q "trusted" &&
10028                 error "$testfile trusted xattrs are user visible"
10029
10030         return 0;
10031 }
10032 run_test 102l "listxattr size test =================================="
10033
10034 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
10035         local path=$DIR/$tfile
10036         touch $path
10037
10038         listxattr_size_check $path || error "listattr_size_check $path failed"
10039 }
10040 run_test 102m "Ensure listxattr fails on small bufffer ========"
10041
10042 cleanup_test102
10043
10044 getxattr() { # getxattr path name
10045         # Return the base64 encoding of the value of xattr name on path.
10046         local path=$1
10047         local name=$2
10048
10049         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
10050         # file: $path
10051         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10052         #
10053         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10054
10055         getfattr --absolute-names --encoding=base64 --name=$name $path |
10056                 awk -F= -v name=$name '$1 == name {
10057                         print substr($0, index($0, "=") + 1);
10058         }'
10059 }
10060
10061 test_102n() { # LU-4101 mdt: protect internal xattrs
10062         [ -z "$(which setfattr 2>/dev/null)" ] &&
10063                 skip "could not find setfattr"
10064         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
10065         then
10066                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
10067         fi
10068
10069         local file0=$DIR/$tfile.0
10070         local file1=$DIR/$tfile.1
10071         local xattr0=$TMP/$tfile.0
10072         local xattr1=$TMP/$tfile.1
10073         local namelist="lov lma lmv link fid version som hsm"
10074         local name
10075         local value
10076
10077         rm -rf $file0 $file1 $xattr0 $xattr1
10078         touch $file0 $file1
10079
10080         # Get 'before' xattrs of $file1.
10081         getfattr --absolute-names --dump --match=- $file1 > $xattr0
10082
10083         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
10084                 namelist+=" lfsck_namespace"
10085         for name in $namelist; do
10086                 # Try to copy xattr from $file0 to $file1.
10087                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10088
10089                 setfattr --name=trusted.$name --value="$value" $file1 ||
10090                         error "setxattr 'trusted.$name' failed"
10091
10092                 # Try to set a garbage xattr.
10093                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10094
10095                 if [[ x$name == "xlov" ]]; then
10096                         setfattr --name=trusted.lov --value="$value" $file1 &&
10097                         error "setxattr invalid 'trusted.lov' success"
10098                 else
10099                         setfattr --name=trusted.$name --value="$value" $file1 ||
10100                                 error "setxattr invalid 'trusted.$name' failed"
10101                 fi
10102
10103                 # Try to remove the xattr from $file1. We don't care if this
10104                 # appears to succeed or fail, we just don't want there to be
10105                 # any changes or crashes.
10106                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10107         done
10108
10109         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
10110         then
10111                 name="lfsck_ns"
10112                 # Try to copy xattr from $file0 to $file1.
10113                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10114
10115                 setfattr --name=trusted.$name --value="$value" $file1 ||
10116                         error "setxattr 'trusted.$name' failed"
10117
10118                 # Try to set a garbage xattr.
10119                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10120
10121                 setfattr --name=trusted.$name --value="$value" $file1 ||
10122                         error "setxattr 'trusted.$name' failed"
10123
10124                 # Try to remove the xattr from $file1. We don't care if this
10125                 # appears to succeed or fail, we just don't want there to be
10126                 # any changes or crashes.
10127                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10128         fi
10129
10130         # Get 'after' xattrs of file1.
10131         getfattr --absolute-names --dump --match=- $file1 > $xattr1
10132
10133         if ! diff $xattr0 $xattr1; then
10134                 error "before and after xattrs of '$file1' differ"
10135         fi
10136
10137         rm -rf $file0 $file1 $xattr0 $xattr1
10138
10139         return 0
10140 }
10141 run_test 102n "silently ignore setxattr on internal trusted xattrs"
10142
10143 test_102p() { # LU-4703 setxattr did not check ownership
10144         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
10145                 skip "MDS needs to be at least 2.5.56"
10146
10147         local testfile=$DIR/$tfile
10148
10149         touch $testfile
10150
10151         echo "setfacl as user..."
10152         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
10153         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
10154
10155         echo "setfattr as user..."
10156         setfacl -m "u:$RUNAS_ID:---" $testfile
10157         $RUNAS setfattr -x system.posix_acl_access $testfile
10158         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
10159 }
10160 run_test 102p "check setxattr(2) correctly fails without permission"
10161
10162 test_102q() {
10163         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
10164                 skip "MDS needs to be at least 2.6.92"
10165
10166         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
10167 }
10168 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
10169
10170 test_102r() {
10171         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
10172                 skip "MDS needs to be at least 2.6.93"
10173
10174         touch $DIR/$tfile || error "touch"
10175         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
10176         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
10177         rm $DIR/$tfile || error "rm"
10178
10179         #normal directory
10180         mkdir -p $DIR/$tdir || error "mkdir"
10181         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10182         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10183         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10184                 error "$testfile error deleting user.author1"
10185         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10186                 grep "user.$(basename $tdir)" &&
10187                 error "$tdir did not delete user.$(basename $tdir)"
10188         rmdir $DIR/$tdir || error "rmdir"
10189
10190         #striped directory
10191         test_mkdir $DIR/$tdir
10192         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10193         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10194         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10195                 error "$testfile error deleting user.author1"
10196         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10197                 grep "user.$(basename $tdir)" &&
10198                 error "$tdir did not delete user.$(basename $tdir)"
10199         rmdir $DIR/$tdir || error "rm striped dir"
10200 }
10201 run_test 102r "set EAs with empty values"
10202
10203 test_102s() {
10204         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10205                 skip "MDS needs to be at least 2.11.52"
10206
10207         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10208
10209         save_lustre_params client "llite.*.xattr_cache" > $save
10210
10211         for cache in 0 1; do
10212                 lctl set_param llite.*.xattr_cache=$cache
10213
10214                 rm -f $DIR/$tfile
10215                 touch $DIR/$tfile || error "touch"
10216                 for prefix in lustre security system trusted user; do
10217                         # Note getxattr() may fail with 'Operation not
10218                         # supported' or 'No such attribute' depending
10219                         # on prefix and cache.
10220                         getfattr -n $prefix.n102s $DIR/$tfile &&
10221                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
10222                 done
10223         done
10224
10225         restore_lustre_params < $save
10226 }
10227 run_test 102s "getting nonexistent xattrs should fail"
10228
10229 test_102t() {
10230         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10231                 skip "MDS needs to be at least 2.11.52"
10232
10233         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10234
10235         save_lustre_params client "llite.*.xattr_cache" > $save
10236
10237         for cache in 0 1; do
10238                 lctl set_param llite.*.xattr_cache=$cache
10239
10240                 for buf_size in 0 256; do
10241                         rm -f $DIR/$tfile
10242                         touch $DIR/$tfile || error "touch"
10243                         setfattr -n user.multiop $DIR/$tfile
10244                         $MULTIOP $DIR/$tfile oa$buf_size ||
10245                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
10246                 done
10247         done
10248
10249         restore_lustre_params < $save
10250 }
10251 run_test 102t "zero length xattr values handled correctly"
10252
10253 run_acl_subtest()
10254 {
10255     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
10256     return $?
10257 }
10258
10259 test_103a() {
10260         [ "$UID" != 0 ] && skip "must run as root"
10261         $GSS && skip_env "could not run under gss"
10262         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
10263                 skip_env "must have acl enabled"
10264         [ -z "$(which setfacl 2>/dev/null)" ] &&
10265                 skip_env "could not find setfacl"
10266         remote_mds_nodsh && skip "remote MDS with nodsh"
10267
10268         gpasswd -a daemon bin                           # LU-5641
10269         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
10270
10271         declare -a identity_old
10272
10273         for num in $(seq $MDSCOUNT); do
10274                 switch_identity $num true || identity_old[$num]=$?
10275         done
10276
10277         SAVE_UMASK=$(umask)
10278         umask 0022
10279         mkdir -p $DIR/$tdir
10280         cd $DIR/$tdir
10281
10282         echo "performing cp ..."
10283         run_acl_subtest cp || error "run_acl_subtest cp failed"
10284         echo "performing getfacl-noacl..."
10285         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
10286         echo "performing misc..."
10287         run_acl_subtest misc || error  "misc test failed"
10288         echo "performing permissions..."
10289         run_acl_subtest permissions || error "permissions failed"
10290         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
10291         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
10292                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
10293                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
10294         then
10295                 echo "performing permissions xattr..."
10296                 run_acl_subtest permissions_xattr ||
10297                         error "permissions_xattr failed"
10298         fi
10299         echo "performing setfacl..."
10300         run_acl_subtest setfacl || error  "setfacl test failed"
10301
10302         # inheritance test got from HP
10303         echo "performing inheritance..."
10304         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
10305         chmod +x make-tree || error "chmod +x failed"
10306         run_acl_subtest inheritance || error "inheritance test failed"
10307         rm -f make-tree
10308
10309         echo "LU-974 ignore umask when acl is enabled..."
10310         run_acl_subtest 974 || error "LU-974 umask test failed"
10311         if [ $MDSCOUNT -ge 2 ]; then
10312                 run_acl_subtest 974_remote ||
10313                         error "LU-974 umask test failed under remote dir"
10314         fi
10315
10316         echo "LU-2561 newly created file is same size as directory..."
10317         if [ "$mds1_FSTYPE" != "zfs" ]; then
10318                 run_acl_subtest 2561 || error "LU-2561 test failed"
10319         else
10320                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
10321         fi
10322
10323         run_acl_subtest 4924 || error "LU-4924 test failed"
10324
10325         cd $SAVE_PWD
10326         umask $SAVE_UMASK
10327
10328         for num in $(seq $MDSCOUNT); do
10329                 if [ "${identity_old[$num]}" = 1 ]; then
10330                         switch_identity $num false || identity_old[$num]=$?
10331                 fi
10332         done
10333 }
10334 run_test 103a "acl test"
10335
10336 test_103b() {
10337         declare -a pids
10338         local U
10339
10340         for U in {0..511}; do
10341                 {
10342                 local O=$(printf "%04o" $U)
10343
10344                 umask $(printf "%04o" $((511 ^ $O)))
10345                 $LFS setstripe -c 1 $DIR/$tfile.s$O
10346                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
10347
10348                 (( $S == ($O & 0666) )) ||
10349                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
10350
10351                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
10352                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
10353                 (( $S == ($O & 0666) )) ||
10354                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
10355
10356                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
10357                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
10358                 (( $S == ($O & 0666) )) ||
10359                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
10360                 rm -f $DIR/$tfile.[smp]$0
10361                 } &
10362                 local pid=$!
10363
10364                 # limit the concurrently running threads to 64. LU-11878
10365                 local idx=$((U % 64))
10366                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
10367                 pids[idx]=$pid
10368         done
10369         wait
10370 }
10371 run_test 103b "umask lfs setstripe"
10372
10373 test_103c() {
10374         mkdir -p $DIR/$tdir
10375         cp -rp $DIR/$tdir $DIR/$tdir.bak
10376
10377         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
10378                 error "$DIR/$tdir shouldn't contain default ACL"
10379         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
10380                 error "$DIR/$tdir.bak shouldn't contain default ACL"
10381         true
10382 }
10383 run_test 103c "'cp -rp' won't set empty acl"
10384
10385 test_104a() {
10386         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10387
10388         touch $DIR/$tfile
10389         lfs df || error "lfs df failed"
10390         lfs df -ih || error "lfs df -ih failed"
10391         lfs df -h $DIR || error "lfs df -h $DIR failed"
10392         lfs df -i $DIR || error "lfs df -i $DIR failed"
10393         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
10394         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
10395
10396         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
10397         lctl --device %$OSC deactivate
10398         lfs df || error "lfs df with deactivated OSC failed"
10399         lctl --device %$OSC activate
10400         # wait the osc back to normal
10401         wait_osc_import_ready client ost
10402
10403         lfs df || error "lfs df with reactivated OSC failed"
10404         rm -f $DIR/$tfile
10405 }
10406 run_test 104a "lfs df [-ih] [path] test ========================="
10407
10408 test_104b() {
10409         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10410         [ $RUNAS_ID -eq $UID ] &&
10411                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10412
10413         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
10414                         grep "Permission denied" | wc -l)))
10415         if [ $denied_cnt -ne 0 ]; then
10416                 error "lfs check servers test failed"
10417         fi
10418 }
10419 run_test 104b "$RUNAS lfs check servers test ===================="
10420
10421 test_105a() {
10422         # doesn't work on 2.4 kernels
10423         touch $DIR/$tfile
10424         if $(flock_is_enabled); then
10425                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
10426         else
10427                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
10428         fi
10429         rm -f $DIR/$tfile
10430 }
10431 run_test 105a "flock when mounted without -o flock test ========"
10432
10433 test_105b() {
10434         touch $DIR/$tfile
10435         if $(flock_is_enabled); then
10436                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
10437         else
10438                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
10439         fi
10440         rm -f $DIR/$tfile
10441 }
10442 run_test 105b "fcntl when mounted without -o flock test ========"
10443
10444 test_105c() {
10445         touch $DIR/$tfile
10446         if $(flock_is_enabled); then
10447                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
10448         else
10449                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
10450         fi
10451         rm -f $DIR/$tfile
10452 }
10453 run_test 105c "lockf when mounted without -o flock test"
10454
10455 test_105d() { # bug 15924
10456         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10457
10458         test_mkdir $DIR/$tdir
10459         flock_is_enabled || skip_env "mount w/o flock enabled"
10460         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
10461         $LCTL set_param fail_loc=0x80000315
10462         flocks_test 2 $DIR/$tdir
10463 }
10464 run_test 105d "flock race (should not freeze) ========"
10465
10466 test_105e() { # bug 22660 && 22040
10467         flock_is_enabled || skip_env "mount w/o flock enabled"
10468
10469         touch $DIR/$tfile
10470         flocks_test 3 $DIR/$tfile
10471 }
10472 run_test 105e "Two conflicting flocks from same process"
10473
10474 test_106() { #bug 10921
10475         test_mkdir $DIR/$tdir
10476         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
10477         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
10478 }
10479 run_test 106 "attempt exec of dir followed by chown of that dir"
10480
10481 test_107() {
10482         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10483
10484         CDIR=`pwd`
10485         local file=core
10486
10487         cd $DIR
10488         rm -f $file
10489
10490         local save_pattern=$(sysctl -n kernel.core_pattern)
10491         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
10492         sysctl -w kernel.core_pattern=$file
10493         sysctl -w kernel.core_uses_pid=0
10494
10495         ulimit -c unlimited
10496         sleep 60 &
10497         SLEEPPID=$!
10498
10499         sleep 1
10500
10501         kill -s 11 $SLEEPPID
10502         wait $SLEEPPID
10503         if [ -e $file ]; then
10504                 size=`stat -c%s $file`
10505                 [ $size -eq 0 ] && error "Fail to create core file $file"
10506         else
10507                 error "Fail to create core file $file"
10508         fi
10509         rm -f $file
10510         sysctl -w kernel.core_pattern=$save_pattern
10511         sysctl -w kernel.core_uses_pid=$save_uses_pid
10512         cd $CDIR
10513 }
10514 run_test 107 "Coredump on SIG"
10515
10516 test_110() {
10517         test_mkdir $DIR/$tdir
10518         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
10519         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
10520                 error "mkdir with 256 char should fail, but did not"
10521         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
10522                 error "create with 255 char failed"
10523         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
10524                 error "create with 256 char should fail, but did not"
10525
10526         ls -l $DIR/$tdir
10527         rm -rf $DIR/$tdir
10528 }
10529 run_test 110 "filename length checking"
10530
10531 #
10532 # Purpose: To verify dynamic thread (OSS) creation.
10533 #
10534 test_115() {
10535         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10536         remote_ost_nodsh && skip "remote OST with nodsh"
10537
10538         # Lustre does not stop service threads once they are started.
10539         # Reset number of running threads to default.
10540         stopall
10541         setupall
10542
10543         local OSTIO_pre
10544         local save_params="$TMP/sanity-$TESTNAME.parameters"
10545
10546         # Get ll_ost_io count before I/O
10547         OSTIO_pre=$(do_facet ost1 \
10548                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
10549         # Exit if lustre is not running (ll_ost_io not running).
10550         [ -z "$OSTIO_pre" ] && error "no OSS threads"
10551
10552         echo "Starting with $OSTIO_pre threads"
10553         local thread_max=$((OSTIO_pre * 2))
10554         local rpc_in_flight=$((thread_max * 2))
10555         # Number of I/O Process proposed to be started.
10556         local nfiles
10557         local facets=$(get_facets OST)
10558
10559         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
10560         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
10561
10562         # Set in_flight to $rpc_in_flight
10563         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
10564                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
10565         nfiles=${rpc_in_flight}
10566         # Set ost thread_max to $thread_max
10567         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
10568
10569         # 5 Minutes should be sufficient for max number of OSS
10570         # threads(thread_max) to be created.
10571         local timeout=300
10572
10573         # Start I/O.
10574         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
10575         test_mkdir $DIR/$tdir
10576         for i in $(seq $nfiles); do
10577                 local file=$DIR/$tdir/${tfile}-$i
10578                 $LFS setstripe -c -1 -i 0 $file
10579                 ($WTL $file $timeout)&
10580         done
10581
10582         # I/O Started - Wait for thread_started to reach thread_max or report
10583         # error if thread_started is more than thread_max.
10584         echo "Waiting for thread_started to reach thread_max"
10585         local thread_started=0
10586         local end_time=$((SECONDS + timeout))
10587
10588         while [ $SECONDS -le $end_time ] ; do
10589                 echo -n "."
10590                 # Get ost i/o thread_started count.
10591                 thread_started=$(do_facet ost1 \
10592                         "$LCTL get_param \
10593                         ost.OSS.ost_io.threads_started | cut -d= -f2")
10594                 # Break out if thread_started is equal/greater than thread_max
10595                 if [[ $thread_started -ge $thread_max ]]; then
10596                         echo ll_ost_io thread_started $thread_started, \
10597                                 equal/greater than thread_max $thread_max
10598                         break
10599                 fi
10600                 sleep 1
10601         done
10602
10603         # Cleanup - We have the numbers, Kill i/o jobs if running.
10604         jobcount=($(jobs -p))
10605         for i in $(seq 0 $((${#jobcount[@]}-1)))
10606         do
10607                 kill -9 ${jobcount[$i]}
10608                 if [ $? -ne 0 ] ; then
10609                         echo Warning: \
10610                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
10611                 fi
10612         done
10613
10614         # Cleanup files left by WTL binary.
10615         for i in $(seq $nfiles); do
10616                 local file=$DIR/$tdir/${tfile}-$i
10617                 rm -rf $file
10618                 if [ $? -ne 0 ] ; then
10619                         echo "Warning: Failed to delete file $file"
10620                 fi
10621         done
10622
10623         restore_lustre_params <$save_params
10624         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
10625
10626         # Error out if no new thread has started or Thread started is greater
10627         # than thread max.
10628         if [[ $thread_started -le $OSTIO_pre ||
10629                         $thread_started -gt $thread_max ]]; then
10630                 error "ll_ost_io: thread_started $thread_started" \
10631                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
10632                       "No new thread started or thread started greater " \
10633                       "than thread_max."
10634         fi
10635 }
10636 run_test 115 "verify dynamic thread creation===================="
10637
10638 free_min_max () {
10639         wait_delete_completed
10640         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
10641         echo "OST kbytes available: ${AVAIL[@]}"
10642         MAXV=${AVAIL[0]}
10643         MAXI=0
10644         MINV=${AVAIL[0]}
10645         MINI=0
10646         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
10647                 #echo OST $i: ${AVAIL[i]}kb
10648                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
10649                         MAXV=${AVAIL[i]}
10650                         MAXI=$i
10651                 fi
10652                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
10653                         MINV=${AVAIL[i]}
10654                         MINI=$i
10655                 fi
10656         done
10657         echo "Min free space: OST $MINI: $MINV"
10658         echo "Max free space: OST $MAXI: $MAXV"
10659 }
10660
10661 test_116a() { # was previously test_116()
10662         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10663         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10664         remote_mds_nodsh && skip "remote MDS with nodsh"
10665
10666         echo -n "Free space priority "
10667         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
10668                 head -n1
10669         declare -a AVAIL
10670         free_min_max
10671
10672         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
10673         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
10674         trap simple_cleanup_common EXIT
10675
10676         # Check if we need to generate uneven OSTs
10677         test_mkdir -p $DIR/$tdir/OST${MINI}
10678         local FILL=$((MINV / 4))
10679         local DIFF=$((MAXV - MINV))
10680         local DIFF2=$((DIFF * 100 / MINV))
10681
10682         local threshold=$(do_facet $SINGLEMDS \
10683                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
10684         threshold=${threshold%%%}
10685         echo -n "Check for uneven OSTs: "
10686         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
10687
10688         if [[ $DIFF2 -gt $threshold ]]; then
10689                 echo "ok"
10690                 echo "Don't need to fill OST$MINI"
10691         else
10692                 # generate uneven OSTs. Write 2% over the QOS threshold value
10693                 echo "no"
10694                 DIFF=$((threshold - DIFF2 + 2))
10695                 DIFF2=$((MINV * DIFF / 100))
10696                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
10697                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
10698                         error "setstripe failed"
10699                 DIFF=$((DIFF2 / 2048))
10700                 i=0
10701                 while [ $i -lt $DIFF ]; do
10702                         i=$((i + 1))
10703                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
10704                                 bs=2M count=1 2>/dev/null
10705                         echo -n .
10706                 done
10707                 echo .
10708                 sync
10709                 sleep_maxage
10710                 free_min_max
10711         fi
10712
10713         DIFF=$((MAXV - MINV))
10714         DIFF2=$((DIFF * 100 / MINV))
10715         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
10716         if [ $DIFF2 -gt $threshold ]; then
10717                 echo "ok"
10718         else
10719                 echo "failed - QOS mode won't be used"
10720                 simple_cleanup_common
10721                 skip "QOS imbalance criteria not met"
10722         fi
10723
10724         MINI1=$MINI
10725         MINV1=$MINV
10726         MAXI1=$MAXI
10727         MAXV1=$MAXV
10728
10729         # now fill using QOS
10730         $LFS setstripe -c 1 $DIR/$tdir
10731         FILL=$((FILL / 200))
10732         if [ $FILL -gt 600 ]; then
10733                 FILL=600
10734         fi
10735         echo "writing $FILL files to QOS-assigned OSTs"
10736         i=0
10737         while [ $i -lt $FILL ]; do
10738                 i=$((i + 1))
10739                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
10740                         count=1 2>/dev/null
10741                 echo -n .
10742         done
10743         echo "wrote $i 200k files"
10744         sync
10745         sleep_maxage
10746
10747         echo "Note: free space may not be updated, so measurements might be off"
10748         free_min_max
10749         DIFF2=$((MAXV - MINV))
10750         echo "free space delta: orig $DIFF final $DIFF2"
10751         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
10752         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
10753         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
10754         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
10755         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
10756         if [[ $DIFF -gt 0 ]]; then
10757                 FILL=$((DIFF2 * 100 / DIFF - 100))
10758                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
10759         fi
10760
10761         # Figure out which files were written where
10762         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10763                awk '/'$MINI1': / {print $2; exit}')
10764         echo $UUID
10765         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10766         echo "$MINC files created on smaller OST $MINI1"
10767         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10768                awk '/'$MAXI1': / {print $2; exit}')
10769         echo $UUID
10770         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10771         echo "$MAXC files created on larger OST $MAXI1"
10772         if [[ $MINC -gt 0 ]]; then
10773                 FILL=$((MAXC * 100 / MINC - 100))
10774                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
10775         fi
10776         [[ $MAXC -gt $MINC ]] ||
10777                 error_ignore LU-9 "stripe QOS didn't balance free space"
10778         simple_cleanup_common
10779 }
10780 run_test 116a "stripe QOS: free space balance ==================="
10781
10782 test_116b() { # LU-2093
10783         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10784         remote_mds_nodsh && skip "remote MDS with nodsh"
10785
10786 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
10787         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
10788                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
10789         [ -z "$old_rr" ] && skip "no QOS"
10790         do_facet $SINGLEMDS lctl set_param \
10791                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
10792         mkdir -p $DIR/$tdir
10793         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
10794         createmany -o $DIR/$tdir/f- 20 || error "can't create"
10795         do_facet $SINGLEMDS lctl set_param fail_loc=0
10796         rm -rf $DIR/$tdir
10797         do_facet $SINGLEMDS lctl set_param \
10798                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
10799 }
10800 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
10801
10802 test_117() # bug 10891
10803 {
10804         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10805
10806         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
10807         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
10808         lctl set_param fail_loc=0x21e
10809         > $DIR/$tfile || error "truncate failed"
10810         lctl set_param fail_loc=0
10811         echo "Truncate succeeded."
10812         rm -f $DIR/$tfile
10813 }
10814 run_test 117 "verify osd extend =========="
10815
10816 NO_SLOW_RESENDCOUNT=4
10817 export OLD_RESENDCOUNT=""
10818 set_resend_count () {
10819         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
10820         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
10821         lctl set_param -n $PROC_RESENDCOUNT $1
10822         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
10823 }
10824
10825 # for reduce test_118* time (b=14842)
10826 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
10827
10828 # Reset async IO behavior after error case
10829 reset_async() {
10830         FILE=$DIR/reset_async
10831
10832         # Ensure all OSCs are cleared
10833         $LFS setstripe -c -1 $FILE
10834         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
10835         sync
10836         rm $FILE
10837 }
10838
10839 test_118a() #bug 11710
10840 {
10841         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10842
10843         reset_async
10844
10845         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10846         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10847         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10848
10849         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10850                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10851                 return 1;
10852         fi
10853         rm -f $DIR/$tfile
10854 }
10855 run_test 118a "verify O_SYNC works =========="
10856
10857 test_118b()
10858 {
10859         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10860         remote_ost_nodsh && skip "remote OST with nodsh"
10861
10862         reset_async
10863
10864         #define OBD_FAIL_SRV_ENOENT 0x217
10865         set_nodes_failloc "$(osts_nodes)" 0x217
10866         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10867         RC=$?
10868         set_nodes_failloc "$(osts_nodes)" 0
10869         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10870         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10871                     grep -c writeback)
10872
10873         if [[ $RC -eq 0 ]]; then
10874                 error "Must return error due to dropped pages, rc=$RC"
10875                 return 1;
10876         fi
10877
10878         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10879                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10880                 return 1;
10881         fi
10882
10883         echo "Dirty pages not leaked on ENOENT"
10884
10885         # Due to the above error the OSC will issue all RPCs syncronously
10886         # until a subsequent RPC completes successfully without error.
10887         $MULTIOP $DIR/$tfile Ow4096yc
10888         rm -f $DIR/$tfile
10889
10890         return 0
10891 }
10892 run_test 118b "Reclaim dirty pages on fatal error =========="
10893
10894 test_118c()
10895 {
10896         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10897
10898         # for 118c, restore the original resend count, LU-1940
10899         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
10900                                 set_resend_count $OLD_RESENDCOUNT
10901         remote_ost_nodsh && skip "remote OST with nodsh"
10902
10903         reset_async
10904
10905         #define OBD_FAIL_OST_EROFS               0x216
10906         set_nodes_failloc "$(osts_nodes)" 0x216
10907
10908         # multiop should block due to fsync until pages are written
10909         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10910         MULTIPID=$!
10911         sleep 1
10912
10913         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
10914                 error "Multiop failed to block on fsync, pid=$MULTIPID"
10915         fi
10916
10917         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10918                     grep -c writeback)
10919         if [[ $WRITEBACK -eq 0 ]]; then
10920                 error "No page in writeback, writeback=$WRITEBACK"
10921         fi
10922
10923         set_nodes_failloc "$(osts_nodes)" 0
10924         wait $MULTIPID
10925         RC=$?
10926         if [[ $RC -ne 0 ]]; then
10927                 error "Multiop fsync failed, rc=$RC"
10928         fi
10929
10930         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10931         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10932                     grep -c writeback)
10933         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10934                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10935         fi
10936
10937         rm -f $DIR/$tfile
10938         echo "Dirty pages flushed via fsync on EROFS"
10939         return 0
10940 }
10941 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
10942
10943 # continue to use small resend count to reduce test_118* time (b=14842)
10944 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
10945
10946 test_118d()
10947 {
10948         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10949         remote_ost_nodsh && skip "remote OST with nodsh"
10950
10951         reset_async
10952
10953         #define OBD_FAIL_OST_BRW_PAUSE_BULK
10954         set_nodes_failloc "$(osts_nodes)" 0x214
10955         # multiop should block due to fsync until pages are written
10956         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10957         MULTIPID=$!
10958         sleep 1
10959
10960         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
10961                 error "Multiop failed to block on fsync, pid=$MULTIPID"
10962         fi
10963
10964         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10965                     grep -c writeback)
10966         if [[ $WRITEBACK -eq 0 ]]; then
10967                 error "No page in writeback, writeback=$WRITEBACK"
10968         fi
10969
10970         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
10971         set_nodes_failloc "$(osts_nodes)" 0
10972
10973         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10974         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10975                     grep -c writeback)
10976         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10977                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10978         fi
10979
10980         rm -f $DIR/$tfile
10981         echo "Dirty pages gaurenteed flushed via fsync"
10982         return 0
10983 }
10984 run_test 118d "Fsync validation inject a delay of the bulk =========="
10985
10986 test_118f() {
10987         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10988
10989         reset_async
10990
10991         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
10992         lctl set_param fail_loc=0x8000040a
10993
10994         # Should simulate EINVAL error which is fatal
10995         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10996         RC=$?
10997         if [[ $RC -eq 0 ]]; then
10998                 error "Must return error due to dropped pages, rc=$RC"
10999         fi
11000
11001         lctl set_param fail_loc=0x0
11002
11003         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11004         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11005         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11006                     grep -c writeback)
11007         if [[ $LOCKED -ne 0 ]]; then
11008                 error "Locked pages remain in cache, locked=$LOCKED"
11009         fi
11010
11011         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11012                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11013         fi
11014
11015         rm -f $DIR/$tfile
11016         echo "No pages locked after fsync"
11017
11018         reset_async
11019         return 0
11020 }
11021 run_test 118f "Simulate unrecoverable OSC side error =========="
11022
11023 test_118g() {
11024         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11025
11026         reset_async
11027
11028         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
11029         lctl set_param fail_loc=0x406
11030
11031         # simulate local -ENOMEM
11032         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11033         RC=$?
11034
11035         lctl set_param fail_loc=0
11036         if [[ $RC -eq 0 ]]; then
11037                 error "Must return error due to dropped pages, rc=$RC"
11038         fi
11039
11040         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11041         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11042         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11043                         grep -c writeback)
11044         if [[ $LOCKED -ne 0 ]]; then
11045                 error "Locked pages remain in cache, locked=$LOCKED"
11046         fi
11047
11048         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11049                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11050         fi
11051
11052         rm -f $DIR/$tfile
11053         echo "No pages locked after fsync"
11054
11055         reset_async
11056         return 0
11057 }
11058 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
11059
11060 test_118h() {
11061         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11062         remote_ost_nodsh && skip "remote OST with nodsh"
11063
11064         reset_async
11065
11066         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11067         set_nodes_failloc "$(osts_nodes)" 0x20e
11068         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11069         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11070         RC=$?
11071
11072         set_nodes_failloc "$(osts_nodes)" 0
11073         if [[ $RC -eq 0 ]]; then
11074                 error "Must return error due to dropped pages, rc=$RC"
11075         fi
11076
11077         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11078         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11079         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11080                     grep -c writeback)
11081         if [[ $LOCKED -ne 0 ]]; then
11082                 error "Locked pages remain in cache, locked=$LOCKED"
11083         fi
11084
11085         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11086                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11087         fi
11088
11089         rm -f $DIR/$tfile
11090         echo "No pages locked after fsync"
11091
11092         return 0
11093 }
11094 run_test 118h "Verify timeout in handling recoverables errors  =========="
11095
11096 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11097
11098 test_118i() {
11099         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11100         remote_ost_nodsh && skip "remote OST with nodsh"
11101
11102         reset_async
11103
11104         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11105         set_nodes_failloc "$(osts_nodes)" 0x20e
11106
11107         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11108         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11109         PID=$!
11110         sleep 5
11111         set_nodes_failloc "$(osts_nodes)" 0
11112
11113         wait $PID
11114         RC=$?
11115         if [[ $RC -ne 0 ]]; then
11116                 error "got error, but should be not, rc=$RC"
11117         fi
11118
11119         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11120         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11121         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11122         if [[ $LOCKED -ne 0 ]]; then
11123                 error "Locked pages remain in cache, locked=$LOCKED"
11124         fi
11125
11126         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11127                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11128         fi
11129
11130         rm -f $DIR/$tfile
11131         echo "No pages locked after fsync"
11132
11133         return 0
11134 }
11135 run_test 118i "Fix error before timeout in recoverable error  =========="
11136
11137 [ "$SLOW" = "no" ] && set_resend_count 4
11138
11139 test_118j() {
11140         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11141         remote_ost_nodsh && skip "remote OST with nodsh"
11142
11143         reset_async
11144
11145         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
11146         set_nodes_failloc "$(osts_nodes)" 0x220
11147
11148         # return -EIO from OST
11149         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11150         RC=$?
11151         set_nodes_failloc "$(osts_nodes)" 0x0
11152         if [[ $RC -eq 0 ]]; then
11153                 error "Must return error due to dropped pages, rc=$RC"
11154         fi
11155
11156         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11157         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11158         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11159         if [[ $LOCKED -ne 0 ]]; then
11160                 error "Locked pages remain in cache, locked=$LOCKED"
11161         fi
11162
11163         # in recoverable error on OST we want resend and stay until it finished
11164         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11165                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11166         fi
11167
11168         rm -f $DIR/$tfile
11169         echo "No pages locked after fsync"
11170
11171         return 0
11172 }
11173 run_test 118j "Simulate unrecoverable OST side error =========="
11174
11175 test_118k()
11176 {
11177         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11178         remote_ost_nodsh && skip "remote OSTs with nodsh"
11179
11180         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11181         set_nodes_failloc "$(osts_nodes)" 0x20e
11182         test_mkdir $DIR/$tdir
11183
11184         for ((i=0;i<10;i++)); do
11185                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
11186                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
11187                 SLEEPPID=$!
11188                 sleep 0.500s
11189                 kill $SLEEPPID
11190                 wait $SLEEPPID
11191         done
11192
11193         set_nodes_failloc "$(osts_nodes)" 0
11194         rm -rf $DIR/$tdir
11195 }
11196 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
11197
11198 test_118l() # LU-646
11199 {
11200         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11201
11202         test_mkdir $DIR/$tdir
11203         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
11204         rm -rf $DIR/$tdir
11205 }
11206 run_test 118l "fsync dir"
11207
11208 test_118m() # LU-3066
11209 {
11210         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11211
11212         test_mkdir $DIR/$tdir
11213         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
11214         rm -rf $DIR/$tdir
11215 }
11216 run_test 118m "fdatasync dir ========="
11217
11218 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11219
11220 test_118n()
11221 {
11222         local begin
11223         local end
11224
11225         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11226         remote_ost_nodsh && skip "remote OSTs with nodsh"
11227
11228         # Sleep to avoid a cached response.
11229         #define OBD_STATFS_CACHE_SECONDS 1
11230         sleep 2
11231
11232         # Inject a 10 second delay in the OST_STATFS handler.
11233         #define OBD_FAIL_OST_STATFS_DELAY 0x242
11234         set_nodes_failloc "$(osts_nodes)" 0x242
11235
11236         begin=$SECONDS
11237         stat --file-system $MOUNT > /dev/null
11238         end=$SECONDS
11239
11240         set_nodes_failloc "$(osts_nodes)" 0
11241
11242         if ((end - begin > 20)); then
11243             error "statfs took $((end - begin)) seconds, expected 10"
11244         fi
11245 }
11246 run_test 118n "statfs() sends OST_STATFS requests in parallel"
11247
11248 test_119a() # bug 11737
11249 {
11250         BSIZE=$((512 * 1024))
11251         directio write $DIR/$tfile 0 1 $BSIZE
11252         # We ask to read two blocks, which is more than a file size.
11253         # directio will indicate an error when requested and actual
11254         # sizes aren't equeal (a normal situation in this case) and
11255         # print actual read amount.
11256         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
11257         if [ "$NOB" != "$BSIZE" ]; then
11258                 error "read $NOB bytes instead of $BSIZE"
11259         fi
11260         rm -f $DIR/$tfile
11261 }
11262 run_test 119a "Short directIO read must return actual read amount"
11263
11264 test_119b() # bug 11737
11265 {
11266         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11267
11268         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
11269         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
11270         sync
11271         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
11272                 error "direct read failed"
11273         rm -f $DIR/$tfile
11274 }
11275 run_test 119b "Sparse directIO read must return actual read amount"
11276
11277 test_119c() # bug 13099
11278 {
11279         BSIZE=1048576
11280         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
11281         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
11282         rm -f $DIR/$tfile
11283 }
11284 run_test 119c "Testing for direct read hitting hole"
11285
11286 test_119d() # bug 15950
11287 {
11288         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11289
11290         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
11291         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
11292         BSIZE=1048576
11293         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
11294         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
11295         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
11296         lctl set_param fail_loc=0x40d
11297         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
11298         pid_dio=$!
11299         sleep 1
11300         cat $DIR/$tfile > /dev/null &
11301         lctl set_param fail_loc=0
11302         pid_reads=$!
11303         wait $pid_dio
11304         log "the DIO writes have completed, now wait for the reads (should not block very long)"
11305         sleep 2
11306         [ -n "`ps h -p $pid_reads -o comm`" ] && \
11307         error "the read rpcs have not completed in 2s"
11308         rm -f $DIR/$tfile
11309         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
11310 }
11311 run_test 119d "The DIO path should try to send a new rpc once one is completed"
11312
11313 test_120a() {
11314         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11315         remote_mds_nodsh && skip "remote MDS with nodsh"
11316         test_mkdir -i0 -c1 $DIR/$tdir
11317         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11318                 skip_env "no early lock cancel on server"
11319
11320         lru_resize_disable mdc
11321         lru_resize_disable osc
11322         cancel_lru_locks mdc
11323         # asynchronous object destroy at MDT could cause bl ast to client
11324         cancel_lru_locks osc
11325
11326         stat $DIR/$tdir > /dev/null
11327         can1=$(do_facet mds1 \
11328                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11329                awk '/ldlm_cancel/ {print $2}')
11330         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11331                awk '/ldlm_bl_callback/ {print $2}')
11332         test_mkdir -i0 -c1 $DIR/$tdir/d1
11333         can2=$(do_facet mds1 \
11334                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11335                awk '/ldlm_cancel/ {print $2}')
11336         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11337                awk '/ldlm_bl_callback/ {print $2}')
11338         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11339         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11340         lru_resize_enable mdc
11341         lru_resize_enable osc
11342 }
11343 run_test 120a "Early Lock Cancel: mkdir test"
11344
11345 test_120b() {
11346         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11347         remote_mds_nodsh && skip "remote MDS with nodsh"
11348         test_mkdir $DIR/$tdir
11349         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11350                 skip_env "no early lock cancel on server"
11351
11352         lru_resize_disable mdc
11353         lru_resize_disable osc
11354         cancel_lru_locks mdc
11355         stat $DIR/$tdir > /dev/null
11356         can1=$(do_facet $SINGLEMDS \
11357                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11358                awk '/ldlm_cancel/ {print $2}')
11359         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11360                awk '/ldlm_bl_callback/ {print $2}')
11361         touch $DIR/$tdir/f1
11362         can2=$(do_facet $SINGLEMDS \
11363                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11364                awk '/ldlm_cancel/ {print $2}')
11365         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11366                awk '/ldlm_bl_callback/ {print $2}')
11367         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11368         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11369         lru_resize_enable mdc
11370         lru_resize_enable osc
11371 }
11372 run_test 120b "Early Lock Cancel: create test"
11373
11374 test_120c() {
11375         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11376         remote_mds_nodsh && skip "remote MDS with nodsh"
11377         test_mkdir -i0 -c1 $DIR/$tdir
11378         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11379                 skip "no early lock cancel on server"
11380
11381         lru_resize_disable mdc
11382         lru_resize_disable osc
11383         test_mkdir -i0 -c1 $DIR/$tdir/d1
11384         test_mkdir -i0 -c1 $DIR/$tdir/d2
11385         touch $DIR/$tdir/d1/f1
11386         cancel_lru_locks mdc
11387         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
11388         can1=$(do_facet mds1 \
11389                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11390                awk '/ldlm_cancel/ {print $2}')
11391         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11392                awk '/ldlm_bl_callback/ {print $2}')
11393         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11394         can2=$(do_facet mds1 \
11395                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11396                awk '/ldlm_cancel/ {print $2}')
11397         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11398                awk '/ldlm_bl_callback/ {print $2}')
11399         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11400         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11401         lru_resize_enable mdc
11402         lru_resize_enable osc
11403 }
11404 run_test 120c "Early Lock Cancel: link test"
11405
11406 test_120d() {
11407         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11408         remote_mds_nodsh && skip "remote MDS with nodsh"
11409         test_mkdir -i0 -c1 $DIR/$tdir
11410         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11411                 skip_env "no early lock cancel on server"
11412
11413         lru_resize_disable mdc
11414         lru_resize_disable osc
11415         touch $DIR/$tdir
11416         cancel_lru_locks mdc
11417         stat $DIR/$tdir > /dev/null
11418         can1=$(do_facet mds1 \
11419                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11420                awk '/ldlm_cancel/ {print $2}')
11421         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11422                awk '/ldlm_bl_callback/ {print $2}')
11423         chmod a+x $DIR/$tdir
11424         can2=$(do_facet mds1 \
11425                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11426                awk '/ldlm_cancel/ {print $2}')
11427         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11428                awk '/ldlm_bl_callback/ {print $2}')
11429         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11430         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11431         lru_resize_enable mdc
11432         lru_resize_enable osc
11433 }
11434 run_test 120d "Early Lock Cancel: setattr test"
11435
11436 test_120e() {
11437         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11438         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11439                 skip_env "no early lock cancel on server"
11440         remote_mds_nodsh && skip "remote MDS with nodsh"
11441
11442         local dlmtrace_set=false
11443
11444         test_mkdir -i0 -c1 $DIR/$tdir
11445         lru_resize_disable mdc
11446         lru_resize_disable osc
11447         ! $LCTL get_param debug | grep -q dlmtrace &&
11448                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
11449         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
11450         cancel_lru_locks mdc
11451         cancel_lru_locks osc
11452         dd if=$DIR/$tdir/f1 of=/dev/null
11453         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
11454         # XXX client can not do early lock cancel of OST lock
11455         # during unlink (LU-4206), so cancel osc lock now.
11456         sleep 2
11457         cancel_lru_locks osc
11458         can1=$(do_facet mds1 \
11459                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11460                awk '/ldlm_cancel/ {print $2}')
11461         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11462                awk '/ldlm_bl_callback/ {print $2}')
11463         unlink $DIR/$tdir/f1
11464         sleep 5
11465         can2=$(do_facet mds1 \
11466                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11467                awk '/ldlm_cancel/ {print $2}')
11468         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11469                awk '/ldlm_bl_callback/ {print $2}')
11470         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
11471                 $LCTL dk $TMP/cancel.debug.txt
11472         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
11473                 $LCTL dk $TMP/blocking.debug.txt
11474         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
11475         lru_resize_enable mdc
11476         lru_resize_enable osc
11477 }
11478 run_test 120e "Early Lock Cancel: unlink test"
11479
11480 test_120f() {
11481         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11482         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11483                 skip_env "no early lock cancel on server"
11484         remote_mds_nodsh && skip "remote MDS with nodsh"
11485
11486         test_mkdir -i0 -c1 $DIR/$tdir
11487         lru_resize_disable mdc
11488         lru_resize_disable osc
11489         test_mkdir -i0 -c1 $DIR/$tdir/d1
11490         test_mkdir -i0 -c1 $DIR/$tdir/d2
11491         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
11492         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
11493         cancel_lru_locks mdc
11494         cancel_lru_locks osc
11495         dd if=$DIR/$tdir/d1/f1 of=/dev/null
11496         dd if=$DIR/$tdir/d2/f2 of=/dev/null
11497         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
11498         # XXX client can not do early lock cancel of OST lock
11499         # during rename (LU-4206), so cancel osc lock now.
11500         sleep 2
11501         cancel_lru_locks osc
11502         can1=$(do_facet mds1 \
11503                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11504                awk '/ldlm_cancel/ {print $2}')
11505         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11506                awk '/ldlm_bl_callback/ {print $2}')
11507         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11508         sleep 5
11509         can2=$(do_facet mds1 \
11510                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11511                awk '/ldlm_cancel/ {print $2}')
11512         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11513                awk '/ldlm_bl_callback/ {print $2}')
11514         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11515         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11516         lru_resize_enable mdc
11517         lru_resize_enable osc
11518 }
11519 run_test 120f "Early Lock Cancel: rename test"
11520
11521 test_120g() {
11522         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11523         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11524                 skip_env "no early lock cancel on server"
11525         remote_mds_nodsh && skip "remote MDS with nodsh"
11526
11527         lru_resize_disable mdc
11528         lru_resize_disable osc
11529         count=10000
11530         echo create $count files
11531         test_mkdir $DIR/$tdir
11532         cancel_lru_locks mdc
11533         cancel_lru_locks osc
11534         t0=$(date +%s)
11535
11536         can0=$(do_facet $SINGLEMDS \
11537                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11538                awk '/ldlm_cancel/ {print $2}')
11539         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11540                awk '/ldlm_bl_callback/ {print $2}')
11541         createmany -o $DIR/$tdir/f $count
11542         sync
11543         can1=$(do_facet $SINGLEMDS \
11544                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11545                awk '/ldlm_cancel/ {print $2}')
11546         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11547                awk '/ldlm_bl_callback/ {print $2}')
11548         t1=$(date +%s)
11549         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
11550         echo rm $count files
11551         rm -r $DIR/$tdir
11552         sync
11553         can2=$(do_facet $SINGLEMDS \
11554                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11555                awk '/ldlm_cancel/ {print $2}')
11556         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11557                awk '/ldlm_bl_callback/ {print $2}')
11558         t2=$(date +%s)
11559         echo total: $count removes in $((t2-t1))
11560         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
11561         sleep 2
11562         # wait for commitment of removal
11563         lru_resize_enable mdc
11564         lru_resize_enable osc
11565 }
11566 run_test 120g "Early Lock Cancel: performance test"
11567
11568 test_121() { #bug #10589
11569         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11570
11571         rm -rf $DIR/$tfile
11572         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
11573 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
11574         lctl set_param fail_loc=0x310
11575         cancel_lru_locks osc > /dev/null
11576         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
11577         lctl set_param fail_loc=0
11578         [[ $reads -eq $writes ]] ||
11579                 error "read $reads blocks, must be $writes blocks"
11580 }
11581 run_test 121 "read cancel race ========="
11582
11583 test_123a_base() { # was test 123, statahead(bug 11401)
11584         local lsx="$1"
11585
11586         SLOWOK=0
11587         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
11588                 log "testing UP system. Performance may be lower than expected."
11589                 SLOWOK=1
11590         fi
11591
11592         rm -rf $DIR/$tdir
11593         test_mkdir $DIR/$tdir
11594         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
11595         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
11596         MULT=10
11597         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
11598                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
11599
11600                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
11601                 lctl set_param -n llite.*.statahead_max 0
11602                 lctl get_param llite.*.statahead_max
11603                 cancel_lru_locks mdc
11604                 cancel_lru_locks osc
11605                 stime=$(date +%s)
11606                 time $lsx $DIR/$tdir | wc -l
11607                 etime=$(date +%s)
11608                 delta=$((etime - stime))
11609                 log "$lsx $i files without statahead: $delta sec"
11610                 lctl set_param llite.*.statahead_max=$max
11611
11612                 swrong=$(lctl get_param -n llite.*.statahead_stats |
11613                         grep "statahead wrong:" | awk '{print $3}')
11614                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
11615                 cancel_lru_locks mdc
11616                 cancel_lru_locks osc
11617                 stime=$(date +%s)
11618                 time $lsx $DIR/$tdir | wc -l
11619                 etime=$(date +%s)
11620                 delta_sa=$((etime - stime))
11621                 log "$lsx $i files with statahead: $delta_sa sec"
11622                 lctl get_param -n llite.*.statahead_stats
11623                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
11624                         grep "statahead wrong:" | awk '{print $3}')
11625
11626                 [[ $swrong -lt $ewrong ]] &&
11627                         log "statahead was stopped, maybe too many locks held!"
11628                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
11629
11630                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
11631                         max=$(lctl get_param -n llite.*.statahead_max |
11632                                 head -n 1)
11633                         lctl set_param -n llite.*.statahead_max 0
11634                         lctl get_param llite.*.statahead_max
11635                         cancel_lru_locks mdc
11636                         cancel_lru_locks osc
11637                         stime=$(date +%s)
11638                         time $lsx $DIR/$tdir | wc -l
11639                         etime=$(date +%s)
11640                         delta=$((etime - stime))
11641                         log "$lsx $i files again without statahead: $delta sec"
11642                         lctl set_param llite.*.statahead_max=$max
11643                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
11644                                 if [  $SLOWOK -eq 0 ]; then
11645                                         error "$lsx $i files is slower with statahead!"
11646                                 else
11647                                         log "$lsx $i files is slower with statahead!"
11648                                 fi
11649                                 break
11650                         fi
11651                 fi
11652
11653                 [ $delta -gt 20 ] && break
11654                 [ $delta -gt 8 ] && MULT=$((50 / delta))
11655                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
11656         done
11657         log "$lsx done"
11658
11659         stime=$(date +%s)
11660         rm -r $DIR/$tdir
11661         sync
11662         etime=$(date +%s)
11663         delta=$((etime - stime))
11664         log "rm -r $DIR/$tdir/: $delta seconds"
11665         log "rm done"
11666         lctl get_param -n llite.*.statahead_stats
11667 }
11668
11669 test_123aa() {
11670         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11671
11672         test_123a_base "ls -l"
11673 }
11674 run_test 123aa "verify statahead work"
11675
11676 test_123ab() {
11677         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11678
11679         statx_supported || skip_env "Test must be statx() syscall supported"
11680
11681         test_123a_base "$STATX -l"
11682 }
11683 run_test 123ab "verify statahead work by using statx"
11684
11685 test_123ac() {
11686         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11687
11688         statx_supported || skip_env "Test must be statx() syscall supported"
11689
11690         local rpcs_before
11691         local rpcs_after
11692         local agl_before
11693         local agl_after
11694
11695         cancel_lru_locks $OSC
11696         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
11697         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
11698                 awk '/agl.total:/ {print $3}')
11699         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
11700         test_123a_base "$STATX --cached=always -D"
11701         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
11702                 awk '/agl.total:/ {print $3}')
11703         [ $agl_before -eq $agl_after ] ||
11704                 error "Should not trigger AGL thread - $agl_before:$agl_after"
11705         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
11706         [ $rpcs_after -eq $rpcs_before ] ||
11707                 error "$STATX should not send glimpse RPCs to $OSC"
11708 }
11709 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
11710
11711 test_123b () { # statahead(bug 15027)
11712         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11713
11714         test_mkdir $DIR/$tdir
11715         createmany -o $DIR/$tdir/$tfile-%d 1000
11716
11717         cancel_lru_locks mdc
11718         cancel_lru_locks osc
11719
11720 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
11721         lctl set_param fail_loc=0x80000803
11722         ls -lR $DIR/$tdir > /dev/null
11723         log "ls done"
11724         lctl set_param fail_loc=0x0
11725         lctl get_param -n llite.*.statahead_stats
11726         rm -r $DIR/$tdir
11727         sync
11728
11729 }
11730 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
11731
11732 test_123c() {
11733         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
11734
11735         test_mkdir -i 0 -c 1 $DIR/$tdir.0
11736         test_mkdir -i 1 -c 1 $DIR/$tdir.1
11737         touch $DIR/$tdir.1/{1..3}
11738         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
11739
11740         remount_client $MOUNT
11741
11742         $MULTIOP $DIR/$tdir.0 Q
11743
11744         # let statahead to complete
11745         ls -l $DIR/$tdir.0 > /dev/null
11746
11747         testid=$(echo $TESTNAME | tr '_' ' ')
11748         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
11749                 error "statahead warning" || true
11750 }
11751 run_test 123c "Can not initialize inode warning on DNE statahead"
11752
11753 test_124a() {
11754         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11755         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11756                 skip_env "no lru resize on server"
11757
11758         local NR=2000
11759
11760         test_mkdir $DIR/$tdir
11761
11762         log "create $NR files at $DIR/$tdir"
11763         createmany -o $DIR/$tdir/f $NR ||
11764                 error "failed to create $NR files in $DIR/$tdir"
11765
11766         cancel_lru_locks mdc
11767         ls -l $DIR/$tdir > /dev/null
11768
11769         local NSDIR=""
11770         local LRU_SIZE=0
11771         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
11772                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
11773                 LRU_SIZE=$($LCTL get_param -n $PARAM)
11774                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
11775                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
11776                         log "NSDIR=$NSDIR"
11777                         log "NS=$(basename $NSDIR)"
11778                         break
11779                 fi
11780         done
11781
11782         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
11783                 skip "Not enough cached locks created!"
11784         fi
11785         log "LRU=$LRU_SIZE"
11786
11787         local SLEEP=30
11788
11789         # We know that lru resize allows one client to hold $LIMIT locks
11790         # for 10h. After that locks begin to be killed by client.
11791         local MAX_HRS=10
11792         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
11793         log "LIMIT=$LIMIT"
11794         if [ $LIMIT -lt $LRU_SIZE ]; then
11795                 skip "Limit is too small $LIMIT"
11796         fi
11797
11798         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
11799         # killing locks. Some time was spent for creating locks. This means
11800         # that up to the moment of sleep finish we must have killed some of
11801         # them (10-100 locks). This depends on how fast ther were created.
11802         # Many of them were touched in almost the same moment and thus will
11803         # be killed in groups.
11804         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE))
11805
11806         # Use $LRU_SIZE_B here to take into account real number of locks
11807         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
11808         local LRU_SIZE_B=$LRU_SIZE
11809         log "LVF=$LVF"
11810         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
11811         log "OLD_LVF=$OLD_LVF"
11812         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
11813
11814         # Let's make sure that we really have some margin. Client checks
11815         # cached locks every 10 sec.
11816         SLEEP=$((SLEEP+20))
11817         log "Sleep ${SLEEP} sec"
11818         local SEC=0
11819         while ((SEC<$SLEEP)); do
11820                 echo -n "..."
11821                 sleep 5
11822                 SEC=$((SEC+5))
11823                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
11824                 echo -n "$LRU_SIZE"
11825         done
11826         echo ""
11827         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
11828         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
11829
11830         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
11831                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
11832                 unlinkmany $DIR/$tdir/f $NR
11833                 return
11834         }
11835
11836         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
11837         log "unlink $NR files at $DIR/$tdir"
11838         unlinkmany $DIR/$tdir/f $NR
11839 }
11840 run_test 124a "lru resize ======================================="
11841
11842 get_max_pool_limit()
11843 {
11844         local limit=$($LCTL get_param \
11845                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
11846         local max=0
11847         for l in $limit; do
11848                 if [[ $l -gt $max ]]; then
11849                         max=$l
11850                 fi
11851         done
11852         echo $max
11853 }
11854
11855 test_124b() {
11856         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11857         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11858                 skip_env "no lru resize on server"
11859
11860         LIMIT=$(get_max_pool_limit)
11861
11862         NR=$(($(default_lru_size)*20))
11863         if [[ $NR -gt $LIMIT ]]; then
11864                 log "Limit lock number by $LIMIT locks"
11865                 NR=$LIMIT
11866         fi
11867
11868         IFree=$(mdsrate_inodes_available)
11869         if [ $IFree -lt $NR ]; then
11870                 log "Limit lock number by $IFree inodes"
11871                 NR=$IFree
11872         fi
11873
11874         lru_resize_disable mdc
11875         test_mkdir -p $DIR/$tdir/disable_lru_resize
11876
11877         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
11878         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
11879         cancel_lru_locks mdc
11880         stime=`date +%s`
11881         PID=""
11882         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11883         PID="$PID $!"
11884         sleep 2
11885         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11886         PID="$PID $!"
11887         sleep 2
11888         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11889         PID="$PID $!"
11890         wait $PID
11891         etime=`date +%s`
11892         nolruresize_delta=$((etime-stime))
11893         log "ls -la time: $nolruresize_delta seconds"
11894         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
11895         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
11896
11897         lru_resize_enable mdc
11898         test_mkdir -p $DIR/$tdir/enable_lru_resize
11899
11900         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
11901         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
11902         cancel_lru_locks mdc
11903         stime=`date +%s`
11904         PID=""
11905         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11906         PID="$PID $!"
11907         sleep 2
11908         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11909         PID="$PID $!"
11910         sleep 2
11911         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11912         PID="$PID $!"
11913         wait $PID
11914         etime=`date +%s`
11915         lruresize_delta=$((etime-stime))
11916         log "ls -la time: $lruresize_delta seconds"
11917         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
11918
11919         if [ $lruresize_delta -gt $nolruresize_delta ]; then
11920                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
11921         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
11922                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
11923         else
11924                 log "lru resize performs the same with no lru resize"
11925         fi
11926         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
11927 }
11928 run_test 124b "lru resize (performance test) ======================="
11929
11930 test_124c() {
11931         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11932         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11933                 skip_env "no lru resize on server"
11934
11935         # cache ununsed locks on client
11936         local nr=100
11937         cancel_lru_locks mdc
11938         test_mkdir $DIR/$tdir
11939         createmany -o $DIR/$tdir/f $nr ||
11940                 error "failed to create $nr files in $DIR/$tdir"
11941         ls -l $DIR/$tdir > /dev/null
11942
11943         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
11944         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11945         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
11946         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
11947         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
11948
11949         # set lru_max_age to 1 sec
11950         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
11951         echo "sleep $((recalc_p * 2)) seconds..."
11952         sleep $((recalc_p * 2))
11953
11954         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
11955         # restore lru_max_age
11956         $LCTL set_param -n $nsdir.lru_max_age $max_age
11957         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
11958         unlinkmany $DIR/$tdir/f $nr
11959 }
11960 run_test 124c "LRUR cancel very aged locks"
11961
11962 test_124d() {
11963         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11964         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11965                 skip_env "no lru resize on server"
11966
11967         # cache ununsed locks on client
11968         local nr=100
11969
11970         lru_resize_disable mdc
11971         stack_trap "lru_resize_enable mdc" EXIT
11972
11973         cancel_lru_locks mdc
11974
11975         # asynchronous object destroy at MDT could cause bl ast to client
11976         test_mkdir $DIR/$tdir
11977         createmany -o $DIR/$tdir/f $nr ||
11978                 error "failed to create $nr files in $DIR/$tdir"
11979         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
11980
11981         ls -l $DIR/$tdir > /dev/null
11982
11983         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
11984         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11985         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
11986         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
11987
11988         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
11989
11990         # set lru_max_age to 1 sec
11991         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
11992         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
11993
11994         echo "sleep $((recalc_p * 2)) seconds..."
11995         sleep $((recalc_p * 2))
11996
11997         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
11998
11999         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12000 }
12001 run_test 124d "cancel very aged locks if lru-resize diasbaled"
12002
12003 test_125() { # 13358
12004         $LCTL get_param -n llite.*.client_type | grep -q local ||
12005                 skip "must run as local client"
12006         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
12007                 skip_env "must have acl enabled"
12008         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
12009
12010         test_mkdir $DIR/$tdir
12011         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
12012         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
12013         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
12014 }
12015 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
12016
12017 test_126() { # bug 12829/13455
12018         $GSS && skip_env "must run as gss disabled"
12019         $LCTL get_param -n llite.*.client_type | grep -q local ||
12020                 skip "must run as local client"
12021         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
12022
12023         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
12024         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
12025         rm -f $DIR/$tfile
12026         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
12027 }
12028 run_test 126 "check that the fsgid provided by the client is taken into account"
12029
12030 test_127a() { # bug 15521
12031         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12032         local name count samp unit min max sum sumsq
12033
12034         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
12035         echo "stats before reset"
12036         $LCTL get_param osc.*.stats
12037         $LCTL set_param osc.*.stats=0
12038         local fsize=$((2048 * 1024))
12039
12040         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
12041         cancel_lru_locks osc
12042         dd if=$DIR/$tfile of=/dev/null bs=$fsize
12043
12044         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
12045         stack_trap "rm -f $TMP/$tfile.tmp"
12046         while read name count samp unit min max sum sumsq; do
12047                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12048                 [ ! $min ] && error "Missing min value for $name proc entry"
12049                 eval $name=$count || error "Wrong proc format"
12050
12051                 case $name in
12052                 read_bytes|write_bytes)
12053                         [[ "$unit" =~ "bytes" ]] ||
12054                                 error "unit is not 'bytes': $unit"
12055                         (( $min >= 4096 )) || error "min is too small: $min"
12056                         (( $min <= $fsize )) || error "min is too big: $min"
12057                         (( $max >= 4096 )) || error "max is too small: $max"
12058                         (( $max <= $fsize )) || error "max is too big: $max"
12059                         (( $sum == $fsize )) || error "sum is wrong: $sum"
12060                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
12061                                 error "sumsquare is too small: $sumsq"
12062                         (( $sumsq <= $fsize * $fsize )) ||
12063                                 error "sumsquare is too big: $sumsq"
12064                         ;;
12065                 ost_read|ost_write)
12066                         [[ "$unit" =~ "usec" ]] ||
12067                                 error "unit is not 'usec': $unit"
12068                         ;;
12069                 *)      ;;
12070                 esac
12071         done < $DIR/$tfile.tmp
12072
12073         #check that we actually got some stats
12074         [ "$read_bytes" ] || error "Missing read_bytes stats"
12075         [ "$write_bytes" ] || error "Missing write_bytes stats"
12076         [ "$read_bytes" != 0 ] || error "no read done"
12077         [ "$write_bytes" != 0 ] || error "no write done"
12078 }
12079 run_test 127a "verify the client stats are sane"
12080
12081 test_127b() { # bug LU-333
12082         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12083         local name count samp unit min max sum sumsq
12084
12085         echo "stats before reset"
12086         $LCTL get_param llite.*.stats
12087         $LCTL set_param llite.*.stats=0
12088
12089         # perform 2 reads and writes so MAX is different from SUM.
12090         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12091         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12092         cancel_lru_locks osc
12093         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12094         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12095
12096         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
12097         stack_trap "rm -f $TMP/$tfile.tmp"
12098         while read name count samp unit min max sum sumsq; do
12099                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12100                 eval $name=$count || error "Wrong proc format"
12101
12102                 case $name in
12103                 read_bytes|write_bytes)
12104                         [[ "$unit" =~ "bytes" ]] ||
12105                                 error "unit is not 'bytes': $unit"
12106                         (( $count == 2 )) || error "count is not 2: $count"
12107                         (( $min == $PAGE_SIZE )) ||
12108                                 error "min is not $PAGE_SIZE: $min"
12109                         (( $max == $PAGE_SIZE )) ||
12110                                 error "max is not $PAGE_SIZE: $max"
12111                         (( $sum == $PAGE_SIZE * 2 )) ||
12112                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
12113                         ;;
12114                 read|write)
12115                         [[ "$unit" =~ "usec" ]] ||
12116                                 error "unit is not 'usec': $unit"
12117                         ;;
12118                 *)      ;;
12119                 esac
12120         done < $TMP/$tfile.tmp
12121
12122         #check that we actually got some stats
12123         [ "$read_bytes" ] || error "Missing read_bytes stats"
12124         [ "$write_bytes" ] || error "Missing write_bytes stats"
12125         [ "$read_bytes" != 0 ] || error "no read done"
12126         [ "$write_bytes" != 0 ] || error "no write done"
12127 }
12128 run_test 127b "verify the llite client stats are sane"
12129
12130 test_127c() { # LU-12394
12131         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12132         local size
12133         local bsize
12134         local reads
12135         local writes
12136         local count
12137
12138         $LCTL set_param llite.*.extents_stats=1
12139         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
12140
12141         # Use two stripes so there is enough space in default config
12142         $LFS setstripe -c 2 $DIR/$tfile
12143
12144         # Extent stats start at 0-4K and go in power of two buckets
12145         # LL_HIST_START = 12 --> 2^12 = 4K
12146         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
12147         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
12148         # small configs
12149         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
12150                 do
12151                 # Write and read, 2x each, second time at a non-zero offset
12152                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
12153                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
12154                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
12155                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
12156                 rm -f $DIR/$tfile
12157         done
12158
12159         $LCTL get_param llite.*.extents_stats
12160
12161         count=2
12162         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
12163                 do
12164                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
12165                                 grep -m 1 $bsize)
12166                 reads=$(echo $bucket | awk '{print $5}')
12167                 writes=$(echo $bucket | awk '{print $9}')
12168                 [ "$reads" -eq $count ] ||
12169                         error "$reads reads in < $bsize bucket, expect $count"
12170                 [ "$writes" -eq $count ] ||
12171                         error "$writes writes in < $bsize bucket, expect $count"
12172         done
12173
12174         # Test mmap write and read
12175         $LCTL set_param llite.*.extents_stats=c
12176         size=512
12177         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
12178         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
12179         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
12180
12181         $LCTL get_param llite.*.extents_stats
12182
12183         count=$(((size*1024) / PAGE_SIZE))
12184
12185         bsize=$((2 * PAGE_SIZE / 1024))K
12186
12187         bucket=$($LCTL get_param -n llite.*.extents_stats |
12188                         grep -m 1 $bsize)
12189         reads=$(echo $bucket | awk '{print $5}')
12190         writes=$(echo $bucket | awk '{print $9}')
12191         # mmap writes fault in the page first, creating an additonal read
12192         [ "$reads" -eq $((2 * count)) ] ||
12193                 error "$reads reads in < $bsize bucket, expect $count"
12194         [ "$writes" -eq $count ] ||
12195                 error "$writes writes in < $bsize bucket, expect $count"
12196 }
12197 run_test 127c "test llite extent stats with regular & mmap i/o"
12198
12199 test_128() { # bug 15212
12200         touch $DIR/$tfile
12201         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
12202                 find $DIR/$tfile
12203                 find $DIR/$tfile
12204         EOF
12205
12206         result=$(grep error $TMP/$tfile.log)
12207         rm -f $DIR/$tfile $TMP/$tfile.log
12208         [ -z "$result" ] ||
12209                 error "consecutive find's under interactive lfs failed"
12210 }
12211 run_test 128 "interactive lfs for 2 consecutive find's"
12212
12213 set_dir_limits () {
12214         local mntdev
12215         local canondev
12216         local node
12217
12218         local ldproc=/proc/fs/ldiskfs
12219         local facets=$(get_facets MDS)
12220
12221         for facet in ${facets//,/ }; do
12222                 canondev=$(ldiskfs_canon \
12223                            *.$(convert_facet2label $facet).mntdev $facet)
12224                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
12225                         ldproc=/sys/fs/ldiskfs
12226                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
12227                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
12228         done
12229 }
12230
12231 check_mds_dmesg() {
12232         local facets=$(get_facets MDS)
12233         for facet in ${facets//,/ }; do
12234                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
12235         done
12236         return 1
12237 }
12238
12239 test_129() {
12240         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12241         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
12242                 skip "Need MDS version with at least 2.5.56"
12243         if [ "$mds1_FSTYPE" != ldiskfs ]; then
12244                 skip_env "ldiskfs only test"
12245         fi
12246         remote_mds_nodsh && skip "remote MDS with nodsh"
12247
12248         local ENOSPC=28
12249         local has_warning=false
12250
12251         rm -rf $DIR/$tdir
12252         mkdir -p $DIR/$tdir
12253
12254         # block size of mds1
12255         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
12256         set_dir_limits $maxsize $((maxsize * 6 / 8))
12257         stack_trap "set_dir_limits 0 0"
12258         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
12259         local dirsize=$(stat -c%s "$DIR/$tdir")
12260         local nfiles=0
12261         while (( $dirsize <= $maxsize )); do
12262                 $MCREATE $DIR/$tdir/file_base_$nfiles
12263                 rc=$?
12264                 # check two errors:
12265                 # ENOSPC for ext4 max_dir_size, which has been used since
12266                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
12267                 if (( rc == ENOSPC )); then
12268                         set_dir_limits 0 0
12269                         echo "rc=$rc returned as expected after $nfiles files"
12270
12271                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
12272                                 error "create failed w/o dir size limit"
12273
12274                         # messages may be rate limited if test is run repeatedly
12275                         check_mds_dmesg '"is approaching max"' ||
12276                                 echo "warning message should be output"
12277                         check_mds_dmesg '"has reached max"' ||
12278                                 echo "reached message should be output"
12279
12280                         dirsize=$(stat -c%s "$DIR/$tdir")
12281
12282                         [[ $dirsize -ge $maxsize ]] && return 0
12283                         error "dirsize $dirsize < $maxsize after $nfiles files"
12284                 elif (( rc != 0 )); then
12285                         break
12286                 fi
12287                 nfiles=$((nfiles + 1))
12288                 dirsize=$(stat -c%s "$DIR/$tdir")
12289         done
12290
12291         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
12292 }
12293 run_test 129 "test directory size limit ========================"
12294
12295 OLDIFS="$IFS"
12296 cleanup_130() {
12297         trap 0
12298         IFS="$OLDIFS"
12299 }
12300
12301 test_130a() {
12302         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12303         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12304
12305         trap cleanup_130 EXIT RETURN
12306
12307         local fm_file=$DIR/$tfile
12308         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
12309         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
12310                 error "dd failed for $fm_file"
12311
12312         # LU-1795: test filefrag/FIEMAP once, even if unsupported
12313         filefrag -ves $fm_file
12314         RC=$?
12315         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12316                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12317         [ $RC != 0 ] && error "filefrag $fm_file failed"
12318
12319         filefrag_op=$(filefrag -ve -k $fm_file |
12320                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12321         lun=$($LFS getstripe -i $fm_file)
12322
12323         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
12324         IFS=$'\n'
12325         tot_len=0
12326         for line in $filefrag_op
12327         do
12328                 frag_lun=`echo $line | cut -d: -f5`
12329                 ext_len=`echo $line | cut -d: -f4`
12330                 if (( $frag_lun != $lun )); then
12331                         cleanup_130
12332                         error "FIEMAP on 1-stripe file($fm_file) failed"
12333                         return
12334                 fi
12335                 (( tot_len += ext_len ))
12336         done
12337
12338         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
12339                 cleanup_130
12340                 error "FIEMAP on 1-stripe file($fm_file) failed;"
12341                 return
12342         fi
12343
12344         cleanup_130
12345
12346         echo "FIEMAP on single striped file succeeded"
12347 }
12348 run_test 130a "FIEMAP (1-stripe file)"
12349
12350 test_130b() {
12351         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12352
12353         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12354         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12355
12356         trap cleanup_130 EXIT RETURN
12357
12358         local fm_file=$DIR/$tfile
12359         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12360                         error "setstripe on $fm_file"
12361         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12362                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12363
12364         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
12365                 error "dd failed on $fm_file"
12366
12367         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12368         filefrag_op=$(filefrag -ve -k $fm_file |
12369                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12370
12371         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12372                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12373
12374         IFS=$'\n'
12375         tot_len=0
12376         num_luns=1
12377         for line in $filefrag_op
12378         do
12379                 frag_lun=$(echo $line | cut -d: -f5 |
12380                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12381                 ext_len=$(echo $line | cut -d: -f4)
12382                 if (( $frag_lun != $last_lun )); then
12383                         if (( tot_len != 1024 )); then
12384                                 cleanup_130
12385                                 error "FIEMAP on $fm_file failed; returned " \
12386                                 "len $tot_len for OST $last_lun instead of 1024"
12387                                 return
12388                         else
12389                                 (( num_luns += 1 ))
12390                                 tot_len=0
12391                         fi
12392                 fi
12393                 (( tot_len += ext_len ))
12394                 last_lun=$frag_lun
12395         done
12396         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
12397                 cleanup_130
12398                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12399                         "luns or wrong len for OST $last_lun"
12400                 return
12401         fi
12402
12403         cleanup_130
12404
12405         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
12406 }
12407 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
12408
12409 test_130c() {
12410         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12411
12412         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12413         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12414
12415         trap cleanup_130 EXIT RETURN
12416
12417         local fm_file=$DIR/$tfile
12418         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
12419         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12420                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12421
12422         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
12423                         error "dd failed on $fm_file"
12424
12425         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12426         filefrag_op=$(filefrag -ve -k $fm_file |
12427                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12428
12429         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12430                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12431
12432         IFS=$'\n'
12433         tot_len=0
12434         num_luns=1
12435         for line in $filefrag_op
12436         do
12437                 frag_lun=$(echo $line | cut -d: -f5 |
12438                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12439                 ext_len=$(echo $line | cut -d: -f4)
12440                 if (( $frag_lun != $last_lun )); then
12441                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
12442                         if (( logical != 512 )); then
12443                                 cleanup_130
12444                                 error "FIEMAP on $fm_file failed; returned " \
12445                                 "logical start for lun $logical instead of 512"
12446                                 return
12447                         fi
12448                         if (( tot_len != 512 )); then
12449                                 cleanup_130
12450                                 error "FIEMAP on $fm_file failed; returned " \
12451                                 "len $tot_len for OST $last_lun instead of 1024"
12452                                 return
12453                         else
12454                                 (( num_luns += 1 ))
12455                                 tot_len=0
12456                         fi
12457                 fi
12458                 (( tot_len += ext_len ))
12459                 last_lun=$frag_lun
12460         done
12461         if (( num_luns != 2 || tot_len != 512 )); then
12462                 cleanup_130
12463                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12464                         "luns or wrong len for OST $last_lun"
12465                 return
12466         fi
12467
12468         cleanup_130
12469
12470         echo "FIEMAP on 2-stripe file with hole succeeded"
12471 }
12472 run_test 130c "FIEMAP (2-stripe file with hole)"
12473
12474 test_130d() {
12475         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
12476
12477         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12478         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12479
12480         trap cleanup_130 EXIT RETURN
12481
12482         local fm_file=$DIR/$tfile
12483         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12484                         error "setstripe on $fm_file"
12485         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12486                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12487
12488         local actual_stripe_count=$($LFS getstripe -c $fm_file)
12489         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
12490                 error "dd failed on $fm_file"
12491
12492         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12493         filefrag_op=$(filefrag -ve -k $fm_file |
12494                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12495
12496         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12497                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12498
12499         IFS=$'\n'
12500         tot_len=0
12501         num_luns=1
12502         for line in $filefrag_op
12503         do
12504                 frag_lun=$(echo $line | cut -d: -f5 |
12505                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12506                 ext_len=$(echo $line | cut -d: -f4)
12507                 if (( $frag_lun != $last_lun )); then
12508                         if (( tot_len != 1024 )); then
12509                                 cleanup_130
12510                                 error "FIEMAP on $fm_file failed; returned " \
12511                                 "len $tot_len for OST $last_lun instead of 1024"
12512                                 return
12513                         else
12514                                 (( num_luns += 1 ))
12515                                 tot_len=0
12516                         fi
12517                 fi
12518                 (( tot_len += ext_len ))
12519                 last_lun=$frag_lun
12520         done
12521         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
12522                 cleanup_130
12523                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12524                         "luns or wrong len for OST $last_lun"
12525                 return
12526         fi
12527
12528         cleanup_130
12529
12530         echo "FIEMAP on N-stripe file succeeded"
12531 }
12532 run_test 130d "FIEMAP (N-stripe file)"
12533
12534 test_130e() {
12535         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12536
12537         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12538         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12539
12540         trap cleanup_130 EXIT RETURN
12541
12542         local fm_file=$DIR/$tfile
12543         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
12544         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12545                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12546
12547         NUM_BLKS=512
12548         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
12549         for ((i = 0; i < $NUM_BLKS; i++))
12550         do
12551                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) conv=notrunc > /dev/null 2>&1
12552         done
12553
12554         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12555         filefrag_op=$(filefrag -ve -k $fm_file |
12556                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12557
12558         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12559                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12560
12561         IFS=$'\n'
12562         tot_len=0
12563         num_luns=1
12564         for line in $filefrag_op
12565         do
12566                 frag_lun=$(echo $line | cut -d: -f5 |
12567                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12568                 ext_len=$(echo $line | cut -d: -f4)
12569                 if (( $frag_lun != $last_lun )); then
12570                         if (( tot_len != $EXPECTED_LEN )); then
12571                                 cleanup_130
12572                                 error "FIEMAP on $fm_file failed; returned " \
12573                                 "len $tot_len for OST $last_lun instead " \
12574                                 "of $EXPECTED_LEN"
12575                                 return
12576                         else
12577                                 (( num_luns += 1 ))
12578                                 tot_len=0
12579                         fi
12580                 fi
12581                 (( tot_len += ext_len ))
12582                 last_lun=$frag_lun
12583         done
12584         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
12585                 cleanup_130
12586                 error "FIEMAP on $fm_file failed; returned wrong number " \
12587                         "of luns or wrong len for OST $last_lun"
12588                 return
12589         fi
12590
12591         cleanup_130
12592
12593         echo "FIEMAP with continuation calls succeeded"
12594 }
12595 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
12596
12597 test_130f() {
12598         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12599         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12600
12601         local fm_file=$DIR/$tfile
12602         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
12603                 error "multiop create with lov_delay_create on $fm_file"
12604
12605         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12606         filefrag_extents=$(filefrag -vek $fm_file |
12607                            awk '/extents? found/ { print $2 }')
12608         if [[ "$filefrag_extents" != "0" ]]; then
12609                 error "FIEMAP on $fm_file failed; " \
12610                       "returned $filefrag_extents expected 0"
12611         fi
12612
12613         rm -f $fm_file
12614 }
12615 run_test 130f "FIEMAP (unstriped file)"
12616
12617 # Test for writev/readv
12618 test_131a() {
12619         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
12620                 error "writev test failed"
12621         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
12622                 error "readv failed"
12623         rm -f $DIR/$tfile
12624 }
12625 run_test 131a "test iov's crossing stripe boundary for writev/readv"
12626
12627 test_131b() {
12628         local fsize=$((524288 + 1048576 + 1572864))
12629         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
12630                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12631                         error "append writev test failed"
12632
12633         ((fsize += 1572864 + 1048576))
12634         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
12635                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12636                         error "append writev test failed"
12637         rm -f $DIR/$tfile
12638 }
12639 run_test 131b "test append writev"
12640
12641 test_131c() {
12642         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
12643         error "NOT PASS"
12644 }
12645 run_test 131c "test read/write on file w/o objects"
12646
12647 test_131d() {
12648         rwv -f $DIR/$tfile -w -n 1 1572864
12649         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
12650         if [ "$NOB" != 1572864 ]; then
12651                 error "Short read filed: read $NOB bytes instead of 1572864"
12652         fi
12653         rm -f $DIR/$tfile
12654 }
12655 run_test 131d "test short read"
12656
12657 test_131e() {
12658         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
12659         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
12660         error "read hitting hole failed"
12661         rm -f $DIR/$tfile
12662 }
12663 run_test 131e "test read hitting hole"
12664
12665 check_stats() {
12666         local facet=$1
12667         local op=$2
12668         local want=${3:-0}
12669         local res
12670
12671         case $facet in
12672         mds*) res=$(do_facet $facet \
12673                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
12674                  ;;
12675         ost*) res=$(do_facet $facet \
12676                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
12677                  ;;
12678         *) error "Wrong facet '$facet'" ;;
12679         esac
12680         [ "$res" ] || error "The counter for $op on $facet was not incremented"
12681         # if the argument $3 is zero, it means any stat increment is ok.
12682         if [[ $want -gt 0 ]]; then
12683                 local count=$(echo $res | awk '{ print $2 }')
12684                 [[ $count -ne $want ]] &&
12685                         error "The $op counter on $facet is $count, not $want"
12686         fi
12687 }
12688
12689 test_133a() {
12690         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12691         remote_ost_nodsh && skip "remote OST with nodsh"
12692         remote_mds_nodsh && skip "remote MDS with nodsh"
12693         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
12694                 skip_env "MDS doesn't support rename stats"
12695
12696         local testdir=$DIR/${tdir}/stats_testdir
12697
12698         mkdir -p $DIR/${tdir}
12699
12700         # clear stats.
12701         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12702         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12703
12704         # verify mdt stats first.
12705         mkdir ${testdir} || error "mkdir failed"
12706         check_stats $SINGLEMDS "mkdir" 1
12707         touch ${testdir}/${tfile} || error "touch failed"
12708         check_stats $SINGLEMDS "open" 1
12709         check_stats $SINGLEMDS "close" 1
12710         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
12711                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
12712                 check_stats $SINGLEMDS "mknod" 2
12713         }
12714         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
12715         check_stats $SINGLEMDS "unlink" 1
12716         rm -f ${testdir}/${tfile} || error "file remove failed"
12717         check_stats $SINGLEMDS "unlink" 2
12718
12719         # remove working dir and check mdt stats again.
12720         rmdir ${testdir} || error "rmdir failed"
12721         check_stats $SINGLEMDS "rmdir" 1
12722
12723         local testdir1=$DIR/${tdir}/stats_testdir1
12724         mkdir -p ${testdir}
12725         mkdir -p ${testdir1}
12726         touch ${testdir1}/test1
12727         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
12728         check_stats $SINGLEMDS "crossdir_rename" 1
12729
12730         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
12731         check_stats $SINGLEMDS "samedir_rename" 1
12732
12733         rm -rf $DIR/${tdir}
12734 }
12735 run_test 133a "Verifying MDT stats ========================================"
12736
12737 test_133b() {
12738         local res
12739
12740         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12741         remote_ost_nodsh && skip "remote OST with nodsh"
12742         remote_mds_nodsh && skip "remote MDS with nodsh"
12743
12744         local testdir=$DIR/${tdir}/stats_testdir
12745
12746         mkdir -p ${testdir} || error "mkdir failed"
12747         touch ${testdir}/${tfile} || error "touch failed"
12748         cancel_lru_locks mdc
12749
12750         # clear stats.
12751         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12752         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12753
12754         # extra mdt stats verification.
12755         chmod 444 ${testdir}/${tfile} || error "chmod failed"
12756         check_stats $SINGLEMDS "setattr" 1
12757         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12758         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
12759         then            # LU-1740
12760                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
12761                 check_stats $SINGLEMDS "getattr" 1
12762         fi
12763         rm -rf $DIR/${tdir}
12764
12765         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
12766         # so the check below is not reliable
12767         [ $MDSCOUNT -eq 1 ] || return 0
12768
12769         # Sleep to avoid a cached response.
12770         #define OBD_STATFS_CACHE_SECONDS 1
12771         sleep 2
12772         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12773         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12774         $LFS df || error "lfs failed"
12775         check_stats $SINGLEMDS "statfs" 1
12776
12777         # check aggregated statfs (LU-10018)
12778         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
12779                 return 0
12780         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
12781                 return 0
12782         sleep 2
12783         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12784         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12785         df $DIR
12786         check_stats $SINGLEMDS "statfs" 1
12787
12788         # We want to check that the client didn't send OST_STATFS to
12789         # ost1 but the MDT also uses OST_STATFS for precreate. So some
12790         # extra care is needed here.
12791         if remote_mds; then
12792                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
12793                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
12794
12795                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
12796                 [ "$res" ] && error "OST got STATFS"
12797         fi
12798
12799         return 0
12800 }
12801 run_test 133b "Verifying extra MDT stats =================================="
12802
12803 test_133c() {
12804         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12805         remote_ost_nodsh && skip "remote OST with nodsh"
12806         remote_mds_nodsh && skip "remote MDS with nodsh"
12807
12808         local testdir=$DIR/$tdir/stats_testdir
12809
12810         test_mkdir -p $testdir
12811
12812         # verify obdfilter stats.
12813         $LFS setstripe -c 1 -i 0 $testdir/$tfile
12814         sync
12815         cancel_lru_locks osc
12816         wait_delete_completed
12817
12818         # clear stats.
12819         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12820         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12821
12822         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
12823                 error "dd failed"
12824         sync
12825         cancel_lru_locks osc
12826         check_stats ost1 "write" 1
12827
12828         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
12829         check_stats ost1 "read" 1
12830
12831         > $testdir/$tfile || error "truncate failed"
12832         check_stats ost1 "punch" 1
12833
12834         rm -f $testdir/$tfile || error "file remove failed"
12835         wait_delete_completed
12836         check_stats ost1 "destroy" 1
12837
12838         rm -rf $DIR/$tdir
12839 }
12840 run_test 133c "Verifying OST stats ========================================"
12841
12842 order_2() {
12843         local value=$1
12844         local orig=$value
12845         local order=1
12846
12847         while [ $value -ge 2 ]; do
12848                 order=$((order*2))
12849                 value=$((value/2))
12850         done
12851
12852         if [ $orig -gt $order ]; then
12853                 order=$((order*2))
12854         fi
12855         echo $order
12856 }
12857
12858 size_in_KMGT() {
12859     local value=$1
12860     local size=('K' 'M' 'G' 'T');
12861     local i=0
12862     local size_string=$value
12863
12864     while [ $value -ge 1024 ]; do
12865         if [ $i -gt 3 ]; then
12866             #T is the biggest unit we get here, if that is bigger,
12867             #just return XXXT
12868             size_string=${value}T
12869             break
12870         fi
12871         value=$((value >> 10))
12872         if [ $value -lt 1024 ]; then
12873             size_string=${value}${size[$i]}
12874             break
12875         fi
12876         i=$((i + 1))
12877     done
12878
12879     echo $size_string
12880 }
12881
12882 get_rename_size() {
12883         local size=$1
12884         local context=${2:-.}
12885         local sample=$(do_facet $SINGLEMDS $LCTL \
12886                 get_param mdt.$FSNAME-MDT0000.rename_stats |
12887                 grep -A1 $context |
12888                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
12889         echo $sample
12890 }
12891
12892 test_133d() {
12893         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12894         remote_ost_nodsh && skip "remote OST with nodsh"
12895         remote_mds_nodsh && skip "remote MDS with nodsh"
12896         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
12897                 skip_env "MDS doesn't support rename stats"
12898
12899         local testdir1=$DIR/${tdir}/stats_testdir1
12900         local testdir2=$DIR/${tdir}/stats_testdir2
12901         mkdir -p $DIR/${tdir}
12902
12903         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
12904
12905         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
12906         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
12907
12908         createmany -o $testdir1/test 512 || error "createmany failed"
12909
12910         # check samedir rename size
12911         mv ${testdir1}/test0 ${testdir1}/test_0
12912
12913         local testdir1_size=$(ls -l $DIR/${tdir} |
12914                 awk '/stats_testdir1/ {print $5}')
12915         local testdir2_size=$(ls -l $DIR/${tdir} |
12916                 awk '/stats_testdir2/ {print $5}')
12917
12918         testdir1_size=$(order_2 $testdir1_size)
12919         testdir2_size=$(order_2 $testdir2_size)
12920
12921         testdir1_size=$(size_in_KMGT $testdir1_size)
12922         testdir2_size=$(size_in_KMGT $testdir2_size)
12923
12924         echo "source rename dir size: ${testdir1_size}"
12925         echo "target rename dir size: ${testdir2_size}"
12926
12927         local cmd="do_facet $SINGLEMDS $LCTL "
12928         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
12929
12930         eval $cmd || error "$cmd failed"
12931         local samedir=$($cmd | grep 'same_dir')
12932         local same_sample=$(get_rename_size $testdir1_size)
12933         [ -z "$samedir" ] && error "samedir_rename_size count error"
12934         [[ $same_sample -eq 1 ]] ||
12935                 error "samedir_rename_size error $same_sample"
12936         echo "Check same dir rename stats success"
12937
12938         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
12939
12940         # check crossdir rename size
12941         mv ${testdir1}/test_0 ${testdir2}/test_0
12942
12943         testdir1_size=$(ls -l $DIR/${tdir} |
12944                 awk '/stats_testdir1/ {print $5}')
12945         testdir2_size=$(ls -l $DIR/${tdir} |
12946                 awk '/stats_testdir2/ {print $5}')
12947
12948         testdir1_size=$(order_2 $testdir1_size)
12949         testdir2_size=$(order_2 $testdir2_size)
12950
12951         testdir1_size=$(size_in_KMGT $testdir1_size)
12952         testdir2_size=$(size_in_KMGT $testdir2_size)
12953
12954         echo "source rename dir size: ${testdir1_size}"
12955         echo "target rename dir size: ${testdir2_size}"
12956
12957         eval $cmd || error "$cmd failed"
12958         local crossdir=$($cmd | grep 'crossdir')
12959         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
12960         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
12961         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
12962         [[ $src_sample -eq 1 ]] ||
12963                 error "crossdir_rename_size error $src_sample"
12964         [[ $tgt_sample -eq 1 ]] ||
12965                 error "crossdir_rename_size error $tgt_sample"
12966         echo "Check cross dir rename stats success"
12967         rm -rf $DIR/${tdir}
12968 }
12969 run_test 133d "Verifying rename_stats ========================================"
12970
12971 test_133e() {
12972         remote_mds_nodsh && skip "remote MDS with nodsh"
12973         remote_ost_nodsh && skip "remote OST with nodsh"
12974         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12975
12976         local testdir=$DIR/${tdir}/stats_testdir
12977         local ctr f0 f1 bs=32768 count=42 sum
12978
12979         mkdir -p ${testdir} || error "mkdir failed"
12980
12981         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
12982
12983         for ctr in {write,read}_bytes; do
12984                 sync
12985                 cancel_lru_locks osc
12986
12987                 do_facet ost1 $LCTL set_param -n \
12988                         "obdfilter.*.exports.clear=clear"
12989
12990                 if [ $ctr = write_bytes ]; then
12991                         f0=/dev/zero
12992                         f1=${testdir}/${tfile}
12993                 else
12994                         f0=${testdir}/${tfile}
12995                         f1=/dev/null
12996                 fi
12997
12998                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
12999                         error "dd failed"
13000                 sync
13001                 cancel_lru_locks osc
13002
13003                 sum=$(do_facet ost1 $LCTL get_param \
13004                         "obdfilter.*.exports.*.stats" |
13005                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
13006                                 $1 == ctr { sum += $7 }
13007                                 END { printf("%0.0f", sum) }')
13008
13009                 if ((sum != bs * count)); then
13010                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
13011                 fi
13012         done
13013
13014         rm -rf $DIR/${tdir}
13015 }
13016 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
13017
13018 test_133f() {
13019         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
13020                 skip "too old lustre for get_param -R ($facet_ver)"
13021
13022         # verifying readability.
13023         $LCTL get_param -R '*' &> /dev/null
13024
13025         # Verifing writability with badarea_io.
13026         $LCTL list_param -FR '*' | grep '=' | tr -d = |
13027                 egrep -v 'force_lbug|changelog_mask' | xargs badarea_io ||
13028                 error "client badarea_io failed"
13029
13030         # remount the FS in case writes/reads /proc break the FS
13031         cleanup || error "failed to unmount"
13032         setup || error "failed to setup"
13033 }
13034 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
13035
13036 test_133g() {
13037         remote_mds_nodsh && skip "remote MDS with nodsh"
13038         remote_ost_nodsh && skip "remote OST with nodsh"
13039
13040         local facet
13041         for facet in mds1 ost1; do
13042                 local facet_ver=$(lustre_version_code $facet)
13043                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
13044                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
13045                 else
13046                         log "$facet: too old lustre for get_param -R"
13047                 fi
13048                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
13049                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
13050                                 tr -d = | egrep -v 'force_lbug|changelog_mask' |
13051                                 xargs badarea_io" ||
13052                                         error "$facet badarea_io failed"
13053                 else
13054                         skip_noexit "$facet: too old lustre for get_param -R"
13055                 fi
13056         done
13057
13058         # remount the FS in case writes/reads /proc break the FS
13059         cleanup || error "failed to unmount"
13060         setup || error "failed to setup"
13061 }
13062 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
13063
13064 test_133h() {
13065         remote_mds_nodsh && skip "remote MDS with nodsh"
13066         remote_ost_nodsh && skip "remote OST with nodsh"
13067         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
13068                 skip "Need MDS version at least 2.9.54"
13069
13070         local facet
13071         for facet in client mds1 ost1; do
13072                 # Get the list of files that are missing the terminating newline
13073                 local plist=$(do_facet $facet
13074                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
13075                 local ent
13076                 for ent in $plist; do
13077                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
13078                                 awk -v FS='\v' -v RS='\v\v' \
13079                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
13080                                         print FILENAME}'" 2>/dev/null)
13081                         [ -z $missing ] || {
13082                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
13083                                 error "file does not end with newline: $facet-$ent"
13084                         }
13085                 done
13086         done
13087 }
13088 run_test 133h "Proc files should end with newlines"
13089
13090 test_134a() {
13091         remote_mds_nodsh && skip "remote MDS with nodsh"
13092         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13093                 skip "Need MDS version at least 2.7.54"
13094
13095         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13096         cancel_lru_locks mdc
13097
13098         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13099         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13100         [ $unused -eq 0 ] || error "$unused locks are not cleared"
13101
13102         local nr=1000
13103         createmany -o $DIR/$tdir/f $nr ||
13104                 error "failed to create $nr files in $DIR/$tdir"
13105         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13106
13107         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
13108         do_facet mds1 $LCTL set_param fail_loc=0x327
13109         do_facet mds1 $LCTL set_param fail_val=500
13110         touch $DIR/$tdir/m
13111
13112         echo "sleep 10 seconds ..."
13113         sleep 10
13114         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
13115
13116         do_facet mds1 $LCTL set_param fail_loc=0
13117         do_facet mds1 $LCTL set_param fail_val=0
13118         [ $lck_cnt -lt $unused ] ||
13119                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
13120
13121         rm $DIR/$tdir/m
13122         unlinkmany $DIR/$tdir/f $nr
13123 }
13124 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
13125
13126 test_134b() {
13127         remote_mds_nodsh && skip "remote MDS with nodsh"
13128         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13129                 skip "Need MDS version at least 2.7.54"
13130
13131         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13132         cancel_lru_locks mdc
13133
13134         local low_wm=$(do_facet mds1 $LCTL get_param -n \
13135                         ldlm.lock_reclaim_threshold_mb)
13136         # disable reclaim temporarily
13137         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
13138
13139         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
13140         do_facet mds1 $LCTL set_param fail_loc=0x328
13141         do_facet mds1 $LCTL set_param fail_val=500
13142
13143         $LCTL set_param debug=+trace
13144
13145         local nr=600
13146         createmany -o $DIR/$tdir/f $nr &
13147         local create_pid=$!
13148
13149         echo "Sleep $TIMEOUT seconds ..."
13150         sleep $TIMEOUT
13151         if ! ps -p $create_pid  > /dev/null 2>&1; then
13152                 do_facet mds1 $LCTL set_param fail_loc=0
13153                 do_facet mds1 $LCTL set_param fail_val=0
13154                 do_facet mds1 $LCTL set_param \
13155                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
13156                 error "createmany finished incorrectly!"
13157         fi
13158         do_facet mds1 $LCTL set_param fail_loc=0
13159         do_facet mds1 $LCTL set_param fail_val=0
13160         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
13161         wait $create_pid || return 1
13162
13163         unlinkmany $DIR/$tdir/f $nr
13164 }
13165 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
13166
13167 test_135() {
13168         remote_mds_nodsh && skip "remote MDS with nodsh"
13169         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13170                 skip "Need MDS version at least 2.13.50"
13171         local fname
13172
13173         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13174
13175 #define OBD_FAIL_PLAIN_RECORDS 0x1319
13176         #set only one record at plain llog
13177         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
13178
13179         #fill already existed plain llog each 64767
13180         #wrapping whole catalog
13181         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13182
13183         createmany -o $DIR/$tdir/$tfile_ 64700
13184         for (( i = 0; i < 64700; i = i + 2 ))
13185         do
13186                 rm $DIR/$tdir/$tfile_$i &
13187                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13188                 local pid=$!
13189                 wait $pid
13190         done
13191
13192         #waiting osp synchronization
13193         wait_delete_completed
13194 }
13195 run_test 135 "Race catalog processing"
13196
13197 test_136() {
13198         remote_mds_nodsh && skip "remote MDS with nodsh"
13199         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13200                 skip "Need MDS version at least 2.13.50"
13201         local fname
13202
13203         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13204         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
13205         #set only one record at plain llog
13206 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
13207         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
13208
13209         #fill already existed 2 plain llogs each 64767
13210         #wrapping whole catalog
13211         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13212         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
13213         wait_delete_completed
13214
13215         createmany -o $DIR/$tdir/$tfile_ 10
13216         sleep 25
13217
13218         do_facet $SINGLEMDS $LCTL set_param fail_val=3
13219         for (( i = 0; i < 10; i = i + 3 ))
13220         do
13221                 rm $DIR/$tdir/$tfile_$i &
13222                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13223                 local pid=$!
13224                 wait $pid
13225                 sleep 7
13226                 rm $DIR/$tdir/$tfile_$((i + 2)) &
13227         done
13228
13229         #waiting osp synchronization
13230         wait_delete_completed
13231 }
13232 run_test 136 "Race catalog processing 2"
13233
13234 test_140() { #bug-17379
13235         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13236
13237         test_mkdir $DIR/$tdir
13238         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
13239         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
13240
13241         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
13242         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
13243         local i=0
13244         while i=$((i + 1)); do
13245                 test_mkdir $i
13246                 cd $i || error "Changing to $i"
13247                 ln -s ../stat stat || error "Creating stat symlink"
13248                 # Read the symlink until ELOOP present,
13249                 # not LBUGing the system is considered success,
13250                 # we didn't overrun the stack.
13251                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
13252                 if [ $ret -ne 0 ]; then
13253                         if [ $ret -eq 40 ]; then
13254                                 break  # -ELOOP
13255                         else
13256                                 error "Open stat symlink"
13257                                         return
13258                         fi
13259                 fi
13260         done
13261         i=$((i - 1))
13262         echo "The symlink depth = $i"
13263         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
13264                 error "Invalid symlink depth"
13265
13266         # Test recursive symlink
13267         ln -s symlink_self symlink_self
13268         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
13269         echo "open symlink_self returns $ret"
13270         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
13271 }
13272 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
13273
13274 test_150a() {
13275         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13276
13277         local TF="$TMP/$tfile"
13278
13279         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13280         cp $TF $DIR/$tfile
13281         cancel_lru_locks $OSC
13282         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
13283         remount_client $MOUNT
13284         df -P $MOUNT
13285         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
13286
13287         $TRUNCATE $TF 6000
13288         $TRUNCATE $DIR/$tfile 6000
13289         cancel_lru_locks $OSC
13290         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
13291
13292         echo "12345" >>$TF
13293         echo "12345" >>$DIR/$tfile
13294         cancel_lru_locks $OSC
13295         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
13296
13297         echo "12345" >>$TF
13298         echo "12345" >>$DIR/$tfile
13299         cancel_lru_locks $OSC
13300         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
13301
13302         rm -f $TF
13303         true
13304 }
13305 run_test 150a "truncate/append tests"
13306
13307 test_150b() {
13308         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13309         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13310                 skip "Need OST version at least 2.13.53"
13311         touch $DIR/$tfile
13312         check_fallocate $DIR/$tfile || error "fallocate failed"
13313 }
13314 run_test 150b "Verify fallocate (prealloc) functionality"
13315
13316 test_150c() {
13317         local bytes
13318         local want
13319
13320         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13321         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13322                 skip "Need OST version at least 2.13.53"
13323
13324         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
13325         fallocate -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
13326         sync; sync_all_data
13327         cancel_lru_locks $OSC
13328         sleep 5
13329         bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
13330         want=$((OSTCOUNT * 1048576))
13331
13332         # Must allocate all requested space, not more than 5% extra
13333         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13334                 error "bytes $bytes is not $want"
13335 }
13336 run_test 150c "Verify fallocate Size and Blocks"
13337
13338 test_150d() {
13339         local bytes
13340         local want
13341
13342         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13343         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13344                 skip "Need OST version at least 2.13.53"
13345
13346         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
13347         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
13348         sync; sync_all_data
13349         cancel_lru_locks $OSC
13350         sleep 5
13351         bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
13352         want=$((OSTCOUNT * 1048576))
13353
13354         # Must allocate all requested space, not more than 5% extra
13355         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13356                 error "bytes $bytes is not $want"
13357 }
13358 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
13359
13360 #LU-2902 roc_hit was not able to read all values from lproc
13361 function roc_hit_init() {
13362         local list=$(comma_list $(osts_nodes))
13363         local dir=$DIR/$tdir-check
13364         local file=$dir/$tfile
13365         local BEFORE
13366         local AFTER
13367         local idx
13368
13369         test_mkdir $dir
13370         #use setstripe to do a write to every ost
13371         for i in $(seq 0 $((OSTCOUNT-1))); do
13372                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
13373                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
13374                 idx=$(printf %04x $i)
13375                 BEFORE=$(get_osd_param $list *OST*$idx stats |
13376                         awk '$1 == "cache_access" {sum += $7}
13377                                 END { printf("%0.0f", sum) }')
13378
13379                 cancel_lru_locks osc
13380                 cat $file >/dev/null
13381
13382                 AFTER=$(get_osd_param $list *OST*$idx stats |
13383                         awk '$1 == "cache_access" {sum += $7}
13384                                 END { printf("%0.0f", sum) }')
13385
13386                 echo BEFORE:$BEFORE AFTER:$AFTER
13387                 if ! let "AFTER - BEFORE == 4"; then
13388                         rm -rf $dir
13389                         error "roc_hit is not safe to use"
13390                 fi
13391                 rm $file
13392         done
13393
13394         rm -rf $dir
13395 }
13396
13397 function roc_hit() {
13398         local list=$(comma_list $(osts_nodes))
13399         echo $(get_osd_param $list '' stats |
13400                 awk '$1 == "cache_hit" {sum += $7}
13401                         END { printf("%0.0f", sum) }')
13402 }
13403
13404 function set_cache() {
13405         local on=1
13406
13407         if [ "$2" == "off" ]; then
13408                 on=0;
13409         fi
13410         local list=$(comma_list $(osts_nodes))
13411         set_osd_param $list '' $1_cache_enable $on
13412
13413         cancel_lru_locks osc
13414 }
13415
13416 test_151() {
13417         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13418         remote_ost_nodsh && skip "remote OST with nodsh"
13419
13420         local CPAGES=3
13421         local list=$(comma_list $(osts_nodes))
13422
13423         # check whether obdfilter is cache capable at all
13424         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
13425                 skip "not cache-capable obdfilter"
13426         fi
13427
13428         # check cache is enabled on all obdfilters
13429         if get_osd_param $list '' read_cache_enable | grep 0; then
13430                 skip "oss cache is disabled"
13431         fi
13432
13433         set_osd_param $list '' writethrough_cache_enable 1
13434
13435         # check write cache is enabled on all obdfilters
13436         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
13437                 skip "oss write cache is NOT enabled"
13438         fi
13439
13440         roc_hit_init
13441
13442         #define OBD_FAIL_OBD_NO_LRU  0x609
13443         do_nodes $list $LCTL set_param fail_loc=0x609
13444
13445         # pages should be in the case right after write
13446         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
13447                 error "dd failed"
13448
13449         local BEFORE=$(roc_hit)
13450         cancel_lru_locks osc
13451         cat $DIR/$tfile >/dev/null
13452         local AFTER=$(roc_hit)
13453
13454         do_nodes $list $LCTL set_param fail_loc=0
13455
13456         if ! let "AFTER - BEFORE == CPAGES"; then
13457                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
13458         fi
13459
13460         cancel_lru_locks osc
13461         # invalidates OST cache
13462         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
13463         set_osd_param $list '' read_cache_enable 0
13464         cat $DIR/$tfile >/dev/null
13465
13466         # now data shouldn't be found in the cache
13467         BEFORE=$(roc_hit)
13468         cancel_lru_locks osc
13469         cat $DIR/$tfile >/dev/null
13470         AFTER=$(roc_hit)
13471         if let "AFTER - BEFORE != 0"; then
13472                 error "IN CACHE: before: $BEFORE, after: $AFTER"
13473         fi
13474
13475         set_osd_param $list '' read_cache_enable 1
13476         rm -f $DIR/$tfile
13477 }
13478 run_test 151 "test cache on oss and controls ==============================="
13479
13480 test_152() {
13481         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13482
13483         local TF="$TMP/$tfile"
13484
13485         # simulate ENOMEM during write
13486 #define OBD_FAIL_OST_NOMEM      0x226
13487         lctl set_param fail_loc=0x80000226
13488         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13489         cp $TF $DIR/$tfile
13490         sync || error "sync failed"
13491         lctl set_param fail_loc=0
13492
13493         # discard client's cache
13494         cancel_lru_locks osc
13495
13496         # simulate ENOMEM during read
13497         lctl set_param fail_loc=0x80000226
13498         cmp $TF $DIR/$tfile || error "cmp failed"
13499         lctl set_param fail_loc=0
13500
13501         rm -f $TF
13502 }
13503 run_test 152 "test read/write with enomem ============================"
13504
13505 test_153() {
13506         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
13507 }
13508 run_test 153 "test if fdatasync does not crash ======================="
13509
13510 dot_lustre_fid_permission_check() {
13511         local fid=$1
13512         local ffid=$MOUNT/.lustre/fid/$fid
13513         local test_dir=$2
13514
13515         echo "stat fid $fid"
13516         stat $ffid > /dev/null || error "stat $ffid failed."
13517         echo "touch fid $fid"
13518         touch $ffid || error "touch $ffid failed."
13519         echo "write to fid $fid"
13520         cat /etc/hosts > $ffid || error "write $ffid failed."
13521         echo "read fid $fid"
13522         diff /etc/hosts $ffid || error "read $ffid failed."
13523         echo "append write to fid $fid"
13524         cat /etc/hosts >> $ffid || error "append write $ffid failed."
13525         echo "rename fid $fid"
13526         mv $ffid $test_dir/$tfile.1 &&
13527                 error "rename $ffid to $tfile.1 should fail."
13528         touch $test_dir/$tfile.1
13529         mv $test_dir/$tfile.1 $ffid &&
13530                 error "rename $tfile.1 to $ffid should fail."
13531         rm -f $test_dir/$tfile.1
13532         echo "truncate fid $fid"
13533         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
13534         echo "link fid $fid"
13535         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
13536         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
13537                 echo "setfacl fid $fid"
13538                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
13539                 echo "getfacl fid $fid"
13540                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
13541         fi
13542         echo "unlink fid $fid"
13543         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
13544         echo "mknod fid $fid"
13545         mknod $ffid c 1 3 && error "mknod $ffid should fail."
13546
13547         fid=[0xf00000400:0x1:0x0]
13548         ffid=$MOUNT/.lustre/fid/$fid
13549
13550         echo "stat non-exist fid $fid"
13551         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
13552         echo "write to non-exist fid $fid"
13553         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
13554         echo "link new fid $fid"
13555         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
13556
13557         mkdir -p $test_dir/$tdir
13558         touch $test_dir/$tdir/$tfile
13559         fid=$($LFS path2fid $test_dir/$tdir)
13560         rc=$?
13561         [ $rc -ne 0 ] &&
13562                 error "error: could not get fid for $test_dir/$dir/$tfile."
13563
13564         ffid=$MOUNT/.lustre/fid/$fid
13565
13566         echo "ls $fid"
13567         ls $ffid > /dev/null || error "ls $ffid failed."
13568         echo "touch $fid/$tfile.1"
13569         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
13570
13571         echo "touch $MOUNT/.lustre/fid/$tfile"
13572         touch $MOUNT/.lustre/fid/$tfile && \
13573                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
13574
13575         echo "setxattr to $MOUNT/.lustre/fid"
13576         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
13577
13578         echo "listxattr for $MOUNT/.lustre/fid"
13579         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
13580
13581         echo "delxattr from $MOUNT/.lustre/fid"
13582         setfattr -x trusted.name1 $MOUNT/.lustre/fid
13583
13584         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
13585         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
13586                 error "touch invalid fid should fail."
13587
13588         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
13589         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
13590                 error "touch non-normal fid should fail."
13591
13592         echo "rename $tdir to $MOUNT/.lustre/fid"
13593         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
13594                 error "rename to $MOUNT/.lustre/fid should fail."
13595
13596         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
13597         then            # LU-3547
13598                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
13599                 local new_obf_mode=777
13600
13601                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
13602                 chmod $new_obf_mode $DIR/.lustre/fid ||
13603                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
13604
13605                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
13606                 [ $obf_mode -eq $new_obf_mode ] ||
13607                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
13608
13609                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
13610                 chmod $old_obf_mode $DIR/.lustre/fid ||
13611                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
13612         fi
13613
13614         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
13615         fid=$($LFS path2fid $test_dir/$tfile-2)
13616
13617         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
13618         then # LU-5424
13619                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
13620                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
13621                         error "create lov data thru .lustre failed"
13622         fi
13623         echo "cp /etc/passwd $test_dir/$tfile-2"
13624         cp /etc/passwd $test_dir/$tfile-2 ||
13625                 error "copy to $test_dir/$tfile-2 failed."
13626         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
13627         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
13628                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
13629
13630         rm -rf $test_dir/tfile.lnk
13631         rm -rf $test_dir/$tfile-2
13632 }
13633
13634 test_154A() {
13635         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13636                 skip "Need MDS version at least 2.4.1"
13637
13638         local tf=$DIR/$tfile
13639         touch $tf
13640
13641         local fid=$($LFS path2fid $tf)
13642         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
13643
13644         # check that we get the same pathname back
13645         local rootpath
13646         local found
13647         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
13648                 echo "$rootpath $fid"
13649                 found=$($LFS fid2path $rootpath "$fid")
13650                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
13651                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
13652         done
13653
13654         # check wrong root path format
13655         rootpath=$MOUNT"_wrong"
13656         found=$($LFS fid2path $rootpath "$fid")
13657         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
13658 }
13659 run_test 154A "lfs path2fid and fid2path basic checks"
13660
13661 test_154B() {
13662         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13663                 skip "Need MDS version at least 2.4.1"
13664
13665         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
13666         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
13667         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
13668         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
13669
13670         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
13671         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
13672
13673         # check that we get the same pathname
13674         echo "PFID: $PFID, name: $name"
13675         local FOUND=$($LFS fid2path $MOUNT "$PFID")
13676         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
13677         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
13678                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
13679
13680         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
13681 }
13682 run_test 154B "verify the ll_decode_linkea tool"
13683
13684 test_154a() {
13685         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13686         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13687         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
13688                 skip "Need MDS version at least 2.2.51"
13689         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13690
13691         cp /etc/hosts $DIR/$tfile
13692
13693         fid=$($LFS path2fid $DIR/$tfile)
13694         rc=$?
13695         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
13696
13697         dot_lustre_fid_permission_check "$fid" $DIR ||
13698                 error "dot lustre permission check $fid failed"
13699
13700         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
13701
13702         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
13703
13704         touch $MOUNT/.lustre/file &&
13705                 error "creation is not allowed under .lustre"
13706
13707         mkdir $MOUNT/.lustre/dir &&
13708                 error "mkdir is not allowed under .lustre"
13709
13710         rm -rf $DIR/$tfile
13711 }
13712 run_test 154a "Open-by-FID"
13713
13714 test_154b() {
13715         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13716         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13717         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13718         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
13719                 skip "Need MDS version at least 2.2.51"
13720
13721         local remote_dir=$DIR/$tdir/remote_dir
13722         local MDTIDX=1
13723         local rc=0
13724
13725         mkdir -p $DIR/$tdir
13726         $LFS mkdir -i $MDTIDX $remote_dir ||
13727                 error "create remote directory failed"
13728
13729         cp /etc/hosts $remote_dir/$tfile
13730
13731         fid=$($LFS path2fid $remote_dir/$tfile)
13732         rc=$?
13733         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
13734
13735         dot_lustre_fid_permission_check "$fid" $remote_dir ||
13736                 error "dot lustre permission check $fid failed"
13737         rm -rf $DIR/$tdir
13738 }
13739 run_test 154b "Open-by-FID for remote directory"
13740
13741 test_154c() {
13742         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13743                 skip "Need MDS version at least 2.4.1"
13744
13745         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
13746         local FID1=$($LFS path2fid $DIR/$tfile.1)
13747         local FID2=$($LFS path2fid $DIR/$tfile.2)
13748         local FID3=$($LFS path2fid $DIR/$tfile.3)
13749
13750         local N=1
13751         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
13752                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
13753                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
13754                 local want=FID$N
13755                 [ "$FID" = "${!want}" ] ||
13756                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
13757                 N=$((N + 1))
13758         done
13759
13760         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
13761         do
13762                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
13763                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
13764                 N=$((N + 1))
13765         done
13766 }
13767 run_test 154c "lfs path2fid and fid2path multiple arguments"
13768
13769 test_154d() {
13770         remote_mds_nodsh && skip "remote MDS with nodsh"
13771         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
13772                 skip "Need MDS version at least 2.5.53"
13773
13774         if remote_mds; then
13775                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
13776         else
13777                 nid="0@lo"
13778         fi
13779         local proc_ofile="mdt.*.exports.'$nid'.open_files"
13780         local fd
13781         local cmd
13782
13783         rm -f $DIR/$tfile
13784         touch $DIR/$tfile
13785
13786         local fid=$($LFS path2fid $DIR/$tfile)
13787         # Open the file
13788         fd=$(free_fd)
13789         cmd="exec $fd<$DIR/$tfile"
13790         eval $cmd
13791         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
13792         echo "$fid_list" | grep "$fid"
13793         rc=$?
13794
13795         cmd="exec $fd>/dev/null"
13796         eval $cmd
13797         if [ $rc -ne 0 ]; then
13798                 error "FID $fid not found in open files list $fid_list"
13799         fi
13800 }
13801 run_test 154d "Verify open file fid"
13802
13803 test_154e()
13804 {
13805         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
13806                 skip "Need MDS version at least 2.6.50"
13807
13808         if ls -a $MOUNT | grep -q '^\.lustre$'; then
13809                 error ".lustre returned by readdir"
13810         fi
13811 }
13812 run_test 154e ".lustre is not returned by readdir"
13813
13814 test_154f() {
13815         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13816
13817         # create parent directory on a single MDT to avoid cross-MDT hardlinks
13818         test_mkdir -p -c1 $DIR/$tdir/d
13819         # test dirs inherit from its stripe
13820         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
13821         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
13822         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
13823         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
13824         touch $DIR/f
13825
13826         # get fid of parents
13827         local FID0=$($LFS path2fid $DIR/$tdir/d)
13828         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
13829         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
13830         local FID3=$($LFS path2fid $DIR)
13831
13832         # check that path2fid --parents returns expected <parent_fid>/name
13833         # 1) test for a directory (single parent)
13834         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
13835         [ "$parent" == "$FID0/foo1" ] ||
13836                 error "expected parent: $FID0/foo1, got: $parent"
13837
13838         # 2) test for a file with nlink > 1 (multiple parents)
13839         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
13840         echo "$parent" | grep -F "$FID1/$tfile" ||
13841                 error "$FID1/$tfile not returned in parent list"
13842         echo "$parent" | grep -F "$FID2/link" ||
13843                 error "$FID2/link not returned in parent list"
13844
13845         # 3) get parent by fid
13846         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
13847         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13848         echo "$parent" | grep -F "$FID1/$tfile" ||
13849                 error "$FID1/$tfile not returned in parent list (by fid)"
13850         echo "$parent" | grep -F "$FID2/link" ||
13851                 error "$FID2/link not returned in parent list (by fid)"
13852
13853         # 4) test for entry in root directory
13854         parent=$($LFS path2fid --parents $DIR/f)
13855         echo "$parent" | grep -F "$FID3/f" ||
13856                 error "$FID3/f not returned in parent list"
13857
13858         # 5) test it on root directory
13859         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
13860                 error "$MOUNT should not have parents"
13861
13862         # enable xattr caching and check that linkea is correctly updated
13863         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
13864         save_lustre_params client "llite.*.xattr_cache" > $save
13865         lctl set_param llite.*.xattr_cache 1
13866
13867         # 6.1) linkea update on rename
13868         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
13869
13870         # get parents by fid
13871         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13872         # foo1 should no longer be returned in parent list
13873         echo "$parent" | grep -F "$FID1" &&
13874                 error "$FID1 should no longer be in parent list"
13875         # the new path should appear
13876         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
13877                 error "$FID2/$tfile.moved is not in parent list"
13878
13879         # 6.2) linkea update on unlink
13880         rm -f $DIR/$tdir/d/foo2/link
13881         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13882         # foo2/link should no longer be returned in parent list
13883         echo "$parent" | grep -F "$FID2/link" &&
13884                 error "$FID2/link should no longer be in parent list"
13885         true
13886
13887         rm -f $DIR/f
13888         restore_lustre_params < $save
13889         rm -f $save
13890 }
13891 run_test 154f "get parent fids by reading link ea"
13892
13893 test_154g()
13894 {
13895         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13896         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
13897            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
13898                 skip "Need MDS version at least 2.6.92"
13899
13900         mkdir -p $DIR/$tdir
13901         llapi_fid_test -d $DIR/$tdir
13902 }
13903 run_test 154g "various llapi FID tests"
13904
13905 test_155_small_load() {
13906     local temp=$TMP/$tfile
13907     local file=$DIR/$tfile
13908
13909     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
13910         error "dd of=$temp bs=6096 count=1 failed"
13911     cp $temp $file
13912     cancel_lru_locks $OSC
13913     cmp $temp $file || error "$temp $file differ"
13914
13915     $TRUNCATE $temp 6000
13916     $TRUNCATE $file 6000
13917     cmp $temp $file || error "$temp $file differ (truncate1)"
13918
13919     echo "12345" >>$temp
13920     echo "12345" >>$file
13921     cmp $temp $file || error "$temp $file differ (append1)"
13922
13923     echo "12345" >>$temp
13924     echo "12345" >>$file
13925     cmp $temp $file || error "$temp $file differ (append2)"
13926
13927     rm -f $temp $file
13928     true
13929 }
13930
13931 test_155_big_load() {
13932         remote_ost_nodsh && skip "remote OST with nodsh"
13933
13934         local temp=$TMP/$tfile
13935         local file=$DIR/$tfile
13936
13937         free_min_max
13938         local cache_size=$(do_facet ost$((MAXI+1)) \
13939                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
13940         local large_file_size=$((cache_size * 2))
13941
13942         echo "OSS cache size: $cache_size KB"
13943         echo "Large file size: $large_file_size KB"
13944
13945         [ $MAXV -le $large_file_size ] &&
13946                 skip_env "max available OST size needs > $large_file_size KB"
13947
13948         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
13949
13950         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
13951                 error "dd of=$temp bs=$large_file_size count=1k failed"
13952         cp $temp $file
13953         ls -lh $temp $file
13954         cancel_lru_locks osc
13955         cmp $temp $file || error "$temp $file differ"
13956
13957         rm -f $temp $file
13958         true
13959 }
13960
13961 save_writethrough() {
13962         local facets=$(get_facets OST)
13963
13964         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
13965 }
13966
13967 test_155a() {
13968         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13969
13970         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13971
13972         save_writethrough $p
13973
13974         set_cache read on
13975         set_cache writethrough on
13976         test_155_small_load
13977         restore_lustre_params < $p
13978         rm -f $p
13979 }
13980 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
13981
13982 test_155b() {
13983         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13984
13985         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13986
13987         save_writethrough $p
13988
13989         set_cache read on
13990         set_cache writethrough off
13991         test_155_small_load
13992         restore_lustre_params < $p
13993         rm -f $p
13994 }
13995 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
13996
13997 test_155c() {
13998         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13999
14000         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14001
14002         save_writethrough $p
14003
14004         set_cache read off
14005         set_cache writethrough on
14006         test_155_small_load
14007         restore_lustre_params < $p
14008         rm -f $p
14009 }
14010 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
14011
14012 test_155d() {
14013         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14014
14015         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14016
14017         save_writethrough $p
14018
14019         set_cache read off
14020         set_cache writethrough off
14021         test_155_small_load
14022         restore_lustre_params < $p
14023         rm -f $p
14024 }
14025 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
14026
14027 test_155e() {
14028         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14029
14030         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14031
14032         save_writethrough $p
14033
14034         set_cache read on
14035         set_cache writethrough on
14036         test_155_big_load
14037         restore_lustre_params < $p
14038         rm -f $p
14039 }
14040 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
14041
14042 test_155f() {
14043         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14044
14045         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14046
14047         save_writethrough $p
14048
14049         set_cache read on
14050         set_cache writethrough off
14051         test_155_big_load
14052         restore_lustre_params < $p
14053         rm -f $p
14054 }
14055 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
14056
14057 test_155g() {
14058         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14059
14060         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14061
14062         save_writethrough $p
14063
14064         set_cache read off
14065         set_cache writethrough on
14066         test_155_big_load
14067         restore_lustre_params < $p
14068         rm -f $p
14069 }
14070 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
14071
14072 test_155h() {
14073         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14074
14075         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14076
14077         save_writethrough $p
14078
14079         set_cache read off
14080         set_cache writethrough off
14081         test_155_big_load
14082         restore_lustre_params < $p
14083         rm -f $p
14084 }
14085 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
14086
14087 test_156() {
14088         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14089         remote_ost_nodsh && skip "remote OST with nodsh"
14090         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
14091                 skip "stats not implemented on old servers"
14092         [ "$ost1_FSTYPE" = "zfs" ] &&
14093                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
14094
14095         local CPAGES=3
14096         local BEFORE
14097         local AFTER
14098         local file="$DIR/$tfile"
14099         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14100
14101         save_writethrough $p
14102         roc_hit_init
14103
14104         log "Turn on read and write cache"
14105         set_cache read on
14106         set_cache writethrough on
14107
14108         log "Write data and read it back."
14109         log "Read should be satisfied from the cache."
14110         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14111         BEFORE=$(roc_hit)
14112         cancel_lru_locks osc
14113         cat $file >/dev/null
14114         AFTER=$(roc_hit)
14115         if ! let "AFTER - BEFORE == CPAGES"; then
14116                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
14117         else
14118                 log "cache hits: before: $BEFORE, after: $AFTER"
14119         fi
14120
14121         log "Read again; it should be satisfied from the cache."
14122         BEFORE=$AFTER
14123         cancel_lru_locks osc
14124         cat $file >/dev/null
14125         AFTER=$(roc_hit)
14126         if ! let "AFTER - BEFORE == CPAGES"; then
14127                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
14128         else
14129                 log "cache hits:: before: $BEFORE, after: $AFTER"
14130         fi
14131
14132         log "Turn off the read cache and turn on the write cache"
14133         set_cache read off
14134         set_cache writethrough on
14135
14136         log "Read again; it should be satisfied from the cache."
14137         BEFORE=$(roc_hit)
14138         cancel_lru_locks osc
14139         cat $file >/dev/null
14140         AFTER=$(roc_hit)
14141         if ! let "AFTER - BEFORE == CPAGES"; then
14142                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
14143         else
14144                 log "cache hits:: before: $BEFORE, after: $AFTER"
14145         fi
14146
14147         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14148                 # > 2.12.56 uses pagecache if cached
14149                 log "Read again; it should not be satisfied from the cache."
14150                 BEFORE=$AFTER
14151                 cancel_lru_locks osc
14152                 cat $file >/dev/null
14153                 AFTER=$(roc_hit)
14154                 if ! let "AFTER - BEFORE == 0"; then
14155                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
14156                 else
14157                         log "cache hits:: before: $BEFORE, after: $AFTER"
14158                 fi
14159         fi
14160
14161         log "Write data and read it back."
14162         log "Read should be satisfied from the cache."
14163         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14164         BEFORE=$(roc_hit)
14165         cancel_lru_locks osc
14166         cat $file >/dev/null
14167         AFTER=$(roc_hit)
14168         if ! let "AFTER - BEFORE == CPAGES"; then
14169                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
14170         else
14171                 log "cache hits:: before: $BEFORE, after: $AFTER"
14172         fi
14173
14174         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14175                 # > 2.12.56 uses pagecache if cached
14176                 log "Read again; it should not be satisfied from the cache."
14177                 BEFORE=$AFTER
14178                 cancel_lru_locks osc
14179                 cat $file >/dev/null
14180                 AFTER=$(roc_hit)
14181                 if ! let "AFTER - BEFORE == 0"; then
14182                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
14183                 else
14184                         log "cache hits:: before: $BEFORE, after: $AFTER"
14185                 fi
14186         fi
14187
14188         log "Turn off read and write cache"
14189         set_cache read off
14190         set_cache writethrough off
14191
14192         log "Write data and read it back"
14193         log "It should not be satisfied from the cache."
14194         rm -f $file
14195         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14196         cancel_lru_locks osc
14197         BEFORE=$(roc_hit)
14198         cat $file >/dev/null
14199         AFTER=$(roc_hit)
14200         if ! let "AFTER - BEFORE == 0"; then
14201                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
14202         else
14203                 log "cache hits:: before: $BEFORE, after: $AFTER"
14204         fi
14205
14206         log "Turn on the read cache and turn off the write cache"
14207         set_cache read on
14208         set_cache writethrough off
14209
14210         log "Write data and read it back"
14211         log "It should not be satisfied from the cache."
14212         rm -f $file
14213         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14214         BEFORE=$(roc_hit)
14215         cancel_lru_locks osc
14216         cat $file >/dev/null
14217         AFTER=$(roc_hit)
14218         if ! let "AFTER - BEFORE == 0"; then
14219                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
14220         else
14221                 log "cache hits:: before: $BEFORE, after: $AFTER"
14222         fi
14223
14224         log "Read again; it should be satisfied from the cache."
14225         BEFORE=$(roc_hit)
14226         cancel_lru_locks osc
14227         cat $file >/dev/null
14228         AFTER=$(roc_hit)
14229         if ! let "AFTER - BEFORE == CPAGES"; then
14230                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
14231         else
14232                 log "cache hits:: before: $BEFORE, after: $AFTER"
14233         fi
14234
14235         restore_lustre_params < $p
14236         rm -f $p $file
14237 }
14238 run_test 156 "Verification of tunables"
14239
14240 test_160a() {
14241         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14242         remote_mds_nodsh && skip "remote MDS with nodsh"
14243         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14244                 skip "Need MDS version at least 2.2.0"
14245
14246         changelog_register || error "changelog_register failed"
14247         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14248         changelog_users $SINGLEMDS | grep -q $cl_user ||
14249                 error "User $cl_user not found in changelog_users"
14250
14251         # change something
14252         test_mkdir -p $DIR/$tdir/pics/2008/zachy
14253         changelog_clear 0 || error "changelog_clear failed"
14254         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
14255         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
14256         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
14257         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
14258         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
14259         rm $DIR/$tdir/pics/desktop.jpg
14260
14261         changelog_dump | tail -10
14262
14263         echo "verifying changelog mask"
14264         changelog_chmask "-MKDIR"
14265         changelog_chmask "-CLOSE"
14266
14267         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
14268         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
14269
14270         changelog_chmask "+MKDIR"
14271         changelog_chmask "+CLOSE"
14272
14273         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
14274         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
14275
14276         changelog_dump | tail -10
14277         MKDIRS=$(changelog_dump | grep -c "MKDIR")
14278         CLOSES=$(changelog_dump | grep -c "CLOSE")
14279         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
14280         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
14281
14282         # verify contents
14283         echo "verifying target fid"
14284         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
14285         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
14286         [ "$fidc" == "$fidf" ] ||
14287                 error "changelog '$tfile' fid $fidc != file fid $fidf"
14288         echo "verifying parent fid"
14289         # The FID returned from the Changelog may be the directory shard on
14290         # a different MDT, and not the FID returned by path2fid on the parent.
14291         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
14292         # since this is what will matter when recreating this file in the tree.
14293         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
14294         local pathp=$($LFS fid2path $MOUNT "$fidp")
14295         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
14296                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
14297
14298         echo "getting records for $cl_user"
14299         changelog_users $SINGLEMDS
14300         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
14301         local nclr=3
14302         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
14303                 error "changelog_clear failed"
14304         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
14305         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
14306         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
14307                 error "user index expect $user_rec1 + $nclr != $user_rec2"
14308
14309         local min0_rec=$(changelog_users $SINGLEMDS |
14310                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
14311         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
14312                           awk '{ print $1; exit; }')
14313
14314         changelog_dump | tail -n 5
14315         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
14316         [ $first_rec == $((min0_rec + 1)) ] ||
14317                 error "first index should be $min0_rec + 1 not $first_rec"
14318
14319         # LU-3446 changelog index reset on MDT restart
14320         local cur_rec1=$(changelog_users $SINGLEMDS |
14321                          awk '/^current.index:/ { print $NF }')
14322         changelog_clear 0 ||
14323                 error "clear all changelog records for $cl_user failed"
14324         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
14325         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
14326                 error "Fail to start $SINGLEMDS"
14327         local cur_rec2=$(changelog_users $SINGLEMDS |
14328                          awk '/^current.index:/ { print $NF }')
14329         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
14330         [ $cur_rec1 == $cur_rec2 ] ||
14331                 error "current index should be $cur_rec1 not $cur_rec2"
14332
14333         echo "verifying users from this test are deregistered"
14334         changelog_deregister || error "changelog_deregister failed"
14335         changelog_users $SINGLEMDS | grep -q $cl_user &&
14336                 error "User '$cl_user' still in changelog_users"
14337
14338         # lctl get_param -n mdd.*.changelog_users
14339         # current index: 144
14340         # ID    index (idle seconds)
14341         # cl3   144 (2)
14342         if ! changelog_users $SINGLEMDS | grep "^cl"; then
14343                 # this is the normal case where all users were deregistered
14344                 # make sure no new records are added when no users are present
14345                 local last_rec1=$(changelog_users $SINGLEMDS |
14346                                   awk '/^current.index:/ { print $NF }')
14347                 touch $DIR/$tdir/chloe
14348                 local last_rec2=$(changelog_users $SINGLEMDS |
14349                                   awk '/^current.index:/ { print $NF }')
14350                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
14351                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
14352         else
14353                 # any changelog users must be leftovers from a previous test
14354                 changelog_users $SINGLEMDS
14355                 echo "other changelog users; can't verify off"
14356         fi
14357 }
14358 run_test 160a "changelog sanity"
14359
14360 test_160b() { # LU-3587
14361         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14362         remote_mds_nodsh && skip "remote MDS with nodsh"
14363         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14364                 skip "Need MDS version at least 2.2.0"
14365
14366         changelog_register || error "changelog_register failed"
14367         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14368         changelog_users $SINGLEMDS | grep -q $cl_user ||
14369                 error "User '$cl_user' not found in changelog_users"
14370
14371         local longname1=$(str_repeat a 255)
14372         local longname2=$(str_repeat b 255)
14373
14374         cd $DIR
14375         echo "creating very long named file"
14376         touch $longname1 || error "create of '$longname1' failed"
14377         echo "renaming very long named file"
14378         mv $longname1 $longname2
14379
14380         changelog_dump | grep RENME | tail -n 5
14381         rm -f $longname2
14382 }
14383 run_test 160b "Verify that very long rename doesn't crash in changelog"
14384
14385 test_160c() {
14386         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14387         remote_mds_nodsh && skip "remote MDS with nodsh"
14388
14389         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
14390                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
14391                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
14392                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
14393
14394         local rc=0
14395
14396         # Registration step
14397         changelog_register || error "changelog_register failed"
14398
14399         rm -rf $DIR/$tdir
14400         mkdir -p $DIR/$tdir
14401         $MCREATE $DIR/$tdir/foo_160c
14402         changelog_chmask "-TRUNC"
14403         $TRUNCATE $DIR/$tdir/foo_160c 200
14404         changelog_chmask "+TRUNC"
14405         $TRUNCATE $DIR/$tdir/foo_160c 199
14406         changelog_dump | tail -n 5
14407         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
14408         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
14409 }
14410 run_test 160c "verify that changelog log catch the truncate event"
14411
14412 test_160d() {
14413         remote_mds_nodsh && skip "remote MDS with nodsh"
14414         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14415         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14416         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
14417                 skip "Need MDS version at least 2.7.60"
14418
14419         # Registration step
14420         changelog_register || error "changelog_register failed"
14421
14422         mkdir -p $DIR/$tdir/migrate_dir
14423         changelog_clear 0 || error "changelog_clear failed"
14424
14425         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
14426         changelog_dump | tail -n 5
14427         local migrates=$(changelog_dump | grep -c "MIGRT")
14428         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
14429 }
14430 run_test 160d "verify that changelog log catch the migrate event"
14431
14432 test_160e() {
14433         remote_mds_nodsh && skip "remote MDS with nodsh"
14434
14435         # Create a user
14436         changelog_register || error "changelog_register failed"
14437
14438         # Delete a future user (expect fail)
14439         local MDT0=$(facet_svc $SINGLEMDS)
14440         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
14441         local rc=$?
14442
14443         if [ $rc -eq 0 ]; then
14444                 error "Deleted non-existant user cl77"
14445         elif [ $rc -ne 2 ]; then
14446                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
14447         fi
14448
14449         # Clear to a bad index (1 billion should be safe)
14450         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
14451         rc=$?
14452
14453         if [ $rc -eq 0 ]; then
14454                 error "Successfully cleared to invalid CL index"
14455         elif [ $rc -ne 22 ]; then
14456                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
14457         fi
14458 }
14459 run_test 160e "changelog negative testing (should return errors)"
14460
14461 test_160f() {
14462         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14463         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14464                 skip "Need MDS version at least 2.10.56"
14465
14466         local mdts=$(comma_list $(mdts_nodes))
14467
14468         # Create a user
14469         changelog_register || error "first changelog_register failed"
14470         changelog_register || error "second changelog_register failed"
14471         local cl_users
14472         declare -A cl_user1
14473         declare -A cl_user2
14474         local user_rec1
14475         local user_rec2
14476         local i
14477
14478         # generate some changelog records to accumulate on each MDT
14479         # use fnv1a because created files should be evenly distributed
14480         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14481                 error "test_mkdir $tdir failed"
14482         log "$(date +%s): creating first files"
14483         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14484                 error "create $DIR/$tdir/$tfile failed"
14485
14486         # check changelogs have been generated
14487         local start=$SECONDS
14488         local idle_time=$((MDSCOUNT * 5 + 5))
14489         local nbcl=$(changelog_dump | wc -l)
14490         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14491
14492         for param in "changelog_max_idle_time=$idle_time" \
14493                      "changelog_gc=1" \
14494                      "changelog_min_gc_interval=2" \
14495                      "changelog_min_free_cat_entries=3"; do
14496                 local MDT0=$(facet_svc $SINGLEMDS)
14497                 local var="${param%=*}"
14498                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14499
14500                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14501                 do_nodes $mdts $LCTL set_param mdd.*.$param
14502         done
14503
14504         # force cl_user2 to be idle (1st part), but also cancel the
14505         # cl_user1 records so that it is not evicted later in the test.
14506         local sleep1=$((idle_time / 2))
14507         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
14508         sleep $sleep1
14509
14510         # simulate changelog catalog almost full
14511         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
14512         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
14513
14514         for i in $(seq $MDSCOUNT); do
14515                 cl_users=(${CL_USERS[mds$i]})
14516                 cl_user1[mds$i]="${cl_users[0]}"
14517                 cl_user2[mds$i]="${cl_users[1]}"
14518
14519                 [ -n "${cl_user1[mds$i]}" ] ||
14520                         error "mds$i: no user registered"
14521                 [ -n "${cl_user2[mds$i]}" ] ||
14522                         error "mds$i: only ${cl_user2[mds$i]} is registered"
14523
14524                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14525                 [ -n "$user_rec1" ] ||
14526                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14527                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14528                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14529                 [ -n "$user_rec2" ] ||
14530                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14531                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14532                      "$user_rec1 + 2 == $user_rec2"
14533                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14534                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14535                               "$user_rec1 + 2, but is $user_rec2"
14536                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14537                 [ -n "$user_rec2" ] ||
14538                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14539                 [ $user_rec1 == $user_rec2 ] ||
14540                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14541                               "$user_rec1, but is $user_rec2"
14542         done
14543
14544         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
14545         local sleep2=$((idle_time - (SECONDS - start) + 1))
14546         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
14547         sleep $sleep2
14548
14549         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
14550         # cl_user1 should be OK because it recently processed records.
14551         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
14552         createmany -m $DIR/$tdir/${tfile}b $((MDSCOUNT * 2)) ||
14553                 error "create $DIR/$tdir/${tfile}b failed"
14554
14555         # ensure gc thread is done
14556         for i in $(mdts_nodes); do
14557                 wait_update $i \
14558                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
14559                         error "$i: GC-thread not done"
14560         done
14561
14562         local first_rec
14563         for i in $(seq $MDSCOUNT); do
14564                 # check cl_user1 still registered
14565                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14566                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14567                 # check cl_user2 unregistered
14568                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14569                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14570
14571                 # check changelogs are present and starting at $user_rec1 + 1
14572                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14573                 [ -n "$user_rec1" ] ||
14574                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14575                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14576                             awk '{ print $1; exit; }')
14577
14578                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14579                 [ $((user_rec1 + 1)) == $first_rec ] ||
14580                         error "mds$i: first index should be $user_rec1 + 1, " \
14581                               "but is $first_rec"
14582         done
14583 }
14584 run_test 160f "changelog garbage collect (timestamped users)"
14585
14586 test_160g() {
14587         remote_mds_nodsh && skip "remote MDS with nodsh"
14588         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14589                 skip "Need MDS version at least 2.10.56"
14590
14591         local mdts=$(comma_list $(mdts_nodes))
14592
14593         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
14594         do_nodes $mdts $LCTL set_param fail_loc=0x1314
14595
14596         # Create a user
14597         changelog_register || error "first changelog_register failed"
14598         changelog_register || error "second changelog_register failed"
14599         local cl_users
14600         declare -A cl_user1
14601         declare -A cl_user2
14602         local user_rec1
14603         local user_rec2
14604         local i
14605
14606         # generate some changelog records to accumulate on each MDT
14607         # use fnv1a because created files should be evenly distributed
14608         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14609                 error "mkdir $tdir failed"
14610         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14611                 error "create $DIR/$tdir/$tfile failed"
14612
14613         # check changelogs have been generated
14614         local nbcl=$(changelog_dump | wc -l)
14615         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14616
14617         # reduce the max_idle_indexes value to make sure we exceed it
14618         max_ndx=$((nbcl / 2 - 1))
14619
14620         for param in "changelog_max_idle_indexes=$max_ndx" \
14621                      "changelog_gc=1" \
14622                      "changelog_min_gc_interval=2" \
14623                      "changelog_min_free_cat_entries=3"; do
14624                 local MDT0=$(facet_svc $SINGLEMDS)
14625                 local var="${param%=*}"
14626                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14627
14628                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14629                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
14630                         error "unable to set mdd.*.$param"
14631         done
14632
14633         # simulate changelog catalog almost full
14634         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
14635         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
14636
14637         for i in $(seq $MDSCOUNT); do
14638                 cl_users=(${CL_USERS[mds$i]})
14639                 cl_user1[mds$i]="${cl_users[0]}"
14640                 cl_user2[mds$i]="${cl_users[1]}"
14641
14642                 [ -n "${cl_user1[mds$i]}" ] ||
14643                         error "mds$i: no user registered"
14644                 [ -n "${cl_user2[mds$i]}" ] ||
14645                         error "mds$i: only ${cl_user1[mds$i]} is registered"
14646
14647                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14648                 [ -n "$user_rec1" ] ||
14649                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14650                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14651                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14652                 [ -n "$user_rec2" ] ||
14653                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14654                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14655                      "$user_rec1 + 2 == $user_rec2"
14656                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14657                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14658                               "$user_rec1 + 2, but is $user_rec2"
14659                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14660                 [ -n "$user_rec2" ] ||
14661                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14662                 [ $user_rec1 == $user_rec2 ] ||
14663                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14664                               "$user_rec1, but is $user_rec2"
14665         done
14666
14667         # ensure we are past the previous changelog_min_gc_interval set above
14668         sleep 2
14669
14670         # generate one more changelog to trigger fail_loc
14671         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14672                 error "create $DIR/$tdir/${tfile}bis failed"
14673
14674         # ensure gc thread is done
14675         for i in $(mdts_nodes); do
14676                 wait_update $i \
14677                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
14678                         error "$i: GC-thread not done"
14679         done
14680
14681         local first_rec
14682         for i in $(seq $MDSCOUNT); do
14683                 # check cl_user1 still registered
14684                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14685                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14686                 # check cl_user2 unregistered
14687                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14688                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14689
14690                 # check changelogs are present and starting at $user_rec1 + 1
14691                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14692                 [ -n "$user_rec1" ] ||
14693                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14694                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14695                             awk '{ print $1; exit; }')
14696
14697                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14698                 [ $((user_rec1 + 1)) == $first_rec ] ||
14699                         error "mds$i: first index should be $user_rec1 + 1, " \
14700                               "but is $first_rec"
14701         done
14702 }
14703 run_test 160g "changelog garbage collect (old users)"
14704
14705 test_160h() {
14706         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14707         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14708                 skip "Need MDS version at least 2.10.56"
14709
14710         local mdts=$(comma_list $(mdts_nodes))
14711
14712         # Create a user
14713         changelog_register || error "first changelog_register failed"
14714         changelog_register || error "second changelog_register failed"
14715         local cl_users
14716         declare -A cl_user1
14717         declare -A cl_user2
14718         local user_rec1
14719         local user_rec2
14720         local i
14721
14722         # generate some changelog records to accumulate on each MDT
14723         # use fnv1a because created files should be evenly distributed
14724         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14725                 error "test_mkdir $tdir failed"
14726         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14727                 error "create $DIR/$tdir/$tfile failed"
14728
14729         # check changelogs have been generated
14730         local nbcl=$(changelog_dump | wc -l)
14731         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14732
14733         for param in "changelog_max_idle_time=10" \
14734                      "changelog_gc=1" \
14735                      "changelog_min_gc_interval=2"; do
14736                 local MDT0=$(facet_svc $SINGLEMDS)
14737                 local var="${param%=*}"
14738                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14739
14740                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14741                 do_nodes $mdts $LCTL set_param mdd.*.$param
14742         done
14743
14744         # force cl_user2 to be idle (1st part)
14745         sleep 9
14746
14747         for i in $(seq $MDSCOUNT); do
14748                 cl_users=(${CL_USERS[mds$i]})
14749                 cl_user1[mds$i]="${cl_users[0]}"
14750                 cl_user2[mds$i]="${cl_users[1]}"
14751
14752                 [ -n "${cl_user1[mds$i]}" ] ||
14753                         error "mds$i: no user registered"
14754                 [ -n "${cl_user2[mds$i]}" ] ||
14755                         error "mds$i: only ${cl_user2[mds$i]} is registered"
14756
14757                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14758                 [ -n "$user_rec1" ] ||
14759                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14760                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14761                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14762                 [ -n "$user_rec2" ] ||
14763                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14764                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14765                      "$user_rec1 + 2 == $user_rec2"
14766                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14767                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14768                               "$user_rec1 + 2, but is $user_rec2"
14769                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14770                 [ -n "$user_rec2" ] ||
14771                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14772                 [ $user_rec1 == $user_rec2 ] ||
14773                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14774                               "$user_rec1, but is $user_rec2"
14775         done
14776
14777         # force cl_user2 to be idle (2nd part) and to reach
14778         # changelog_max_idle_time
14779         sleep 2
14780
14781         # force each GC-thread start and block then
14782         # one per MDT/MDD, set fail_val accordingly
14783         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
14784         do_nodes $mdts $LCTL set_param fail_loc=0x1316
14785
14786         # generate more changelogs to trigger fail_loc
14787         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14788                 error "create $DIR/$tdir/${tfile}bis failed"
14789
14790         # stop MDT to stop GC-thread, should be done in back-ground as it will
14791         # block waiting for the thread to be released and exit
14792         declare -A stop_pids
14793         for i in $(seq $MDSCOUNT); do
14794                 stop mds$i &
14795                 stop_pids[mds$i]=$!
14796         done
14797
14798         for i in $(mdts_nodes); do
14799                 local facet
14800                 local nb=0
14801                 local facets=$(facets_up_on_host $i)
14802
14803                 for facet in ${facets//,/ }; do
14804                         if [[ $facet == mds* ]]; then
14805                                 nb=$((nb + 1))
14806                         fi
14807                 done
14808                 # ensure each MDS's gc threads are still present and all in "R"
14809                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
14810                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
14811                         error "$i: expected $nb GC-thread"
14812                 wait_update $i \
14813                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
14814                         "R" 20 ||
14815                         error "$i: GC-thread not found in R-state"
14816                 # check umounts of each MDT on MDS have reached kthread_stop()
14817                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
14818                         error "$i: expected $nb umount"
14819                 wait_update $i \
14820                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
14821                         error "$i: umount not found in D-state"
14822         done
14823
14824         # release all GC-threads
14825         do_nodes $mdts $LCTL set_param fail_loc=0
14826
14827         # wait for MDT stop to complete
14828         for i in $(seq $MDSCOUNT); do
14829                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
14830         done
14831
14832         # XXX
14833         # may try to check if any orphan changelog records are present
14834         # via ldiskfs/zfs and llog_reader...
14835
14836         # re-start/mount MDTs
14837         for i in $(seq $MDSCOUNT); do
14838                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
14839                         error "Fail to start mds$i"
14840         done
14841
14842         local first_rec
14843         for i in $(seq $MDSCOUNT); do
14844                 # check cl_user1 still registered
14845                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14846                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14847                 # check cl_user2 unregistered
14848                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14849                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14850
14851                 # check changelogs are present and starting at $user_rec1 + 1
14852                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14853                 [ -n "$user_rec1" ] ||
14854                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14855                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14856                             awk '{ print $1; exit; }')
14857
14858                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14859                 [ $((user_rec1 + 1)) == $first_rec ] ||
14860                         error "mds$i: first index should be $user_rec1 + 1, " \
14861                               "but is $first_rec"
14862         done
14863 }
14864 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
14865               "during mount"
14866
14867 test_160i() {
14868
14869         local mdts=$(comma_list $(mdts_nodes))
14870
14871         changelog_register || error "first changelog_register failed"
14872
14873         # generate some changelog records to accumulate on each MDT
14874         # use fnv1a because created files should be evenly distributed
14875         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14876                 error "mkdir $tdir failed"
14877         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14878                 error "create $DIR/$tdir/$tfile failed"
14879
14880         # check changelogs have been generated
14881         local nbcl=$(changelog_dump | wc -l)
14882         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14883
14884         # simulate race between register and unregister
14885         # XXX as fail_loc is set per-MDS, with DNE configs the race
14886         # simulation will only occur for one MDT per MDS and for the
14887         # others the normal race scenario will take place
14888         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
14889         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
14890         do_nodes $mdts $LCTL set_param fail_val=1
14891
14892         # unregister 1st user
14893         changelog_deregister &
14894         local pid1=$!
14895         # wait some time for deregister work to reach race rdv
14896         sleep 2
14897         # register 2nd user
14898         changelog_register || error "2nd user register failed"
14899
14900         wait $pid1 || error "1st user deregister failed"
14901
14902         local i
14903         local last_rec
14904         declare -A LAST_REC
14905         for i in $(seq $MDSCOUNT); do
14906                 if changelog_users mds$i | grep "^cl"; then
14907                         # make sure new records are added with one user present
14908                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
14909                                           awk '/^current.index:/ { print $NF }')
14910                 else
14911                         error "mds$i has no user registered"
14912                 fi
14913         done
14914
14915         # generate more changelog records to accumulate on each MDT
14916         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14917                 error "create $DIR/$tdir/${tfile}bis failed"
14918
14919         for i in $(seq $MDSCOUNT); do
14920                 last_rec=$(changelog_users $SINGLEMDS |
14921                            awk '/^current.index:/ { print $NF }')
14922                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
14923                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
14924                         error "changelogs are off on mds$i"
14925         done
14926 }
14927 run_test 160i "changelog user register/unregister race"
14928
14929 test_160j() {
14930         remote_mds_nodsh && skip "remote MDS with nodsh"
14931         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
14932                 skip "Need MDS version at least 2.12.56"
14933
14934         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
14935         stack_trap "umount $MOUNT2" EXIT
14936
14937         changelog_register || error "first changelog_register failed"
14938         stack_trap "changelog_deregister" EXIT
14939
14940         # generate some changelog
14941         # use fnv1a because created files should be evenly distributed
14942         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14943                 error "mkdir $tdir failed"
14944         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14945                 error "create $DIR/$tdir/${tfile}bis failed"
14946
14947         # open the changelog device
14948         exec 3>/dev/changelog-$FSNAME-MDT0000
14949         stack_trap "exec 3>&-" EXIT
14950         exec 4</dev/changelog-$FSNAME-MDT0000
14951         stack_trap "exec 4<&-" EXIT
14952
14953         # umount the first lustre mount
14954         umount $MOUNT
14955         stack_trap "mount_client $MOUNT" EXIT
14956
14957         # read changelog
14958         cat <&4 >/dev/null || error "read changelog failed"
14959
14960         # clear changelog
14961         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14962         changelog_users $SINGLEMDS | grep -q $cl_user ||
14963                 error "User $cl_user not found in changelog_users"
14964
14965         printf 'clear:'$cl_user':0' >&3
14966 }
14967 run_test 160j "client can be umounted  while its chanangelog is being used"
14968
14969 test_160k() {
14970         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14971         remote_mds_nodsh && skip "remote MDS with nodsh"
14972
14973         mkdir -p $DIR/$tdir/1/1
14974
14975         changelog_register || error "changelog_register failed"
14976         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14977
14978         changelog_users $SINGLEMDS | grep -q $cl_user ||
14979                 error "User '$cl_user' not found in changelog_users"
14980 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
14981         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
14982         rmdir $DIR/$tdir/1/1 & sleep 1
14983         mkdir $DIR/$tdir/2
14984         touch $DIR/$tdir/2/2
14985         rm -rf $DIR/$tdir/2
14986
14987         wait
14988         sleep 4
14989
14990         changelog_dump | grep rmdir || error "rmdir not recorded"
14991
14992         rm -rf $DIR/$tdir
14993         changelog_deregister
14994 }
14995 run_test 160k "Verify that changelog records are not lost"
14996
14997 test_161a() {
14998         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14999
15000         test_mkdir -c1 $DIR/$tdir
15001         cp /etc/hosts $DIR/$tdir/$tfile
15002         test_mkdir -c1 $DIR/$tdir/foo1
15003         test_mkdir -c1 $DIR/$tdir/foo2
15004         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
15005         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
15006         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
15007         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
15008         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
15009         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15010                 $LFS fid2path $DIR $FID
15011                 error "bad link ea"
15012         fi
15013         # middle
15014         rm $DIR/$tdir/foo2/zachary
15015         # last
15016         rm $DIR/$tdir/foo2/thor
15017         # first
15018         rm $DIR/$tdir/$tfile
15019         # rename
15020         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
15021         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
15022                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
15023         rm $DIR/$tdir/foo2/maggie
15024
15025         # overflow the EA
15026         local longname=$tfile.avg_len_is_thirty_two_
15027         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
15028                 error_noexit 'failed to unlink many hardlinks'" EXIT
15029         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
15030                 error "failed to hardlink many files"
15031         links=$($LFS fid2path $DIR $FID | wc -l)
15032         echo -n "${links}/1000 links in link EA"
15033         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
15034 }
15035 run_test 161a "link ea sanity"
15036
15037 test_161b() {
15038         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15039         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
15040
15041         local MDTIDX=1
15042         local remote_dir=$DIR/$tdir/remote_dir
15043
15044         mkdir -p $DIR/$tdir
15045         $LFS mkdir -i $MDTIDX $remote_dir ||
15046                 error "create remote directory failed"
15047
15048         cp /etc/hosts $remote_dir/$tfile
15049         mkdir -p $remote_dir/foo1
15050         mkdir -p $remote_dir/foo2
15051         ln $remote_dir/$tfile $remote_dir/foo1/sofia
15052         ln $remote_dir/$tfile $remote_dir/foo2/zachary
15053         ln $remote_dir/$tfile $remote_dir/foo1/luna
15054         ln $remote_dir/$tfile $remote_dir/foo2/thor
15055
15056         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
15057                      tr -d ']')
15058         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15059                 $LFS fid2path $DIR $FID
15060                 error "bad link ea"
15061         fi
15062         # middle
15063         rm $remote_dir/foo2/zachary
15064         # last
15065         rm $remote_dir/foo2/thor
15066         # first
15067         rm $remote_dir/$tfile
15068         # rename
15069         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
15070         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
15071         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
15072                 $LFS fid2path $DIR $FID
15073                 error "bad link rename"
15074         fi
15075         rm $remote_dir/foo2/maggie
15076
15077         # overflow the EA
15078         local longname=filename_avg_len_is_thirty_two_
15079         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
15080                 error "failed to hardlink many files"
15081         links=$($LFS fid2path $DIR $FID | wc -l)
15082         echo -n "${links}/1000 links in link EA"
15083         [[ ${links} -gt 60 ]] ||
15084                 error "expected at least 60 links in link EA"
15085         unlinkmany $remote_dir/foo2/$longname 1000 ||
15086         error "failed to unlink many hardlinks"
15087 }
15088 run_test 161b "link ea sanity under remote directory"
15089
15090 test_161c() {
15091         remote_mds_nodsh && skip "remote MDS with nodsh"
15092         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15093         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
15094                 skip "Need MDS version at least 2.1.5"
15095
15096         # define CLF_RENAME_LAST 0x0001
15097         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
15098         changelog_register || error "changelog_register failed"
15099
15100         rm -rf $DIR/$tdir
15101         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
15102         touch $DIR/$tdir/foo_161c
15103         touch $DIR/$tdir/bar_161c
15104         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15105         changelog_dump | grep RENME | tail -n 5
15106         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15107         changelog_clear 0 || error "changelog_clear failed"
15108         if [ x$flags != "x0x1" ]; then
15109                 error "flag $flags is not 0x1"
15110         fi
15111
15112         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
15113         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
15114         touch $DIR/$tdir/foo_161c
15115         touch $DIR/$tdir/bar_161c
15116         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15117         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15118         changelog_dump | grep RENME | tail -n 5
15119         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15120         changelog_clear 0 || error "changelog_clear failed"
15121         if [ x$flags != "x0x0" ]; then
15122                 error "flag $flags is not 0x0"
15123         fi
15124         echo "rename overwrite a target having nlink > 1," \
15125                 "changelog record has flags of $flags"
15126
15127         # rename doesn't overwrite a target (changelog flag 0x0)
15128         touch $DIR/$tdir/foo_161c
15129         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
15130         changelog_dump | grep RENME | tail -n 5
15131         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
15132         changelog_clear 0 || error "changelog_clear failed"
15133         if [ x$flags != "x0x0" ]; then
15134                 error "flag $flags is not 0x0"
15135         fi
15136         echo "rename doesn't overwrite a target," \
15137                 "changelog record has flags of $flags"
15138
15139         # define CLF_UNLINK_LAST 0x0001
15140         # unlink a file having nlink = 1 (changelog flag 0x1)
15141         rm -f $DIR/$tdir/foo2_161c
15142         changelog_dump | grep UNLNK | tail -n 5
15143         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15144         changelog_clear 0 || error "changelog_clear failed"
15145         if [ x$flags != "x0x1" ]; then
15146                 error "flag $flags is not 0x1"
15147         fi
15148         echo "unlink a file having nlink = 1," \
15149                 "changelog record has flags of $flags"
15150
15151         # unlink a file having nlink > 1 (changelog flag 0x0)
15152         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15153         rm -f $DIR/$tdir/foobar_161c
15154         changelog_dump | grep UNLNK | tail -n 5
15155         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15156         changelog_clear 0 || error "changelog_clear failed"
15157         if [ x$flags != "x0x0" ]; then
15158                 error "flag $flags is not 0x0"
15159         fi
15160         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
15161 }
15162 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
15163
15164 test_161d() {
15165         remote_mds_nodsh && skip "remote MDS with nodsh"
15166         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
15167
15168         local pid
15169         local fid
15170
15171         changelog_register || error "changelog_register failed"
15172
15173         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
15174         # interfer with $MOUNT/.lustre/fid/ access
15175         mkdir $DIR/$tdir
15176         [[ $? -eq 0 ]] || error "mkdir failed"
15177
15178         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
15179         $LCTL set_param fail_loc=0x8000140c
15180         # 5s pause
15181         $LCTL set_param fail_val=5
15182
15183         # create file
15184         echo foofoo > $DIR/$tdir/$tfile &
15185         pid=$!
15186
15187         # wait for create to be delayed
15188         sleep 2
15189
15190         ps -p $pid
15191         [[ $? -eq 0 ]] || error "create should be blocked"
15192
15193         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
15194         stack_trap "rm -f $tempfile"
15195         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
15196         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
15197         # some delay may occur during ChangeLog publishing and file read just
15198         # above, that could allow file write to happen finally
15199         [[ -s $tempfile ]] && echo "file should be empty"
15200
15201         $LCTL set_param fail_loc=0
15202
15203         wait $pid
15204         [[ $? -eq 0 ]] || error "create failed"
15205 }
15206 run_test 161d "create with concurrent .lustre/fid access"
15207
15208 check_path() {
15209         local expected="$1"
15210         shift
15211         local fid="$2"
15212
15213         local path
15214         path=$($LFS fid2path "$@")
15215         local rc=$?
15216
15217         if [ $rc -ne 0 ]; then
15218                 error "path looked up of '$expected' failed: rc=$rc"
15219         elif [ "$path" != "$expected" ]; then
15220                 error "path looked up '$path' instead of '$expected'"
15221         else
15222                 echo "FID '$fid' resolves to path '$path' as expected"
15223         fi
15224 }
15225
15226 test_162a() { # was test_162
15227         test_mkdir -p -c1 $DIR/$tdir/d2
15228         touch $DIR/$tdir/d2/$tfile
15229         touch $DIR/$tdir/d2/x1
15230         touch $DIR/$tdir/d2/x2
15231         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
15232         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
15233         # regular file
15234         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
15235         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
15236
15237         # softlink
15238         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
15239         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
15240         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
15241
15242         # softlink to wrong file
15243         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
15244         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
15245         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
15246
15247         # hardlink
15248         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
15249         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
15250         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
15251         # fid2path dir/fsname should both work
15252         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
15253         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
15254
15255         # hardlink count: check that there are 2 links
15256         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
15257         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
15258
15259         # hardlink indexing: remove the first link
15260         rm $DIR/$tdir/d2/p/q/r/hlink
15261         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
15262 }
15263 run_test 162a "path lookup sanity"
15264
15265 test_162b() {
15266         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15267         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15268
15269         mkdir $DIR/$tdir
15270         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
15271                                 error "create striped dir failed"
15272
15273         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
15274                                         tail -n 1 | awk '{print $2}')
15275         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
15276
15277         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
15278         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
15279
15280         # regular file
15281         for ((i=0;i<5;i++)); do
15282                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
15283                         error "get fid for f$i failed"
15284                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
15285
15286                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
15287                         error "get fid for d$i failed"
15288                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
15289         done
15290
15291         return 0
15292 }
15293 run_test 162b "striped directory path lookup sanity"
15294
15295 # LU-4239: Verify fid2path works with paths 100 or more directories deep
15296 test_162c() {
15297         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
15298                 skip "Need MDS version at least 2.7.51"
15299
15300         local lpath=$tdir.local
15301         local rpath=$tdir.remote
15302
15303         test_mkdir $DIR/$lpath
15304         test_mkdir $DIR/$rpath
15305
15306         for ((i = 0; i <= 101; i++)); do
15307                 lpath="$lpath/$i"
15308                 mkdir $DIR/$lpath
15309                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
15310                         error "get fid for local directory $DIR/$lpath failed"
15311                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
15312
15313                 rpath="$rpath/$i"
15314                 test_mkdir $DIR/$rpath
15315                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
15316                         error "get fid for remote directory $DIR/$rpath failed"
15317                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
15318         done
15319
15320         return 0
15321 }
15322 run_test 162c "fid2path works with paths 100 or more directories deep"
15323
15324 oalr_event_count() {
15325         local event="${1}"
15326         local trace="${2}"
15327
15328         awk -v name="${FSNAME}-OST0000" \
15329             -v event="${event}" \
15330             '$1 == "TRACE" && $2 == event && $3 == name' \
15331             "${trace}" |
15332         wc -l
15333 }
15334
15335 oalr_expect_event_count() {
15336         local event="${1}"
15337         local trace="${2}"
15338         local expect="${3}"
15339         local count
15340
15341         count=$(oalr_event_count "${event}" "${trace}")
15342         if ((count == expect)); then
15343                 return 0
15344         fi
15345
15346         error_noexit "${event} event count was '${count}', expected ${expect}"
15347         cat "${trace}" >&2
15348         exit 1
15349 }
15350
15351 cleanup_165() {
15352         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
15353         stop ost1
15354         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
15355 }
15356
15357 setup_165() {
15358         sync # Flush previous IOs so we can count log entries.
15359         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
15360         stack_trap cleanup_165 EXIT
15361 }
15362
15363 test_165a() {
15364         local trace="/tmp/${tfile}.trace"
15365         local rc
15366         local count
15367
15368         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15369         setup_165
15370         sleep 5
15371
15372         do_facet ost1 ofd_access_log_reader --list
15373         stop ost1
15374
15375         do_facet ost1 killall -TERM ofd_access_log_reader
15376         wait
15377         rc=$?
15378
15379         if ((rc != 0)); then
15380                 error "ofd_access_log_reader exited with rc = '${rc}'"
15381         fi
15382
15383         # Parse trace file for discovery events:
15384         oalr_expect_event_count alr_log_add "${trace}" 1
15385         oalr_expect_event_count alr_log_eof "${trace}" 1
15386         oalr_expect_event_count alr_log_free "${trace}" 1
15387 }
15388 run_test 165a "ofd access log discovery"
15389
15390 test_165b() {
15391         local trace="/tmp/${tfile}.trace"
15392         local file="${DIR}/${tfile}"
15393         local pfid1
15394         local pfid2
15395         local -a entry
15396         local rc
15397         local count
15398         local size
15399         local flags
15400
15401         setup_165
15402
15403         lfs setstripe -c 1 -i 0 "${file}"
15404         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15405         do_facet ost1 ofd_access_log_reader --list
15406
15407         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15408         sleep 5
15409         do_facet ost1 killall -TERM ofd_access_log_reader
15410         wait
15411         rc=$?
15412
15413         if ((rc != 0)); then
15414                 error "ofd_access_log_reader exited with rc = '${rc}'"
15415         fi
15416
15417         oalr_expect_event_count alr_log_entry "${trace}" 1
15418
15419         pfid1=$($LFS path2fid "${file}")
15420
15421         # 1     2             3   4    5     6   7    8    9     10
15422         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
15423         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
15424
15425         echo "entry = '${entry[*]}'" >&2
15426
15427         pfid2=${entry[4]}
15428         if [[ "${pfid1}" != "${pfid2}" ]]; then
15429                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
15430         fi
15431
15432         size=${entry[8]}
15433         if ((size != 1048576)); then
15434                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
15435         fi
15436
15437         flags=${entry[10]}
15438         if [[ "${flags}" != "w" ]]; then
15439                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
15440         fi
15441
15442         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15443         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c || error "cannot read '${file}'"
15444         sleep 5
15445         do_facet ost1 killall -TERM ofd_access_log_reader
15446         wait
15447         rc=$?
15448
15449         if ((rc != 0)); then
15450                 error "ofd_access_log_reader exited with rc = '${rc}'"
15451         fi
15452
15453         oalr_expect_event_count alr_log_entry "${trace}" 1
15454
15455         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
15456         echo "entry = '${entry[*]}'" >&2
15457
15458         pfid2=${entry[4]}
15459         if [[ "${pfid1}" != "${pfid2}" ]]; then
15460                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
15461         fi
15462
15463         size=${entry[8]}
15464         if ((size != 524288)); then
15465                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
15466         fi
15467
15468         flags=${entry[10]}
15469         if [[ "${flags}" != "r" ]]; then
15470                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
15471         fi
15472 }
15473 run_test 165b "ofd access log entries are produced and consumed"
15474
15475 test_165c() {
15476         local file="${DIR}/${tdir}/${tfile}"
15477         test_mkdir "${DIR}/${tdir}"
15478
15479         setup_165
15480
15481         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
15482
15483         # 4096 / 64 = 64. Create twice as many entries.
15484         for ((i = 0; i < 128; i++)); do
15485                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c || error "cannot create file"
15486         done
15487
15488         sync
15489         do_facet ost1 ofd_access_log_reader --list
15490         unlinkmany  "${file}-%d" 128
15491 }
15492 run_test 165c "full ofd access logs do not block IOs"
15493
15494 oal_peek_entry_count() {
15495         do_facet ost1 ofd_access_log_reader --list | awk '$1 == "_entry_count:" { print $2; }'
15496 }
15497
15498 oal_expect_entry_count() {
15499         local entry_count=$(oal_peek_entry_count)
15500         local expect="$1"
15501
15502         if ((entry_count == expect)); then
15503                 return 0
15504         fi
15505
15506         error_noexit "bad entry count, got ${entry_count}, expected ${expect}"
15507         do_facet ost1 ofd_access_log_reader --list >&2
15508         exit 1
15509 }
15510
15511 test_165d() {
15512         local trace="/tmp/${tfile}.trace"
15513         local file="${DIR}/${tdir}/${tfile}"
15514         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
15515         local entry_count
15516         test_mkdir "${DIR}/${tdir}"
15517
15518         setup_165
15519         lfs setstripe -c 1 -i 0 "${file}"
15520
15521         do_facet ost1 lctl set_param "${param}=rw"
15522         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15523         oal_expect_entry_count 1
15524
15525         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15526         oal_expect_entry_count 2
15527
15528         do_facet ost1 lctl set_param "${param}=r"
15529         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15530         oal_expect_entry_count 2
15531
15532         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15533         oal_expect_entry_count 3
15534
15535         do_facet ost1 lctl set_param "${param}=w"
15536         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15537         oal_expect_entry_count 4
15538
15539         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15540         oal_expect_entry_count 4
15541
15542         do_facet ost1 lctl set_param "${param}=0"
15543         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15544         oal_expect_entry_count 4
15545
15546         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15547         oal_expect_entry_count 4
15548 }
15549 run_test 165d "ofd_access_log mask works"
15550
15551 test_169() {
15552         # do directio so as not to populate the page cache
15553         log "creating a 10 Mb file"
15554         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
15555         log "starting reads"
15556         dd if=$DIR/$tfile of=/dev/null bs=4096 &
15557         log "truncating the file"
15558         $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
15559         log "killing dd"
15560         kill %+ || true # reads might have finished
15561         echo "wait until dd is finished"
15562         wait
15563         log "removing the temporary file"
15564         rm -rf $DIR/$tfile || error "tmp file removal failed"
15565 }
15566 run_test 169 "parallel read and truncate should not deadlock"
15567
15568 test_170() {
15569         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15570
15571         $LCTL clear     # bug 18514
15572         $LCTL debug_daemon start $TMP/${tfile}_log_good
15573         touch $DIR/$tfile
15574         $LCTL debug_daemon stop
15575         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
15576                 error "sed failed to read log_good"
15577
15578         $LCTL debug_daemon start $TMP/${tfile}_log_good
15579         rm -rf $DIR/$tfile
15580         $LCTL debug_daemon stop
15581
15582         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
15583                error "lctl df log_bad failed"
15584
15585         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
15586         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
15587
15588         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
15589         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
15590
15591         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
15592                 error "bad_line good_line1 good_line2 are empty"
15593
15594         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
15595         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
15596         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
15597
15598         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
15599         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
15600         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
15601
15602         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
15603                 error "bad_line_new good_line_new are empty"
15604
15605         local expected_good=$((good_line1 + good_line2*2))
15606
15607         rm -f $TMP/${tfile}*
15608         # LU-231, short malformed line may not be counted into bad lines
15609         if [ $bad_line -ne $bad_line_new ] &&
15610                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
15611                 error "expected $bad_line bad lines, but got $bad_line_new"
15612                 return 1
15613         fi
15614
15615         if [ $expected_good -ne $good_line_new ]; then
15616                 error "expected $expected_good good lines, but got $good_line_new"
15617                 return 2
15618         fi
15619         true
15620 }
15621 run_test 170 "test lctl df to handle corrupted log ====================="
15622
15623 test_171() { # bug20592
15624         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15625
15626         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
15627         $LCTL set_param fail_loc=0x50e
15628         $LCTL set_param fail_val=3000
15629         multiop_bg_pause $DIR/$tfile O_s || true
15630         local MULTIPID=$!
15631         kill -USR1 $MULTIPID
15632         # cause log dump
15633         sleep 3
15634         wait $MULTIPID
15635         if dmesg | grep "recursive fault"; then
15636                 error "caught a recursive fault"
15637         fi
15638         $LCTL set_param fail_loc=0
15639         true
15640 }
15641 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
15642
15643 # it would be good to share it with obdfilter-survey/iokit-libecho code
15644 setup_obdecho_osc () {
15645         local rc=0
15646         local ost_nid=$1
15647         local obdfilter_name=$2
15648         echo "Creating new osc for $obdfilter_name on $ost_nid"
15649         # make sure we can find loopback nid
15650         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
15651
15652         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
15653                            ${obdfilter_name}_osc_UUID || rc=2; }
15654         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
15655                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
15656         return $rc
15657 }
15658
15659 cleanup_obdecho_osc () {
15660         local obdfilter_name=$1
15661         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
15662         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
15663         return 0
15664 }
15665
15666 obdecho_test() {
15667         local OBD=$1
15668         local node=$2
15669         local pages=${3:-64}
15670         local rc=0
15671         local id
15672
15673         local count=10
15674         local obd_size=$(get_obd_size $node $OBD)
15675         local page_size=$(get_page_size $node)
15676         if [[ -n "$obd_size" ]]; then
15677                 local new_count=$((obd_size / (pages * page_size / 1024)))
15678                 [[ $new_count -ge $count ]] || count=$new_count
15679         fi
15680
15681         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
15682         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
15683                            rc=2; }
15684         if [ $rc -eq 0 ]; then
15685             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
15686             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
15687         fi
15688         echo "New object id is $id"
15689         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
15690                            rc=4; }
15691         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
15692                            "test_brw $count w v $pages $id" || rc=4; }
15693         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
15694                            rc=4; }
15695         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
15696                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
15697         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
15698                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
15699         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
15700         return $rc
15701 }
15702
15703 test_180a() {
15704         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15705
15706         if ! module_loaded obdecho; then
15707                 load_module obdecho/obdecho &&
15708                         stack_trap "rmmod obdecho" EXIT ||
15709                         error "unable to load obdecho on client"
15710         fi
15711
15712         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
15713         local host=$($LCTL get_param -n osc.$osc.import |
15714                      awk '/current_connection:/ { print $2 }' )
15715         local target=$($LCTL get_param -n osc.$osc.import |
15716                        awk '/target:/ { print $2 }' )
15717         target=${target%_UUID}
15718
15719         if [ -n "$target" ]; then
15720                 setup_obdecho_osc $host $target &&
15721                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
15722                         { error "obdecho setup failed with $?"; return; }
15723
15724                 obdecho_test ${target}_osc client ||
15725                         error "obdecho_test failed on ${target}_osc"
15726         else
15727                 $LCTL get_param osc.$osc.import
15728                 error "there is no osc.$osc.import target"
15729         fi
15730 }
15731 run_test 180a "test obdecho on osc"
15732
15733 test_180b() {
15734         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15735         remote_ost_nodsh && skip "remote OST with nodsh"
15736
15737         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
15738                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
15739                 error "failed to load module obdecho"
15740
15741         local target=$(do_facet ost1 $LCTL dl |
15742                        awk '/obdfilter/ { print $4; exit; }')
15743
15744         if [ -n "$target" ]; then
15745                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
15746         else
15747                 do_facet ost1 $LCTL dl
15748                 error "there is no obdfilter target on ost1"
15749         fi
15750 }
15751 run_test 180b "test obdecho directly on obdfilter"
15752
15753 test_180c() { # LU-2598
15754         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15755         remote_ost_nodsh && skip "remote OST with nodsh"
15756         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
15757                 skip "Need MDS version at least 2.4.0"
15758
15759         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
15760                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
15761                 error "failed to load module obdecho"
15762
15763         local target=$(do_facet ost1 $LCTL dl |
15764                        awk '/obdfilter/ { print $4; exit; }')
15765
15766         if [ -n "$target" ]; then
15767                 local pages=16384 # 64MB bulk I/O RPC size
15768
15769                 obdecho_test "$target" ost1 "$pages" ||
15770                         error "obdecho_test with pages=$pages failed with $?"
15771         else
15772                 do_facet ost1 $LCTL dl
15773                 error "there is no obdfilter target on ost1"
15774         fi
15775 }
15776 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
15777
15778 test_181() { # bug 22177
15779         test_mkdir $DIR/$tdir
15780         # create enough files to index the directory
15781         createmany -o $DIR/$tdir/foobar 4000
15782         # print attributes for debug purpose
15783         lsattr -d .
15784         # open dir
15785         multiop_bg_pause $DIR/$tdir D_Sc || return 1
15786         MULTIPID=$!
15787         # remove the files & current working dir
15788         unlinkmany $DIR/$tdir/foobar 4000
15789         rmdir $DIR/$tdir
15790         kill -USR1 $MULTIPID
15791         wait $MULTIPID
15792         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
15793         return 0
15794 }
15795 run_test 181 "Test open-unlinked dir ========================"
15796
15797 test_182() {
15798         local fcount=1000
15799         local tcount=10
15800
15801         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
15802
15803         $LCTL set_param mdc.*.rpc_stats=clear
15804
15805         for (( i = 0; i < $tcount; i++ )) ; do
15806                 mkdir $DIR/$tdir/$i
15807         done
15808
15809         for (( i = 0; i < $tcount; i++ )) ; do
15810                 createmany -o $DIR/$tdir/$i/f- $fcount &
15811         done
15812         wait
15813
15814         for (( i = 0; i < $tcount; i++ )) ; do
15815                 unlinkmany $DIR/$tdir/$i/f- $fcount &
15816         done
15817         wait
15818
15819         $LCTL get_param mdc.*.rpc_stats
15820
15821         rm -rf $DIR/$tdir
15822 }
15823 run_test 182 "Test parallel modify metadata operations ================"
15824
15825 test_183() { # LU-2275
15826         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15827         remote_mds_nodsh && skip "remote MDS with nodsh"
15828         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
15829                 skip "Need MDS version at least 2.3.56"
15830
15831         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
15832         echo aaa > $DIR/$tdir/$tfile
15833
15834 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
15835         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
15836
15837         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
15838         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
15839
15840         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
15841
15842         # Flush negative dentry cache
15843         touch $DIR/$tdir/$tfile
15844
15845         # We are not checking for any leaked references here, they'll
15846         # become evident next time we do cleanup with module unload.
15847         rm -rf $DIR/$tdir
15848 }
15849 run_test 183 "No crash or request leak in case of strange dispositions ========"
15850
15851 # test suite 184 is for LU-2016, LU-2017
15852 test_184a() {
15853         check_swap_layouts_support
15854
15855         dir0=$DIR/$tdir/$testnum
15856         test_mkdir -p -c1 $dir0
15857         ref1=/etc/passwd
15858         ref2=/etc/group
15859         file1=$dir0/f1
15860         file2=$dir0/f2
15861         $LFS setstripe -c1 $file1
15862         cp $ref1 $file1
15863         $LFS setstripe -c2 $file2
15864         cp $ref2 $file2
15865         gen1=$($LFS getstripe -g $file1)
15866         gen2=$($LFS getstripe -g $file2)
15867
15868         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
15869         gen=$($LFS getstripe -g $file1)
15870         [[ $gen1 != $gen ]] ||
15871                 "Layout generation on $file1 does not change"
15872         gen=$($LFS getstripe -g $file2)
15873         [[ $gen2 != $gen ]] ||
15874                 "Layout generation on $file2 does not change"
15875
15876         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
15877         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
15878
15879         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
15880 }
15881 run_test 184a "Basic layout swap"
15882
15883 test_184b() {
15884         check_swap_layouts_support
15885
15886         dir0=$DIR/$tdir/$testnum
15887         mkdir -p $dir0 || error "creating dir $dir0"
15888         file1=$dir0/f1
15889         file2=$dir0/f2
15890         file3=$dir0/f3
15891         dir1=$dir0/d1
15892         dir2=$dir0/d2
15893         mkdir $dir1 $dir2
15894         $LFS setstripe -c1 $file1
15895         $LFS setstripe -c2 $file2
15896         $LFS setstripe -c1 $file3
15897         chown $RUNAS_ID $file3
15898         gen1=$($LFS getstripe -g $file1)
15899         gen2=$($LFS getstripe -g $file2)
15900
15901         $LFS swap_layouts $dir1 $dir2 &&
15902                 error "swap of directories layouts should fail"
15903         $LFS swap_layouts $dir1 $file1 &&
15904                 error "swap of directory and file layouts should fail"
15905         $RUNAS $LFS swap_layouts $file1 $file2 &&
15906                 error "swap of file we cannot write should fail"
15907         $LFS swap_layouts $file1 $file3 &&
15908                 error "swap of file with different owner should fail"
15909         /bin/true # to clear error code
15910 }
15911 run_test 184b "Forbidden layout swap (will generate errors)"
15912
15913 test_184c() {
15914         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
15915         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
15916         check_swap_layouts_support
15917
15918         local dir0=$DIR/$tdir/$testnum
15919         mkdir -p $dir0 || error "creating dir $dir0"
15920
15921         local ref1=$dir0/ref1
15922         local ref2=$dir0/ref2
15923         local file1=$dir0/file1
15924         local file2=$dir0/file2
15925         # create a file large enough for the concurrent test
15926         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
15927         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
15928         echo "ref file size: ref1($(stat -c %s $ref1))," \
15929              "ref2($(stat -c %s $ref2))"
15930
15931         cp $ref2 $file2
15932         dd if=$ref1 of=$file1 bs=16k &
15933         local DD_PID=$!
15934
15935         # Make sure dd starts to copy file
15936         while [ ! -f $file1 ]; do sleep 0.1; done
15937
15938         $LFS swap_layouts $file1 $file2
15939         local rc=$?
15940         wait $DD_PID
15941         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
15942         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
15943
15944         # how many bytes copied before swapping layout
15945         local copied=$(stat -c %s $file2)
15946         local remaining=$(stat -c %s $ref1)
15947         remaining=$((remaining - copied))
15948         echo "Copied $copied bytes before swapping layout..."
15949
15950         cmp -n $copied $file1 $ref2 | grep differ &&
15951                 error "Content mismatch [0, $copied) of ref2 and file1"
15952         cmp -n $copied $file2 $ref1 ||
15953                 error "Content mismatch [0, $copied) of ref1 and file2"
15954         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
15955                 error "Content mismatch [$copied, EOF) of ref1 and file1"
15956
15957         # clean up
15958         rm -f $ref1 $ref2 $file1 $file2
15959 }
15960 run_test 184c "Concurrent write and layout swap"
15961
15962 test_184d() {
15963         check_swap_layouts_support
15964         [ -z "$(which getfattr 2>/dev/null)" ] &&
15965                 skip_env "no getfattr command"
15966
15967         local file1=$DIR/$tdir/$tfile-1
15968         local file2=$DIR/$tdir/$tfile-2
15969         local file3=$DIR/$tdir/$tfile-3
15970         local lovea1
15971         local lovea2
15972
15973         mkdir -p $DIR/$tdir
15974         touch $file1 || error "create $file1 failed"
15975         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
15976                 error "create $file2 failed"
15977         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
15978                 error "create $file3 failed"
15979         lovea1=$(get_layout_param $file1)
15980
15981         $LFS swap_layouts $file2 $file3 ||
15982                 error "swap $file2 $file3 layouts failed"
15983         $LFS swap_layouts $file1 $file2 ||
15984                 error "swap $file1 $file2 layouts failed"
15985
15986         lovea2=$(get_layout_param $file2)
15987         echo "$lovea1"
15988         echo "$lovea2"
15989         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
15990
15991         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
15992         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
15993 }
15994 run_test 184d "allow stripeless layouts swap"
15995
15996 test_184e() {
15997         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
15998                 skip "Need MDS version at least 2.6.94"
15999         check_swap_layouts_support
16000         [ -z "$(which getfattr 2>/dev/null)" ] &&
16001                 skip_env "no getfattr command"
16002
16003         local file1=$DIR/$tdir/$tfile-1
16004         local file2=$DIR/$tdir/$tfile-2
16005         local file3=$DIR/$tdir/$tfile-3
16006         local lovea
16007
16008         mkdir -p $DIR/$tdir
16009         touch $file1 || error "create $file1 failed"
16010         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
16011                 error "create $file2 failed"
16012         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
16013                 error "create $file3 failed"
16014
16015         $LFS swap_layouts $file1 $file2 ||
16016                 error "swap $file1 $file2 layouts failed"
16017
16018         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
16019         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
16020
16021         echo 123 > $file1 || error "Should be able to write into $file1"
16022
16023         $LFS swap_layouts $file1 $file3 ||
16024                 error "swap $file1 $file3 layouts failed"
16025
16026         echo 123 > $file1 || error "Should be able to write into $file1"
16027
16028         rm -rf $file1 $file2 $file3
16029 }
16030 run_test 184e "Recreate layout after stripeless layout swaps"
16031
16032 test_184f() {
16033         # Create a file with name longer than sizeof(struct stat) ==
16034         # 144 to see if we can get chars from the file name to appear
16035         # in the returned striping. Note that 'f' == 0x66.
16036         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
16037
16038         mkdir -p $DIR/$tdir
16039         mcreate $DIR/$tdir/$file
16040         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
16041                 error "IOC_MDC_GETFILEINFO returned garbage striping"
16042         fi
16043 }
16044 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
16045
16046 test_185() { # LU-2441
16047         # LU-3553 - no volatile file support in old servers
16048         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
16049                 skip "Need MDS version at least 2.3.60"
16050
16051         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16052         touch $DIR/$tdir/spoo
16053         local mtime1=$(stat -c "%Y" $DIR/$tdir)
16054         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
16055                 error "cannot create/write a volatile file"
16056         [ "$FILESET" == "" ] &&
16057         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
16058                 error "FID is still valid after close"
16059
16060         multiop_bg_pause $DIR/$tdir vVw4096_c
16061         local multi_pid=$!
16062
16063         local OLD_IFS=$IFS
16064         IFS=":"
16065         local fidv=($fid)
16066         IFS=$OLD_IFS
16067         # assume that the next FID for this client is sequential, since stdout
16068         # is unfortunately eaten by multiop_bg_pause
16069         local n=$((${fidv[1]} + 1))
16070         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
16071         if [ "$FILESET" == "" ]; then
16072                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
16073                         error "FID is missing before close"
16074         fi
16075         kill -USR1 $multi_pid
16076         # 1 second delay, so if mtime change we will see it
16077         sleep 1
16078         local mtime2=$(stat -c "%Y" $DIR/$tdir)
16079         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
16080 }
16081 run_test 185 "Volatile file support"
16082
16083 function create_check_volatile() {
16084         local idx=$1
16085         local tgt
16086
16087         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
16088         local PID=$!
16089         sleep 1
16090         local FID=$(cat /tmp/${tfile}.fid)
16091         [ "$FID" == "" ] && error "can't get FID for volatile"
16092         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
16093         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
16094         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
16095         kill -USR1 $PID
16096         wait
16097         sleep 1
16098         cancel_lru_locks mdc # flush opencache
16099         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
16100         return 0
16101 }
16102
16103 test_185a(){
16104         # LU-12516 - volatile creation via .lustre
16105         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
16106                 skip "Need MDS version at least 2.3.55"
16107
16108         create_check_volatile 0
16109         [ $MDSCOUNT -lt 2 ] && return 0
16110
16111         # DNE case
16112         create_check_volatile 1
16113
16114         return 0
16115 }
16116 run_test 185a "Volatile file creation in .lustre/fid/"
16117
16118 test_187a() {
16119         remote_mds_nodsh && skip "remote MDS with nodsh"
16120         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
16121                 skip "Need MDS version at least 2.3.0"
16122
16123         local dir0=$DIR/$tdir/$testnum
16124         mkdir -p $dir0 || error "creating dir $dir0"
16125
16126         local file=$dir0/file1
16127         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
16128         local dv1=$($LFS data_version $file)
16129         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
16130         local dv2=$($LFS data_version $file)
16131         [[ $dv1 != $dv2 ]] ||
16132                 error "data version did not change on write $dv1 == $dv2"
16133
16134         # clean up
16135         rm -f $file1
16136 }
16137 run_test 187a "Test data version change"
16138
16139 test_187b() {
16140         remote_mds_nodsh && skip "remote MDS with nodsh"
16141         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
16142                 skip "Need MDS version at least 2.3.0"
16143
16144         local dir0=$DIR/$tdir/$testnum
16145         mkdir -p $dir0 || error "creating dir $dir0"
16146
16147         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
16148         [[ ${DV[0]} != ${DV[1]} ]] ||
16149                 error "data version did not change on write"\
16150                       " ${DV[0]} == ${DV[1]}"
16151
16152         # clean up
16153         rm -f $file1
16154 }
16155 run_test 187b "Test data version change on volatile file"
16156
16157 test_200() {
16158         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16159         remote_mgs_nodsh && skip "remote MGS with nodsh"
16160         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16161
16162         local POOL=${POOL:-cea1}
16163         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
16164         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
16165         # Pool OST targets
16166         local first_ost=0
16167         local last_ost=$(($OSTCOUNT - 1))
16168         local ost_step=2
16169         local ost_list=$(seq $first_ost $ost_step $last_ost)
16170         local ost_range="$first_ost $last_ost $ost_step"
16171         local test_path=$POOL_ROOT/$POOL_DIR_NAME
16172         local file_dir=$POOL_ROOT/file_tst
16173         local subdir=$test_path/subdir
16174         local rc=0
16175
16176         while : ; do
16177                 # former test_200a test_200b
16178                 pool_add $POOL                          || { rc=$? ; break; }
16179                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
16180                 # former test_200c test_200d
16181                 mkdir -p $test_path
16182                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
16183                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
16184                 mkdir -p $subdir
16185                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
16186                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
16187                                                         || { rc=$? ; break; }
16188                 # former test_200e test_200f
16189                 local files=$((OSTCOUNT*3))
16190                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
16191                                                         || { rc=$? ; break; }
16192                 pool_create_files $POOL $file_dir $files "$ost_list" \
16193                                                         || { rc=$? ; break; }
16194                 # former test_200g test_200h
16195                 pool_lfs_df $POOL                       || { rc=$? ; break; }
16196                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
16197
16198                 # former test_201a test_201b test_201c
16199                 pool_remove_first_target $POOL          || { rc=$? ; break; }
16200
16201                 local f=$test_path/$tfile
16202                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
16203                 pool_remove $POOL $f                    || { rc=$? ; break; }
16204                 break
16205         done
16206
16207         destroy_test_pools
16208
16209         return $rc
16210 }
16211 run_test 200 "OST pools"
16212
16213 # usage: default_attr <count | size | offset>
16214 default_attr() {
16215         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
16216 }
16217
16218 # usage: check_default_stripe_attr
16219 check_default_stripe_attr() {
16220         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
16221         case $1 in
16222         --stripe-count|-c)
16223                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
16224         --stripe-size|-S)
16225                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
16226         --stripe-index|-i)
16227                 EXPECTED=-1;;
16228         *)
16229                 error "unknown getstripe attr '$1'"
16230         esac
16231
16232         [ $ACTUAL == $EXPECTED ] ||
16233                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
16234 }
16235
16236 test_204a() {
16237         test_mkdir $DIR/$tdir
16238         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
16239
16240         check_default_stripe_attr --stripe-count
16241         check_default_stripe_attr --stripe-size
16242         check_default_stripe_attr --stripe-index
16243 }
16244 run_test 204a "Print default stripe attributes"
16245
16246 test_204b() {
16247         test_mkdir $DIR/$tdir
16248         $LFS setstripe --stripe-count 1 $DIR/$tdir
16249
16250         check_default_stripe_attr --stripe-size
16251         check_default_stripe_attr --stripe-index
16252 }
16253 run_test 204b "Print default stripe size and offset"
16254
16255 test_204c() {
16256         test_mkdir $DIR/$tdir
16257         $LFS setstripe --stripe-size 65536 $DIR/$tdir
16258
16259         check_default_stripe_attr --stripe-count
16260         check_default_stripe_attr --stripe-index
16261 }
16262 run_test 204c "Print default stripe count and offset"
16263
16264 test_204d() {
16265         test_mkdir $DIR/$tdir
16266         $LFS setstripe --stripe-index 0 $DIR/$tdir
16267
16268         check_default_stripe_attr --stripe-count
16269         check_default_stripe_attr --stripe-size
16270 }
16271 run_test 204d "Print default stripe count and size"
16272
16273 test_204e() {
16274         test_mkdir $DIR/$tdir
16275         $LFS setstripe -d $DIR/$tdir
16276
16277         check_default_stripe_attr --stripe-count --raw
16278         check_default_stripe_attr --stripe-size --raw
16279         check_default_stripe_attr --stripe-index --raw
16280 }
16281 run_test 204e "Print raw stripe attributes"
16282
16283 test_204f() {
16284         test_mkdir $DIR/$tdir
16285         $LFS setstripe --stripe-count 1 $DIR/$tdir
16286
16287         check_default_stripe_attr --stripe-size --raw
16288         check_default_stripe_attr --stripe-index --raw
16289 }
16290 run_test 204f "Print raw stripe size and offset"
16291
16292 test_204g() {
16293         test_mkdir $DIR/$tdir
16294         $LFS setstripe --stripe-size 65536 $DIR/$tdir
16295
16296         check_default_stripe_attr --stripe-count --raw
16297         check_default_stripe_attr --stripe-index --raw
16298 }
16299 run_test 204g "Print raw stripe count and offset"
16300
16301 test_204h() {
16302         test_mkdir $DIR/$tdir
16303         $LFS setstripe --stripe-index 0 $DIR/$tdir
16304
16305         check_default_stripe_attr --stripe-count --raw
16306         check_default_stripe_attr --stripe-size --raw
16307 }
16308 run_test 204h "Print raw stripe count and size"
16309
16310 # Figure out which job scheduler is being used, if any,
16311 # or use a fake one
16312 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
16313         JOBENV=SLURM_JOB_ID
16314 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
16315         JOBENV=LSB_JOBID
16316 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
16317         JOBENV=PBS_JOBID
16318 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
16319         JOBENV=LOADL_STEP_ID
16320 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
16321         JOBENV=JOB_ID
16322 else
16323         $LCTL list_param jobid_name > /dev/null 2>&1
16324         if [ $? -eq 0 ]; then
16325                 JOBENV=nodelocal
16326         else
16327                 JOBENV=FAKE_JOBID
16328         fi
16329 fi
16330 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
16331
16332 verify_jobstats() {
16333         local cmd=($1)
16334         shift
16335         local facets="$@"
16336
16337 # we don't really need to clear the stats for this test to work, since each
16338 # command has a unique jobid, but it makes debugging easier if needed.
16339 #       for facet in $facets; do
16340 #               local dev=$(convert_facet2label $facet)
16341 #               # clear old jobstats
16342 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
16343 #       done
16344
16345         # use a new JobID for each test, or we might see an old one
16346         [ "$JOBENV" = "FAKE_JOBID" ] &&
16347                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
16348
16349         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
16350
16351         [ "$JOBENV" = "nodelocal" ] && {
16352                 FAKE_JOBID=id.$testnum.%e.$RANDOM
16353                 $LCTL set_param jobid_name=$FAKE_JOBID
16354                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
16355         }
16356
16357         log "Test: ${cmd[*]}"
16358         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
16359
16360         if [ $JOBENV = "FAKE_JOBID" ]; then
16361                 FAKE_JOBID=$JOBVAL ${cmd[*]}
16362         else
16363                 ${cmd[*]}
16364         fi
16365
16366         # all files are created on OST0000
16367         for facet in $facets; do
16368                 local stats="*.$(convert_facet2label $facet).job_stats"
16369
16370                 # strip out libtool wrappers for in-tree executables
16371                 if [ $(do_facet $facet lctl get_param $stats |
16372                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
16373                         do_facet $facet lctl get_param $stats
16374                         error "No jobstats for $JOBVAL found on $facet::$stats"
16375                 fi
16376         done
16377 }
16378
16379 jobstats_set() {
16380         local new_jobenv=$1
16381
16382         set_persistent_param_and_check client "jobid_var" \
16383                 "$FSNAME.sys.jobid_var" $new_jobenv
16384 }
16385
16386 test_205a() { # Job stats
16387         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16388         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
16389                 skip "Need MDS version with at least 2.7.1"
16390         remote_mgs_nodsh && skip "remote MGS with nodsh"
16391         remote_mds_nodsh && skip "remote MDS with nodsh"
16392         remote_ost_nodsh && skip "remote OST with nodsh"
16393         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
16394                 skip "Server doesn't support jobstats"
16395         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
16396
16397         local old_jobenv=$($LCTL get_param -n jobid_var)
16398         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
16399
16400         if [[ $PERM_CMD == *"set_param -P"* ]]; then
16401                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
16402         else
16403                 stack_trap "do_facet mgs $PERM_CMD \
16404                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
16405         fi
16406         changelog_register
16407
16408         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
16409                                 mdt.*.job_cleanup_interval | head -n 1)
16410         local new_interval=5
16411         do_facet $SINGLEMDS \
16412                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
16413         stack_trap "do_facet $SINGLEMDS \
16414                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
16415         local start=$SECONDS
16416
16417         local cmd
16418         # mkdir
16419         cmd="mkdir $DIR/$tdir"
16420         verify_jobstats "$cmd" "$SINGLEMDS"
16421         # rmdir
16422         cmd="rmdir $DIR/$tdir"
16423         verify_jobstats "$cmd" "$SINGLEMDS"
16424         # mkdir on secondary MDT
16425         if [ $MDSCOUNT -gt 1 ]; then
16426                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
16427                 verify_jobstats "$cmd" "mds2"
16428         fi
16429         # mknod
16430         cmd="mknod $DIR/$tfile c 1 3"
16431         verify_jobstats "$cmd" "$SINGLEMDS"
16432         # unlink
16433         cmd="rm -f $DIR/$tfile"
16434         verify_jobstats "$cmd" "$SINGLEMDS"
16435         # create all files on OST0000 so verify_jobstats can find OST stats
16436         # open & close
16437         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
16438         verify_jobstats "$cmd" "$SINGLEMDS"
16439         # setattr
16440         cmd="touch $DIR/$tfile"
16441         verify_jobstats "$cmd" "$SINGLEMDS ost1"
16442         # write
16443         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
16444         verify_jobstats "$cmd" "ost1"
16445         # read
16446         cancel_lru_locks osc
16447         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
16448         verify_jobstats "$cmd" "ost1"
16449         # truncate
16450         cmd="$TRUNCATE $DIR/$tfile 0"
16451         verify_jobstats "$cmd" "$SINGLEMDS ost1"
16452         # rename
16453         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
16454         verify_jobstats "$cmd" "$SINGLEMDS"
16455         # jobstats expiry - sleep until old stats should be expired
16456         local left=$((new_interval + 5 - (SECONDS - start)))
16457         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
16458                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
16459                         "0" $left
16460         cmd="mkdir $DIR/$tdir.expire"
16461         verify_jobstats "$cmd" "$SINGLEMDS"
16462         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
16463             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
16464
16465         # Ensure that jobid are present in changelog (if supported by MDS)
16466         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
16467                 changelog_dump | tail -10
16468                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
16469                 [ $jobids -eq 9 ] ||
16470                         error "Wrong changelog jobid count $jobids != 9"
16471
16472                 # LU-5862
16473                 JOBENV="disable"
16474                 jobstats_set $JOBENV
16475                 touch $DIR/$tfile
16476                 changelog_dump | grep $tfile
16477                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
16478                 [ $jobids -eq 0 ] ||
16479                         error "Unexpected jobids when jobid_var=$JOBENV"
16480         fi
16481
16482         lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"
16483         JOBENV="JOBCOMPLEX"
16484         JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
16485
16486         verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
16487 }
16488 run_test 205a "Verify job stats"
16489
16490 # LU-13117, LU-13597
16491 test_205b() {
16492         job_stats="mdt.*.job_stats"
16493         $LCTL set_param $job_stats=clear
16494         $LCTL set_param jobid_var=USER jobid_name="%e.%u"
16495         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
16496         do_facet $SINGLEMDS $LCTL get_param $job_stats |
16497                 grep "job_id:.*foolish" &&
16498                         error "Unexpected jobid found"
16499         do_facet $SINGLEMDS $LCTL get_param $job_stats |
16500                 grep "open:.*min.*max.*sum" ||
16501                         error "wrong job_stats format found"
16502 }
16503 run_test 205b "Verify job stats jobid and output format"
16504
16505 # LU-1480, LU-1773 and LU-1657
16506 test_206() {
16507         mkdir -p $DIR/$tdir
16508         $LFS setstripe -c -1 $DIR/$tdir
16509 #define OBD_FAIL_LOV_INIT 0x1403
16510         $LCTL set_param fail_loc=0xa0001403
16511         $LCTL set_param fail_val=1
16512         touch $DIR/$tdir/$tfile || true
16513 }
16514 run_test 206 "fail lov_init_raid0() doesn't lbug"
16515
16516 test_207a() {
16517         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
16518         local fsz=`stat -c %s $DIR/$tfile`
16519         cancel_lru_locks mdc
16520
16521         # do not return layout in getattr intent
16522 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
16523         $LCTL set_param fail_loc=0x170
16524         local sz=`stat -c %s $DIR/$tfile`
16525
16526         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
16527
16528         rm -rf $DIR/$tfile
16529 }
16530 run_test 207a "can refresh layout at glimpse"
16531
16532 test_207b() {
16533         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
16534         local cksum=`md5sum $DIR/$tfile`
16535         local fsz=`stat -c %s $DIR/$tfile`
16536         cancel_lru_locks mdc
16537         cancel_lru_locks osc
16538
16539         # do not return layout in getattr intent
16540 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
16541         $LCTL set_param fail_loc=0x171
16542
16543         # it will refresh layout after the file is opened but before read issues
16544         echo checksum is "$cksum"
16545         echo "$cksum" |md5sum -c --quiet || error "file differs"
16546
16547         rm -rf $DIR/$tfile
16548 }
16549 run_test 207b "can refresh layout at open"
16550
16551 test_208() {
16552         # FIXME: in this test suite, only RD lease is used. This is okay
16553         # for now as only exclusive open is supported. After generic lease
16554         # is done, this test suite should be revised. - Jinshan
16555
16556         remote_mds_nodsh && skip "remote MDS with nodsh"
16557         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
16558                 skip "Need MDS version at least 2.4.52"
16559
16560         echo "==== test 1: verify get lease work"
16561         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
16562
16563         echo "==== test 2: verify lease can be broken by upcoming open"
16564         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
16565         local PID=$!
16566         sleep 1
16567
16568         $MULTIOP $DIR/$tfile oO_RDONLY:c
16569         kill -USR1 $PID && wait $PID || error "break lease error"
16570
16571         echo "==== test 3: verify lease can't be granted if an open already exists"
16572         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
16573         local PID=$!
16574         sleep 1
16575
16576         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
16577         kill -USR1 $PID && wait $PID || error "open file error"
16578
16579         echo "==== test 4: lease can sustain over recovery"
16580         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
16581         PID=$!
16582         sleep 1
16583
16584         fail mds1
16585
16586         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
16587
16588         echo "==== test 5: lease broken can't be regained by replay"
16589         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
16590         PID=$!
16591         sleep 1
16592
16593         # open file to break lease and then recovery
16594         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
16595         fail mds1
16596
16597         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
16598
16599         rm -f $DIR/$tfile
16600 }
16601 run_test 208 "Exclusive open"
16602
16603 test_209() {
16604         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
16605                 skip_env "must have disp_stripe"
16606
16607         touch $DIR/$tfile
16608         sync; sleep 5; sync;
16609
16610         echo 3 > /proc/sys/vm/drop_caches
16611         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
16612
16613         # open/close 500 times
16614         for i in $(seq 500); do
16615                 cat $DIR/$tfile
16616         done
16617
16618         echo 3 > /proc/sys/vm/drop_caches
16619         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
16620
16621         echo "before: $req_before, after: $req_after"
16622         [ $((req_after - req_before)) -ge 300 ] &&
16623                 error "open/close requests are not freed"
16624         return 0
16625 }
16626 run_test 209 "read-only open/close requests should be freed promptly"
16627
16628 test_210() {
16629         local pid
16630
16631         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
16632         pid=$!
16633         sleep 1
16634
16635         $LFS getstripe $DIR/$tfile
16636         kill -USR1 $pid
16637         wait $pid || error "multiop failed"
16638
16639         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
16640         pid=$!
16641         sleep 1
16642
16643         $LFS getstripe $DIR/$tfile
16644         kill -USR1 $pid
16645         wait $pid || error "multiop failed"
16646 }
16647 run_test 210 "lfs getstripe does not break leases"
16648
16649 test_212() {
16650         size=`date +%s`
16651         size=$((size % 8192 + 1))
16652         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
16653         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
16654         rm -f $DIR/f212 $DIR/f212.xyz
16655 }
16656 run_test 212 "Sendfile test ============================================"
16657
16658 test_213() {
16659         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
16660         cancel_lru_locks osc
16661         lctl set_param fail_loc=0x8000040f
16662         # generate a read lock
16663         cat $DIR/$tfile > /dev/null
16664         # write to the file, it will try to cancel the above read lock.
16665         cat /etc/hosts >> $DIR/$tfile
16666 }
16667 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
16668
16669 test_214() { # for bug 20133
16670         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
16671         for (( i=0; i < 340; i++ )) ; do
16672                 touch $DIR/$tdir/d214c/a$i
16673         done
16674
16675         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
16676         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
16677         ls $DIR/d214c || error "ls $DIR/d214c failed"
16678         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
16679         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
16680 }
16681 run_test 214 "hash-indexed directory test - bug 20133"
16682
16683 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
16684 create_lnet_proc_files() {
16685         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
16686 }
16687
16688 # counterpart of create_lnet_proc_files
16689 remove_lnet_proc_files() {
16690         rm -f $TMP/lnet_$1.sys
16691 }
16692
16693 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
16694 # 3rd arg as regexp for body
16695 check_lnet_proc_stats() {
16696         local l=$(cat "$TMP/lnet_$1" |wc -l)
16697         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
16698
16699         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
16700 }
16701
16702 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
16703 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
16704 # optional and can be regexp for 2nd line (lnet.routes case)
16705 check_lnet_proc_entry() {
16706         local blp=2          # blp stands for 'position of 1st line of body'
16707         [ -z "$5" ] || blp=3 # lnet.routes case
16708
16709         local l=$(cat "$TMP/lnet_$1" |wc -l)
16710         # subtracting one from $blp because the body can be empty
16711         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
16712
16713         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
16714                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
16715
16716         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
16717                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
16718
16719         # bail out if any unexpected line happened
16720         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
16721         [ "$?" != 0 ] || error "$2 misformatted"
16722 }
16723
16724 test_215() { # for bugs 18102, 21079, 21517
16725         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16726
16727         local N='(0|[1-9][0-9]*)'       # non-negative numeric
16728         local P='[1-9][0-9]*'           # positive numeric
16729         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
16730         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
16731         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
16732         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
16733
16734         local L1 # regexp for 1st line
16735         local L2 # regexp for 2nd line (optional)
16736         local BR # regexp for the rest (body)
16737
16738         # lnet.stats should look as 11 space-separated non-negative numerics
16739         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
16740         create_lnet_proc_files "stats"
16741         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
16742         remove_lnet_proc_files "stats"
16743
16744         # lnet.routes should look like this:
16745         # Routing disabled/enabled
16746         # net hops priority state router
16747         # where net is a string like tcp0, hops > 0, priority >= 0,
16748         # state is up/down,
16749         # router is a string like 192.168.1.1@tcp2
16750         L1="^Routing (disabled|enabled)$"
16751         L2="^net +hops +priority +state +router$"
16752         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
16753         create_lnet_proc_files "routes"
16754         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
16755         remove_lnet_proc_files "routes"
16756
16757         # lnet.routers should look like this:
16758         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
16759         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
16760         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
16761         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
16762         L1="^ref +rtr_ref +alive +router$"
16763         BR="^$P +$P +(up|down) +$NID$"
16764         create_lnet_proc_files "routers"
16765         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
16766         remove_lnet_proc_files "routers"
16767
16768         # lnet.peers should look like this:
16769         # nid refs state last max rtr min tx min queue
16770         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
16771         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
16772         # numeric (0 or >0 or <0), queue >= 0.
16773         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
16774         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
16775         create_lnet_proc_files "peers"
16776         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
16777         remove_lnet_proc_files "peers"
16778
16779         # lnet.buffers  should look like this:
16780         # pages count credits min
16781         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
16782         L1="^pages +count +credits +min$"
16783         BR="^ +$N +$N +$I +$I$"
16784         create_lnet_proc_files "buffers"
16785         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
16786         remove_lnet_proc_files "buffers"
16787
16788         # lnet.nis should look like this:
16789         # nid status alive refs peer rtr max tx min
16790         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
16791         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
16792         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
16793         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
16794         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
16795         create_lnet_proc_files "nis"
16796         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
16797         remove_lnet_proc_files "nis"
16798
16799         # can we successfully write to lnet.stats?
16800         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
16801 }
16802 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
16803
16804 test_216() { # bug 20317
16805         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16806         remote_ost_nodsh && skip "remote OST with nodsh"
16807
16808         local node
16809         local facets=$(get_facets OST)
16810         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16811
16812         save_lustre_params client "osc.*.contention_seconds" > $p
16813         save_lustre_params $facets \
16814                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
16815         save_lustre_params $facets \
16816                 "ldlm.namespaces.filter-*.contended_locks" >> $p
16817         save_lustre_params $facets \
16818                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
16819         clear_stats osc.*.osc_stats
16820
16821         # agressive lockless i/o settings
16822         do_nodes $(comma_list $(osts_nodes)) \
16823                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
16824                         ldlm.namespaces.filter-*.contended_locks=0 \
16825                         ldlm.namespaces.filter-*.contention_seconds=60"
16826         lctl set_param -n osc.*.contention_seconds=60
16827
16828         $DIRECTIO write $DIR/$tfile 0 10 4096
16829         $CHECKSTAT -s 40960 $DIR/$tfile
16830
16831         # disable lockless i/o
16832         do_nodes $(comma_list $(osts_nodes)) \
16833                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
16834                         ldlm.namespaces.filter-*.contended_locks=32 \
16835                         ldlm.namespaces.filter-*.contention_seconds=0"
16836         lctl set_param -n osc.*.contention_seconds=0
16837         clear_stats osc.*.osc_stats
16838
16839         dd if=/dev/zero of=$DIR/$tfile count=0
16840         $CHECKSTAT -s 0 $DIR/$tfile
16841
16842         restore_lustre_params <$p
16843         rm -f $p
16844         rm $DIR/$tfile
16845 }
16846 run_test 216 "check lockless direct write updates file size and kms correctly"
16847
16848 test_217() { # bug 22430
16849         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16850
16851         local node
16852         local nid
16853
16854         for node in $(nodes_list); do
16855                 nid=$(host_nids_address $node $NETTYPE)
16856                 if [[ $nid = *-* ]] ; then
16857                         echo "lctl ping $(h2nettype $nid)"
16858                         lctl ping $(h2nettype $nid)
16859                 else
16860                         echo "skipping $node (no hyphen detected)"
16861                 fi
16862         done
16863 }
16864 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
16865
16866 test_218() {
16867        # do directio so as not to populate the page cache
16868        log "creating a 10 Mb file"
16869        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
16870        log "starting reads"
16871        dd if=$DIR/$tfile of=/dev/null bs=4096 &
16872        log "truncating the file"
16873        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
16874        log "killing dd"
16875        kill %+ || true # reads might have finished
16876        echo "wait until dd is finished"
16877        wait
16878        log "removing the temporary file"
16879        rm -rf $DIR/$tfile || error "tmp file removal failed"
16880 }
16881 run_test 218 "parallel read and truncate should not deadlock"
16882
16883 test_219() {
16884         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16885
16886         # write one partial page
16887         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
16888         # set no grant so vvp_io_commit_write will do sync write
16889         $LCTL set_param fail_loc=0x411
16890         # write a full page at the end of file
16891         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
16892
16893         $LCTL set_param fail_loc=0
16894         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
16895         $LCTL set_param fail_loc=0x411
16896         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
16897
16898         # LU-4201
16899         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
16900         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
16901 }
16902 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
16903
16904 test_220() { #LU-325
16905         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16906         remote_ost_nodsh && skip "remote OST with nodsh"
16907         remote_mds_nodsh && skip "remote MDS with nodsh"
16908         remote_mgs_nodsh && skip "remote MGS with nodsh"
16909
16910         local OSTIDX=0
16911
16912         # create on MDT0000 so the last_id and next_id are correct
16913         mkdir $DIR/$tdir
16914         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
16915         OST=${OST%_UUID}
16916
16917         # on the mdt's osc
16918         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
16919         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
16920                         osp.$mdtosc_proc1.prealloc_last_id)
16921         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
16922                         osp.$mdtosc_proc1.prealloc_next_id)
16923
16924         $LFS df -i
16925
16926         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
16927         #define OBD_FAIL_OST_ENOINO              0x229
16928         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
16929         create_pool $FSNAME.$TESTNAME || return 1
16930         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
16931
16932         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
16933
16934         MDSOBJS=$((last_id - next_id))
16935         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
16936
16937         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
16938         echo "OST still has $count kbytes free"
16939
16940         echo "create $MDSOBJS files @next_id..."
16941         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
16942
16943         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
16944                         osp.$mdtosc_proc1.prealloc_last_id)
16945         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
16946                         osp.$mdtosc_proc1.prealloc_next_id)
16947
16948         echo "after creation, last_id=$last_id2, next_id=$next_id2"
16949         $LFS df -i
16950
16951         echo "cleanup..."
16952
16953         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
16954         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
16955
16956         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
16957                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
16958         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
16959                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
16960         echo "unlink $MDSOBJS files @$next_id..."
16961         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
16962 }
16963 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
16964
16965 test_221() {
16966         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16967
16968         dd if=`which date` of=$MOUNT/date oflag=sync
16969         chmod +x $MOUNT/date
16970
16971         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
16972         $LCTL set_param fail_loc=0x80001401
16973
16974         $MOUNT/date > /dev/null
16975         rm -f $MOUNT/date
16976 }
16977 run_test 221 "make sure fault and truncate race to not cause OOM"
16978
16979 test_222a () {
16980         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16981
16982         rm -rf $DIR/$tdir
16983         test_mkdir $DIR/$tdir
16984         $LFS setstripe -c 1 -i 0 $DIR/$tdir
16985         createmany -o $DIR/$tdir/$tfile 10
16986         cancel_lru_locks mdc
16987         cancel_lru_locks osc
16988         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
16989         $LCTL set_param fail_loc=0x31a
16990         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
16991         $LCTL set_param fail_loc=0
16992         rm -r $DIR/$tdir
16993 }
16994 run_test 222a "AGL for ls should not trigger CLIO lock failure"
16995
16996 test_222b () {
16997         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16998
16999         rm -rf $DIR/$tdir
17000         test_mkdir $DIR/$tdir
17001         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17002         createmany -o $DIR/$tdir/$tfile 10
17003         cancel_lru_locks mdc
17004         cancel_lru_locks osc
17005         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
17006         $LCTL set_param fail_loc=0x31a
17007         rm -r $DIR/$tdir || error "AGL for rmdir failed"
17008         $LCTL set_param fail_loc=0
17009 }
17010 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
17011
17012 test_223 () {
17013         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17014
17015         rm -rf $DIR/$tdir
17016         test_mkdir $DIR/$tdir
17017         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17018         createmany -o $DIR/$tdir/$tfile 10
17019         cancel_lru_locks mdc
17020         cancel_lru_locks osc
17021         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
17022         $LCTL set_param fail_loc=0x31b
17023         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
17024         $LCTL set_param fail_loc=0
17025         rm -r $DIR/$tdir
17026 }
17027 run_test 223 "osc reenqueue if without AGL lock granted ======================="
17028
17029 test_224a() { # LU-1039, MRP-303
17030         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17031
17032         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
17033         $LCTL set_param fail_loc=0x508
17034         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
17035         $LCTL set_param fail_loc=0
17036         df $DIR
17037 }
17038 run_test 224a "Don't panic on bulk IO failure"
17039
17040 test_224b() { # LU-1039, MRP-303
17041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17042
17043         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
17044         cancel_lru_locks osc
17045         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
17046         $LCTL set_param fail_loc=0x515
17047         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
17048         $LCTL set_param fail_loc=0
17049         df $DIR
17050 }
17051 run_test 224b "Don't panic on bulk IO failure"
17052
17053 test_224c() { # LU-6441
17054         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17055         remote_mds_nodsh && skip "remote MDS with nodsh"
17056
17057         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17058         save_writethrough $p
17059         set_cache writethrough on
17060
17061         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
17062         local at_max=$($LCTL get_param -n at_max)
17063         local timeout=$($LCTL get_param -n timeout)
17064         local test_at="at_max"
17065         local param_at="$FSNAME.sys.at_max"
17066         local test_timeout="timeout"
17067         local param_timeout="$FSNAME.sys.timeout"
17068
17069         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
17070
17071         set_persistent_param_and_check client "$test_at" "$param_at" 0
17072         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
17073
17074         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
17075         do_facet ost1 "$LCTL set_param fail_loc=0x520"
17076         $LFS setstripe -c 1 -i 0 $DIR/$tfile
17077         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
17078         sync
17079         do_facet ost1 "$LCTL set_param fail_loc=0"
17080
17081         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
17082         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
17083                 $timeout
17084
17085         $LCTL set_param -n $pages_per_rpc
17086         restore_lustre_params < $p
17087         rm -f $p
17088 }
17089 run_test 224c "Don't hang if one of md lost during large bulk RPC"
17090
17091 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
17092 test_225a () {
17093         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17094         if [ -z ${MDSSURVEY} ]; then
17095                 skip_env "mds-survey not found"
17096         fi
17097         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
17098                 skip "Need MDS version at least 2.2.51"
17099
17100         local mds=$(facet_host $SINGLEMDS)
17101         local target=$(do_nodes $mds 'lctl dl' |
17102                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17103
17104         local cmd1="file_count=1000 thrhi=4"
17105         local cmd2="dir_count=2 layer=mdd stripe_count=0"
17106         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17107         local cmd="$cmd1 $cmd2 $cmd3"
17108
17109         rm -f ${TMP}/mds_survey*
17110         echo + $cmd
17111         eval $cmd || error "mds-survey with zero-stripe failed"
17112         cat ${TMP}/mds_survey*
17113         rm -f ${TMP}/mds_survey*
17114 }
17115 run_test 225a "Metadata survey sanity with zero-stripe"
17116
17117 test_225b () {
17118         if [ -z ${MDSSURVEY} ]; then
17119                 skip_env "mds-survey not found"
17120         fi
17121         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
17122                 skip "Need MDS version at least 2.2.51"
17123         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17124         remote_mds_nodsh && skip "remote MDS with nodsh"
17125         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
17126                 skip_env "Need to mount OST to test"
17127         fi
17128
17129         local mds=$(facet_host $SINGLEMDS)
17130         local target=$(do_nodes $mds 'lctl dl' |
17131                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17132
17133         local cmd1="file_count=1000 thrhi=4"
17134         local cmd2="dir_count=2 layer=mdd stripe_count=1"
17135         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17136         local cmd="$cmd1 $cmd2 $cmd3"
17137
17138         rm -f ${TMP}/mds_survey*
17139         echo + $cmd
17140         eval $cmd || error "mds-survey with stripe_count failed"
17141         cat ${TMP}/mds_survey*
17142         rm -f ${TMP}/mds_survey*
17143 }
17144 run_test 225b "Metadata survey sanity with stripe_count = 1"
17145
17146 mcreate_path2fid () {
17147         local mode=$1
17148         local major=$2
17149         local minor=$3
17150         local name=$4
17151         local desc=$5
17152         local path=$DIR/$tdir/$name
17153         local fid
17154         local rc
17155         local fid_path
17156
17157         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
17158                 error "cannot create $desc"
17159
17160         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
17161         rc=$?
17162         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
17163
17164         fid_path=$($LFS fid2path $MOUNT $fid)
17165         rc=$?
17166         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
17167
17168         [ "$path" == "$fid_path" ] ||
17169                 error "fid2path returned $fid_path, expected $path"
17170
17171         echo "pass with $path and $fid"
17172 }
17173
17174 test_226a () {
17175         rm -rf $DIR/$tdir
17176         mkdir -p $DIR/$tdir
17177
17178         mcreate_path2fid 0010666 0 0 fifo "FIFO"
17179         mcreate_path2fid 0020666 1 3 null "character special file (null)"
17180         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
17181         mcreate_path2fid 0040666 0 0 dir "directory"
17182         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
17183         mcreate_path2fid 0100666 0 0 file "regular file"
17184         mcreate_path2fid 0120666 0 0 link "symbolic link"
17185         mcreate_path2fid 0140666 0 0 sock "socket"
17186 }
17187 run_test 226a "call path2fid and fid2path on files of all type"
17188
17189 test_226b () {
17190         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17191
17192         local MDTIDX=1
17193
17194         rm -rf $DIR/$tdir
17195         mkdir -p $DIR/$tdir
17196         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
17197                 error "create remote directory failed"
17198         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
17199         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
17200                                 "character special file (null)"
17201         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
17202                                 "character special file (no device)"
17203         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
17204         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
17205                                 "block special file (loop)"
17206         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
17207         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
17208         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
17209 }
17210 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
17211
17212 # LU-1299 Executing or running ldd on a truncated executable does not
17213 # cause an out-of-memory condition.
17214 test_227() {
17215         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17216         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
17217
17218         dd if=$(which date) of=$MOUNT/date bs=1k count=1
17219         chmod +x $MOUNT/date
17220
17221         $MOUNT/date > /dev/null
17222         ldd $MOUNT/date > /dev/null
17223         rm -f $MOUNT/date
17224 }
17225 run_test 227 "running truncated executable does not cause OOM"
17226
17227 # LU-1512 try to reuse idle OI blocks
17228 test_228a() {
17229         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17230         remote_mds_nodsh && skip "remote MDS with nodsh"
17231         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17232
17233         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17234         local myDIR=$DIR/$tdir
17235
17236         mkdir -p $myDIR
17237         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17238         $LCTL set_param fail_loc=0x80001002
17239         createmany -o $myDIR/t- 10000
17240         $LCTL set_param fail_loc=0
17241         # The guard is current the largest FID holder
17242         touch $myDIR/guard
17243         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17244                     tr -d '[')
17245         local IDX=$(($SEQ % 64))
17246
17247         do_facet $SINGLEMDS sync
17248         # Make sure journal flushed.
17249         sleep 6
17250         local blk1=$(do_facet $SINGLEMDS \
17251                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17252                      grep Blockcount | awk '{print $4}')
17253
17254         # Remove old files, some OI blocks will become idle.
17255         unlinkmany $myDIR/t- 10000
17256         # Create new files, idle OI blocks should be reused.
17257         createmany -o $myDIR/t- 2000
17258         do_facet $SINGLEMDS sync
17259         # Make sure journal flushed.
17260         sleep 6
17261         local blk2=$(do_facet $SINGLEMDS \
17262                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17263                      grep Blockcount | awk '{print $4}')
17264
17265         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17266 }
17267 run_test 228a "try to reuse idle OI blocks"
17268
17269 test_228b() {
17270         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17271         remote_mds_nodsh && skip "remote MDS with nodsh"
17272         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17273
17274         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17275         local myDIR=$DIR/$tdir
17276
17277         mkdir -p $myDIR
17278         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17279         $LCTL set_param fail_loc=0x80001002
17280         createmany -o $myDIR/t- 10000
17281         $LCTL set_param fail_loc=0
17282         # The guard is current the largest FID holder
17283         touch $myDIR/guard
17284         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17285                     tr -d '[')
17286         local IDX=$(($SEQ % 64))
17287
17288         do_facet $SINGLEMDS sync
17289         # Make sure journal flushed.
17290         sleep 6
17291         local blk1=$(do_facet $SINGLEMDS \
17292                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17293                      grep Blockcount | awk '{print $4}')
17294
17295         # Remove old files, some OI blocks will become idle.
17296         unlinkmany $myDIR/t- 10000
17297
17298         # stop the MDT
17299         stop $SINGLEMDS || error "Fail to stop MDT."
17300         # remount the MDT
17301         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
17302
17303         df $MOUNT || error "Fail to df."
17304         # Create new files, idle OI blocks should be reused.
17305         createmany -o $myDIR/t- 2000
17306         do_facet $SINGLEMDS sync
17307         # Make sure journal flushed.
17308         sleep 6
17309         local blk2=$(do_facet $SINGLEMDS \
17310                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17311                      grep Blockcount | awk '{print $4}')
17312
17313         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17314 }
17315 run_test 228b "idle OI blocks can be reused after MDT restart"
17316
17317 #LU-1881
17318 test_228c() {
17319         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17320         remote_mds_nodsh && skip "remote MDS with nodsh"
17321         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17322
17323         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17324         local myDIR=$DIR/$tdir
17325
17326         mkdir -p $myDIR
17327         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17328         $LCTL set_param fail_loc=0x80001002
17329         # 20000 files can guarantee there are index nodes in the OI file
17330         createmany -o $myDIR/t- 20000
17331         $LCTL set_param fail_loc=0
17332         # The guard is current the largest FID holder
17333         touch $myDIR/guard
17334         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17335                     tr -d '[')
17336         local IDX=$(($SEQ % 64))
17337
17338         do_facet $SINGLEMDS sync
17339         # Make sure journal flushed.
17340         sleep 6
17341         local blk1=$(do_facet $SINGLEMDS \
17342                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17343                      grep Blockcount | awk '{print $4}')
17344
17345         # Remove old files, some OI blocks will become idle.
17346         unlinkmany $myDIR/t- 20000
17347         rm -f $myDIR/guard
17348         # The OI file should become empty now
17349
17350         # Create new files, idle OI blocks should be reused.
17351         createmany -o $myDIR/t- 2000
17352         do_facet $SINGLEMDS sync
17353         # Make sure journal flushed.
17354         sleep 6
17355         local blk2=$(do_facet $SINGLEMDS \
17356                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17357                      grep Blockcount | awk '{print $4}')
17358
17359         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17360 }
17361 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
17362
17363 test_229() { # LU-2482, LU-3448
17364         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17365         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
17366         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
17367                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
17368
17369         rm -f $DIR/$tfile
17370
17371         # Create a file with a released layout and stripe count 2.
17372         $MULTIOP $DIR/$tfile H2c ||
17373                 error "failed to create file with released layout"
17374
17375         $LFS getstripe -v $DIR/$tfile
17376
17377         local pattern=$($LFS getstripe -L $DIR/$tfile)
17378         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
17379
17380         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
17381                 error "getstripe"
17382         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
17383         stat $DIR/$tfile || error "failed to stat released file"
17384
17385         chown $RUNAS_ID $DIR/$tfile ||
17386                 error "chown $RUNAS_ID $DIR/$tfile failed"
17387
17388         chgrp $RUNAS_ID $DIR/$tfile ||
17389                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
17390
17391         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
17392         rm $DIR/$tfile || error "failed to remove released file"
17393 }
17394 run_test 229 "getstripe/stat/rm/attr changes work on released files"
17395
17396 test_230a() {
17397         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17398         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17399         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17400                 skip "Need MDS version at least 2.11.52"
17401
17402         local MDTIDX=1
17403
17404         test_mkdir $DIR/$tdir
17405         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
17406         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
17407         [ $mdt_idx -ne 0 ] &&
17408                 error "create local directory on wrong MDT $mdt_idx"
17409
17410         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
17411                         error "create remote directory failed"
17412         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
17413         [ $mdt_idx -ne $MDTIDX ] &&
17414                 error "create remote directory on wrong MDT $mdt_idx"
17415
17416         createmany -o $DIR/$tdir/test_230/t- 10 ||
17417                 error "create files on remote directory failed"
17418         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
17419         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
17420         rm -r $DIR/$tdir || error "unlink remote directory failed"
17421 }
17422 run_test 230a "Create remote directory and files under the remote directory"
17423
17424 test_230b() {
17425         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17426         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17427         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17428                 skip "Need MDS version at least 2.11.52"
17429
17430         local MDTIDX=1
17431         local mdt_index
17432         local i
17433         local file
17434         local pid
17435         local stripe_count
17436         local migrate_dir=$DIR/$tdir/migrate_dir
17437         local other_dir=$DIR/$tdir/other_dir
17438
17439         test_mkdir $DIR/$tdir
17440         test_mkdir -i0 -c1 $migrate_dir
17441         test_mkdir -i0 -c1 $other_dir
17442         for ((i=0; i<10; i++)); do
17443                 mkdir -p $migrate_dir/dir_${i}
17444                 createmany -o $migrate_dir/dir_${i}/f 10 ||
17445                         error "create files under remote dir failed $i"
17446         done
17447
17448         cp /etc/passwd $migrate_dir/$tfile
17449         cp /etc/passwd $other_dir/$tfile
17450         chattr +SAD $migrate_dir
17451         chattr +SAD $migrate_dir/$tfile
17452
17453         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17454         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17455         local old_dir_mode=$(stat -c%f $migrate_dir)
17456         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
17457
17458         mkdir -p $migrate_dir/dir_default_stripe2
17459         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
17460         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
17461
17462         mkdir -p $other_dir
17463         ln $migrate_dir/$tfile $other_dir/luna
17464         ln $migrate_dir/$tfile $migrate_dir/sofia
17465         ln $other_dir/$tfile $migrate_dir/david
17466         ln -s $migrate_dir/$tfile $other_dir/zachary
17467         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
17468         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
17469
17470         local len
17471         local lnktgt
17472
17473         # inline symlink
17474         for len in 58 59 60; do
17475                 lnktgt=$(str_repeat 'l' $len)
17476                 touch $migrate_dir/$lnktgt
17477                 ln -s $lnktgt $migrate_dir/${len}char_ln
17478         done
17479
17480         # PATH_MAX
17481         for len in 4094 4095; do
17482                 lnktgt=$(str_repeat 'l' $len)
17483                 ln -s $lnktgt $migrate_dir/${len}char_ln
17484         done
17485
17486         # NAME_MAX
17487         for len in 254 255; do
17488                 touch $migrate_dir/$(str_repeat 'l' $len)
17489         done
17490
17491         $LFS migrate -m $MDTIDX $migrate_dir ||
17492                 error "fails on migrating remote dir to MDT1"
17493
17494         echo "migratate to MDT1, then checking.."
17495         for ((i = 0; i < 10; i++)); do
17496                 for file in $(find $migrate_dir/dir_${i}); do
17497                         mdt_index=$($LFS getstripe -m $file)
17498                         # broken symlink getstripe will fail
17499                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
17500                                 error "$file is not on MDT${MDTIDX}"
17501                 done
17502         done
17503
17504         # the multiple link file should still in MDT0
17505         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
17506         [ $mdt_index == 0 ] ||
17507                 error "$file is not on MDT${MDTIDX}"
17508
17509         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17510         [ "$old_dir_flag" = "$new_dir_flag" ] ||
17511                 error " expect $old_dir_flag get $new_dir_flag"
17512
17513         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17514         [ "$old_file_flag" = "$new_file_flag" ] ||
17515                 error " expect $old_file_flag get $new_file_flag"
17516
17517         local new_dir_mode=$(stat -c%f $migrate_dir)
17518         [ "$old_dir_mode" = "$new_dir_mode" ] ||
17519                 error "expect mode $old_dir_mode get $new_dir_mode"
17520
17521         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
17522         [ "$old_file_mode" = "$new_file_mode" ] ||
17523                 error "expect mode $old_file_mode get $new_file_mode"
17524
17525         diff /etc/passwd $migrate_dir/$tfile ||
17526                 error "$tfile different after migration"
17527
17528         diff /etc/passwd $other_dir/luna ||
17529                 error "luna different after migration"
17530
17531         diff /etc/passwd $migrate_dir/sofia ||
17532                 error "sofia different after migration"
17533
17534         diff /etc/passwd $migrate_dir/david ||
17535                 error "david different after migration"
17536
17537         diff /etc/passwd $other_dir/zachary ||
17538                 error "zachary different after migration"
17539
17540         diff /etc/passwd $migrate_dir/${tfile}_ln ||
17541                 error "${tfile}_ln different after migration"
17542
17543         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
17544                 error "${tfile}_ln_other different after migration"
17545
17546         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
17547         [ $stripe_count = 2 ] ||
17548                 error "dir strpe_count $d != 2 after migration."
17549
17550         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
17551         [ $stripe_count = 2 ] ||
17552                 error "file strpe_count $d != 2 after migration."
17553
17554         #migrate back to MDT0
17555         MDTIDX=0
17556
17557         $LFS migrate -m $MDTIDX $migrate_dir ||
17558                 error "fails on migrating remote dir to MDT0"
17559
17560         echo "migrate back to MDT0, checking.."
17561         for file in $(find $migrate_dir); do
17562                 mdt_index=$($LFS getstripe -m $file)
17563                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
17564                         error "$file is not on MDT${MDTIDX}"
17565         done
17566
17567         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17568         [ "$old_dir_flag" = "$new_dir_flag" ] ||
17569                 error " expect $old_dir_flag get $new_dir_flag"
17570
17571         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17572         [ "$old_file_flag" = "$new_file_flag" ] ||
17573                 error " expect $old_file_flag get $new_file_flag"
17574
17575         local new_dir_mode=$(stat -c%f $migrate_dir)
17576         [ "$old_dir_mode" = "$new_dir_mode" ] ||
17577                 error "expect mode $old_dir_mode get $new_dir_mode"
17578
17579         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
17580         [ "$old_file_mode" = "$new_file_mode" ] ||
17581                 error "expect mode $old_file_mode get $new_file_mode"
17582
17583         diff /etc/passwd ${migrate_dir}/$tfile ||
17584                 error "$tfile different after migration"
17585
17586         diff /etc/passwd ${other_dir}/luna ||
17587                 error "luna different after migration"
17588
17589         diff /etc/passwd ${migrate_dir}/sofia ||
17590                 error "sofia different after migration"
17591
17592         diff /etc/passwd ${other_dir}/zachary ||
17593                 error "zachary different after migration"
17594
17595         diff /etc/passwd $migrate_dir/${tfile}_ln ||
17596                 error "${tfile}_ln different after migration"
17597
17598         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
17599                 error "${tfile}_ln_other different after migration"
17600
17601         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
17602         [ $stripe_count = 2 ] ||
17603                 error "dir strpe_count $d != 2 after migration."
17604
17605         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
17606         [ $stripe_count = 2 ] ||
17607                 error "file strpe_count $d != 2 after migration."
17608
17609         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17610 }
17611 run_test 230b "migrate directory"
17612
17613 test_230c() {
17614         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17615         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17616         remote_mds_nodsh && skip "remote MDS with nodsh"
17617         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17618                 skip "Need MDS version at least 2.11.52"
17619
17620         local MDTIDX=1
17621         local total=3
17622         local mdt_index
17623         local file
17624         local migrate_dir=$DIR/$tdir/migrate_dir
17625
17626         #If migrating directory fails in the middle, all entries of
17627         #the directory is still accessiable.
17628         test_mkdir $DIR/$tdir
17629         test_mkdir -i0 -c1 $migrate_dir
17630         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
17631         stat $migrate_dir
17632         createmany -o $migrate_dir/f $total ||
17633                 error "create files under ${migrate_dir} failed"
17634
17635         # fail after migrating top dir, and this will fail only once, so the
17636         # first sub file migration will fail (currently f3), others succeed.
17637         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
17638         do_facet mds1 lctl set_param fail_loc=0x1801
17639         local t=$(ls $migrate_dir | wc -l)
17640         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
17641                 error "migrate should fail"
17642         local u=$(ls $migrate_dir | wc -l)
17643         [ "$u" == "$t" ] || error "$u != $t during migration"
17644
17645         # add new dir/file should succeed
17646         mkdir $migrate_dir/dir ||
17647                 error "mkdir failed under migrating directory"
17648         touch $migrate_dir/file ||
17649                 error "create file failed under migrating directory"
17650
17651         # add file with existing name should fail
17652         for file in $migrate_dir/f*; do
17653                 stat $file > /dev/null || error "stat $file failed"
17654                 $OPENFILE -f O_CREAT:O_EXCL $file &&
17655                         error "open(O_CREAT|O_EXCL) $file should fail"
17656                 $MULTIOP $file m && error "create $file should fail"
17657                 touch $DIR/$tdir/remote_dir/$tfile ||
17658                         error "touch $tfile failed"
17659                 ln $DIR/$tdir/remote_dir/$tfile $file &&
17660                         error "link $file should fail"
17661                 mdt_index=$($LFS getstripe -m $file)
17662                 if [ $mdt_index == 0 ]; then
17663                         # file failed to migrate is not allowed to rename to
17664                         mv $DIR/$tdir/remote_dir/$tfile $file &&
17665                                 error "rename to $file should fail"
17666                 else
17667                         mv $DIR/$tdir/remote_dir/$tfile $file ||
17668                                 error "rename to $file failed"
17669                 fi
17670                 echo hello >> $file || error "write $file failed"
17671         done
17672
17673         # resume migration with different options should fail
17674         $LFS migrate -m 0 $migrate_dir &&
17675                 error "migrate -m 0 $migrate_dir should fail"
17676
17677         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
17678                 error "migrate -c 2 $migrate_dir should fail"
17679
17680         # resume migration should succeed
17681         $LFS migrate -m $MDTIDX $migrate_dir ||
17682                 error "migrate $migrate_dir failed"
17683
17684         echo "Finish migration, then checking.."
17685         for file in $(find $migrate_dir); do
17686                 mdt_index=$($LFS getstripe -m $file)
17687                 [ $mdt_index == $MDTIDX ] ||
17688                         error "$file is not on MDT${MDTIDX}"
17689         done
17690
17691         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17692 }
17693 run_test 230c "check directory accessiblity if migration failed"
17694
17695 test_230d() {
17696         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17697         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17698         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17699                 skip "Need MDS version at least 2.11.52"
17700         # LU-11235
17701         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
17702
17703         local migrate_dir=$DIR/$tdir/migrate_dir
17704         local old_index
17705         local new_index
17706         local old_count
17707         local new_count
17708         local new_hash
17709         local mdt_index
17710         local i
17711         local j
17712
17713         old_index=$((RANDOM % MDSCOUNT))
17714         old_count=$((MDSCOUNT - old_index))
17715         new_index=$((RANDOM % MDSCOUNT))
17716         new_count=$((MDSCOUNT - new_index))
17717         new_hash=1 # for all_char
17718
17719         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
17720         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
17721
17722         test_mkdir $DIR/$tdir
17723         test_mkdir -i $old_index -c $old_count $migrate_dir
17724
17725         for ((i=0; i<100; i++)); do
17726                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
17727                 createmany -o $migrate_dir/dir_${i}/f 100 ||
17728                         error "create files under remote dir failed $i"
17729         done
17730
17731         echo -n "Migrate from MDT$old_index "
17732         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
17733         echo -n "to MDT$new_index"
17734         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
17735         echo
17736
17737         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
17738         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
17739                 error "migrate remote dir error"
17740
17741         echo "Finish migration, then checking.."
17742         for file in $(find $migrate_dir); do
17743                 mdt_index=$($LFS getstripe -m $file)
17744                 if [ $mdt_index -lt $new_index ] ||
17745                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
17746                         error "$file is on MDT$mdt_index"
17747                 fi
17748         done
17749
17750         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17751 }
17752 run_test 230d "check migrate big directory"
17753
17754 test_230e() {
17755         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17756         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17757         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17758                 skip "Need MDS version at least 2.11.52"
17759
17760         local i
17761         local j
17762         local a_fid
17763         local b_fid
17764
17765         mkdir -p $DIR/$tdir
17766         mkdir $DIR/$tdir/migrate_dir
17767         mkdir $DIR/$tdir/other_dir
17768         touch $DIR/$tdir/migrate_dir/a
17769         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
17770         ls $DIR/$tdir/other_dir
17771
17772         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
17773                 error "migrate dir fails"
17774
17775         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
17776         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
17777
17778         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17779         [ $mdt_index == 0 ] || error "a is not on MDT0"
17780
17781         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
17782                 error "migrate dir fails"
17783
17784         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
17785         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
17786
17787         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17788         [ $mdt_index == 1 ] || error "a is not on MDT1"
17789
17790         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
17791         [ $mdt_index == 1 ] || error "b is not on MDT1"
17792
17793         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
17794         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
17795
17796         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
17797
17798         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17799 }
17800 run_test 230e "migrate mulitple local link files"
17801
17802 test_230f() {
17803         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17804         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17805         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17806                 skip "Need MDS version at least 2.11.52"
17807
17808         local a_fid
17809         local ln_fid
17810
17811         mkdir -p $DIR/$tdir
17812         mkdir $DIR/$tdir/migrate_dir
17813         $LFS mkdir -i1 $DIR/$tdir/other_dir
17814         touch $DIR/$tdir/migrate_dir/a
17815         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
17816         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
17817         ls $DIR/$tdir/other_dir
17818
17819         # a should be migrated to MDT1, since no other links on MDT0
17820         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
17821                 error "#1 migrate dir fails"
17822         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
17823         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
17824         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17825         [ $mdt_index == 1 ] || error "a is not on MDT1"
17826
17827         # a should stay on MDT1, because it is a mulitple link file
17828         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
17829                 error "#2 migrate dir fails"
17830         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17831         [ $mdt_index == 1 ] || error "a is not on MDT1"
17832
17833         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
17834                 error "#3 migrate dir fails"
17835
17836         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
17837         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
17838         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
17839
17840         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
17841         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
17842
17843         # a should be migrated to MDT0, since no other links on MDT1
17844         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
17845                 error "#4 migrate dir fails"
17846         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17847         [ $mdt_index == 0 ] || error "a is not on MDT0"
17848
17849         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17850 }
17851 run_test 230f "migrate mulitple remote link files"
17852
17853 test_230g() {
17854         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17855         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17856         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17857                 skip "Need MDS version at least 2.11.52"
17858
17859         mkdir -p $DIR/$tdir/migrate_dir
17860
17861         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
17862                 error "migrating dir to non-exist MDT succeeds"
17863         true
17864 }
17865 run_test 230g "migrate dir to non-exist MDT"
17866
17867 test_230h() {
17868         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17869         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17870         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17871                 skip "Need MDS version at least 2.11.52"
17872
17873         local mdt_index
17874
17875         mkdir -p $DIR/$tdir/migrate_dir
17876
17877         $LFS migrate -m1 $DIR &&
17878                 error "migrating mountpoint1 should fail"
17879
17880         $LFS migrate -m1 $DIR/$tdir/.. &&
17881                 error "migrating mountpoint2 should fail"
17882
17883         # same as mv
17884         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
17885                 error "migrating $tdir/migrate_dir/.. should fail"
17886
17887         true
17888 }
17889 run_test 230h "migrate .. and root"
17890
17891 test_230i() {
17892         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17893         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17894         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17895                 skip "Need MDS version at least 2.11.52"
17896
17897         mkdir -p $DIR/$tdir/migrate_dir
17898
17899         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
17900                 error "migration fails with a tailing slash"
17901
17902         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
17903                 error "migration fails with two tailing slashes"
17904 }
17905 run_test 230i "lfs migrate -m tolerates trailing slashes"
17906
17907 test_230j() {
17908         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
17909         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
17910                 skip "Need MDS version at least 2.11.52"
17911
17912         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
17913         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
17914                 error "create $tfile failed"
17915         cat /etc/passwd > $DIR/$tdir/$tfile
17916
17917         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
17918
17919         cmp /etc/passwd $DIR/$tdir/$tfile ||
17920                 error "DoM file mismatch after migration"
17921 }
17922 run_test 230j "DoM file data not changed after dir migration"
17923
17924 test_230k() {
17925         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
17926         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
17927                 skip "Need MDS version at least 2.11.56"
17928
17929         local total=20
17930         local files_on_starting_mdt=0
17931
17932         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
17933         $LFS getdirstripe $DIR/$tdir
17934         for i in $(seq $total); do
17935                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
17936                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
17937                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
17938         done
17939
17940         echo "$files_on_starting_mdt files on MDT0"
17941
17942         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
17943         $LFS getdirstripe $DIR/$tdir
17944
17945         files_on_starting_mdt=0
17946         for i in $(seq $total); do
17947                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
17948                         error "file $tfile.$i mismatch after migration"
17949                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
17950                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
17951         done
17952
17953         echo "$files_on_starting_mdt files on MDT1 after migration"
17954         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
17955
17956         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
17957         $LFS getdirstripe $DIR/$tdir
17958
17959         files_on_starting_mdt=0
17960         for i in $(seq $total); do
17961                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
17962                         error "file $tfile.$i mismatch after 2nd migration"
17963                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
17964                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
17965         done
17966
17967         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
17968         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
17969
17970         true
17971 }
17972 run_test 230k "file data not changed after dir migration"
17973
17974 test_230l() {
17975         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
17976         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
17977                 skip "Need MDS version at least 2.11.56"
17978
17979         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
17980         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
17981                 error "create files under remote dir failed $i"
17982         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
17983 }
17984 run_test 230l "readdir between MDTs won't crash"
17985
17986 test_230m() {
17987         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
17988         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
17989                 skip "Need MDS version at least 2.11.56"
17990
17991         local MDTIDX=1
17992         local mig_dir=$DIR/$tdir/migrate_dir
17993         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
17994         local shortstr="b"
17995         local val
17996
17997         echo "Creating files and dirs with xattrs"
17998         test_mkdir $DIR/$tdir
17999         test_mkdir -i0 -c1 $mig_dir
18000         mkdir $mig_dir/dir
18001         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
18002                 error "cannot set xattr attr1 on dir"
18003         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
18004                 error "cannot set xattr attr2 on dir"
18005         touch $mig_dir/dir/f0
18006         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
18007                 error "cannot set xattr attr1 on file"
18008         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
18009                 error "cannot set xattr attr2 on file"
18010         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18011         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18012         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
18013         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18014         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
18015         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18016         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
18017         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18018         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
18019
18020         echo "Migrating to MDT1"
18021         $LFS migrate -m $MDTIDX $mig_dir ||
18022                 error "fails on migrating dir to MDT1"
18023
18024         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18025         echo "Checking xattrs"
18026         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18027         [ "$val" = $longstr ] ||
18028                 error "expecting xattr1 $longstr on dir, found $val"
18029         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18030         [ "$val" = $shortstr ] ||
18031                 error "expecting xattr2 $shortstr on dir, found $val"
18032         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18033         [ "$val" = $longstr ] ||
18034                 error "expecting xattr1 $longstr on file, found $val"
18035         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18036         [ "$val" = $shortstr ] ||
18037                 error "expecting xattr2 $shortstr on file, found $val"
18038 }
18039 run_test 230m "xattrs not changed after dir migration"
18040
18041 test_230n() {
18042         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18043         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
18044                 skip "Need MDS version at least 2.13.53"
18045
18046         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
18047         cat /etc/hosts > $DIR/$tdir/$tfile
18048         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
18049         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
18050
18051         cmp /etc/hosts $DIR/$tdir/$tfile ||
18052                 error "File data mismatch after migration"
18053 }
18054 run_test 230n "Dir migration with mirrored file"
18055
18056 test_230o() {
18057         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18058         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18059                 skip "Need MDS version at least 2.13.52"
18060
18061         local mdts=$(comma_list $(mdts_nodes))
18062         local timeout=100
18063
18064         local restripe_status
18065         local delta
18066         local i
18067         local j
18068
18069         [[ $(facet_fstype mds1) == zfs ]] && timeout=300
18070
18071         # in case "crush" hash type is not set
18072         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18073
18074         restripe_status=$(do_facet mds1 $LCTL get_param -n \
18075                            mdt.*MDT0000.enable_dir_restripe)
18076         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
18077         stack_trap "do_nodes $mdts $LCTL set_param \
18078                     mdt.*.enable_dir_restripe=$restripe_status"
18079
18080         mkdir $DIR/$tdir
18081         createmany -m $DIR/$tdir/f 100 ||
18082                 error "create files under remote dir failed $i"
18083         createmany -d $DIR/$tdir/d 100 ||
18084                 error "create dirs under remote dir failed $i"
18085
18086         for i in $(seq 2 $MDSCOUNT); do
18087                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
18088                 $LFS setdirstripe -c $i $DIR/$tdir ||
18089                         error "split -c $i $tdir failed"
18090                 wait_update $HOSTNAME \
18091                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
18092                         error "dir split not finished"
18093                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18094                         awk '/migrate/ {sum += $2} END { print sum }')
18095                 echo "$delta files migrated when dir split from $((i - 1)) to $i stripes"
18096                 # delta is around total_files/stripe_count
18097                 [ $delta -lt $((200 /(i - 1))) ] ||
18098                         error "$delta files migrated"
18099         done
18100 }
18101 run_test 230o "dir split"
18102
18103 test_230p() {
18104         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18105         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18106                 skip "Need MDS version at least 2.13.52"
18107
18108         local mdts=$(comma_list $(mdts_nodes))
18109         local timeout=100
18110
18111         local restripe_status
18112         local delta
18113         local i
18114         local j
18115
18116         [[ $(facet_fstype mds1) == zfs ]] && timeout=300
18117
18118         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18119
18120         restripe_status=$(do_facet mds1 $LCTL get_param -n \
18121                            mdt.*MDT0000.enable_dir_restripe)
18122         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
18123         stack_trap "do_nodes $mdts $LCTL set_param \
18124                     mdt.*.enable_dir_restripe=$restripe_status"
18125
18126         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
18127         createmany -m $DIR/$tdir/f 100 ||
18128                 error "create files under remote dir failed $i"
18129         createmany -d $DIR/$tdir/d 100 ||
18130                 error "create dirs under remote dir failed $i"
18131
18132         for i in $(seq $((MDSCOUNT - 1)) -1 1); do
18133                 local mdt_hash="crush"
18134
18135                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
18136                 $LFS setdirstripe -c $i $DIR/$tdir ||
18137                         error "split -c $i $tdir failed"
18138                 [ $i -eq 1 ] && mdt_hash="none"
18139                 wait_update $HOSTNAME \
18140                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
18141                         error "dir merge not finished"
18142                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18143                         awk '/migrate/ {sum += $2} END { print sum }')
18144                 echo "$delta files migrated when dir merge from $((i + 1)) to $i stripes"
18145                 # delta is around total_files/stripe_count
18146                 [ $delta -lt $((200 / i)) ] ||
18147                         error "$delta files migrated"
18148         done
18149 }
18150 run_test 230p "dir merge"
18151
18152 test_230q() {
18153         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18154         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18155                 skip "Need MDS version at least 2.13.52"
18156
18157         local mdts=$(comma_list $(mdts_nodes))
18158         local saved_threshold=$(do_facet mds1 \
18159                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
18160         local saved_delta=$(do_facet mds1 \
18161                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
18162         local threshold=100
18163         local delta=2
18164         local total=0
18165         local stripe_count=0
18166         local stripe_index
18167         local nr_files
18168
18169         stack_trap "do_nodes $mdts $LCTL set_param \
18170                     mdt.*.dir_split_count=$saved_threshold"
18171         stack_trap "do_nodes $mdts $LCTL set_param \
18172                     mdt.*.dir_split_delta=$saved_delta"
18173         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
18174         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
18175         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
18176         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
18177         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
18178         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18179
18180         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
18181         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
18182
18183         while [ $stripe_count -lt $MDSCOUNT ]; do
18184                 createmany -m $DIR/$tdir/f $total $((threshold * 3 / 2)) ||
18185                         error "create sub files failed"
18186                 stat $DIR/$tdir > /dev/null
18187                 total=$((total + threshold * 3 / 2))
18188                 stripe_count=$((stripe_count + delta))
18189                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
18190
18191                 wait_update $HOSTNAME \
18192                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
18193                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
18194
18195                 wait_update $HOSTNAME \
18196                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
18197                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
18198
18199                 nr_files=$($LFS getstripe -m $DIR/$tdir/* |
18200                            grep -w $stripe_index | wc -l)
18201                 echo "$nr_files files on MDT$stripe_index after split"
18202                 [ $nr_files -lt $((total / (stripe_count - 1))) ] ||
18203                         error "$nr_files files on MDT$stripe_index after split"
18204
18205                 nr_files=$(ls $DIR/$tdir | wc -w)
18206                 [ $nr_files -eq $total ] ||
18207                         error "total sub files $nr_files != $total"
18208         done
18209 }
18210 run_test 230q "dir auto split"
18211
18212 test_231a()
18213 {
18214         # For simplicity this test assumes that max_pages_per_rpc
18215         # is the same across all OSCs
18216         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
18217         local bulk_size=$((max_pages * PAGE_SIZE))
18218         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
18219                                        head -n 1)
18220
18221         mkdir -p $DIR/$tdir
18222         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
18223                 error "failed to set stripe with -S ${brw_size}M option"
18224
18225         # clear the OSC stats
18226         $LCTL set_param osc.*.stats=0 &>/dev/null
18227         stop_writeback
18228
18229         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
18230         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
18231                 oflag=direct &>/dev/null || error "dd failed"
18232
18233         sync; sleep 1; sync # just to be safe
18234         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
18235         if [ x$nrpcs != "x1" ]; then
18236                 $LCTL get_param osc.*.stats
18237                 error "found $nrpcs ost_write RPCs, not 1 as expected"
18238         fi
18239
18240         start_writeback
18241         # Drop the OSC cache, otherwise we will read from it
18242         cancel_lru_locks osc
18243
18244         # clear the OSC stats
18245         $LCTL set_param osc.*.stats=0 &>/dev/null
18246
18247         # Client reads $bulk_size.
18248         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
18249                 iflag=direct &>/dev/null || error "dd failed"
18250
18251         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
18252         if [ x$nrpcs != "x1" ]; then
18253                 $LCTL get_param osc.*.stats
18254                 error "found $nrpcs ost_read RPCs, not 1 as expected"
18255         fi
18256 }
18257 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
18258
18259 test_231b() {
18260         mkdir -p $DIR/$tdir
18261         local i
18262         for i in {0..1023}; do
18263                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
18264                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
18265                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
18266         done
18267         sync
18268 }
18269 run_test 231b "must not assert on fully utilized OST request buffer"
18270
18271 test_232a() {
18272         mkdir -p $DIR/$tdir
18273         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
18274
18275         #define OBD_FAIL_LDLM_OST_LVB            0x31c
18276         do_facet ost1 $LCTL set_param fail_loc=0x31c
18277
18278         # ignore dd failure
18279         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
18280
18281         do_facet ost1 $LCTL set_param fail_loc=0
18282         umount_client $MOUNT || error "umount failed"
18283         mount_client $MOUNT || error "mount failed"
18284         stop ost1 || error "cannot stop ost1"
18285         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18286 }
18287 run_test 232a "failed lock should not block umount"
18288
18289 test_232b() {
18290         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
18291                 skip "Need MDS version at least 2.10.58"
18292
18293         mkdir -p $DIR/$tdir
18294         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
18295         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
18296         sync
18297         cancel_lru_locks osc
18298
18299         #define OBD_FAIL_LDLM_OST_LVB            0x31c
18300         do_facet ost1 $LCTL set_param fail_loc=0x31c
18301
18302         # ignore failure
18303         $LFS data_version $DIR/$tdir/$tfile || true
18304
18305         do_facet ost1 $LCTL set_param fail_loc=0
18306         umount_client $MOUNT || error "umount failed"
18307         mount_client $MOUNT || error "mount failed"
18308         stop ost1 || error "cannot stop ost1"
18309         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18310 }
18311 run_test 232b "failed data version lock should not block umount"
18312
18313 test_233a() {
18314         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
18315                 skip "Need MDS version at least 2.3.64"
18316         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
18317
18318         local fid=$($LFS path2fid $MOUNT)
18319
18320         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18321                 error "cannot access $MOUNT using its FID '$fid'"
18322 }
18323 run_test 233a "checking that OBF of the FS root succeeds"
18324
18325 test_233b() {
18326         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
18327                 skip "Need MDS version at least 2.5.90"
18328         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
18329
18330         local fid=$($LFS path2fid $MOUNT/.lustre)
18331
18332         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18333                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
18334
18335         fid=$($LFS path2fid $MOUNT/.lustre/fid)
18336         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18337                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
18338 }
18339 run_test 233b "checking that OBF of the FS .lustre succeeds"
18340
18341 test_234() {
18342         local p="$TMP/sanityN-$TESTNAME.parameters"
18343         save_lustre_params client "llite.*.xattr_cache" > $p
18344         lctl set_param llite.*.xattr_cache 1 ||
18345                 skip_env "xattr cache is not supported"
18346
18347         mkdir -p $DIR/$tdir || error "mkdir failed"
18348         touch $DIR/$tdir/$tfile || error "touch failed"
18349         # OBD_FAIL_LLITE_XATTR_ENOMEM
18350         $LCTL set_param fail_loc=0x1405
18351         getfattr -n user.attr $DIR/$tdir/$tfile &&
18352                 error "getfattr should have failed with ENOMEM"
18353         $LCTL set_param fail_loc=0x0
18354         rm -rf $DIR/$tdir
18355
18356         restore_lustre_params < $p
18357         rm -f $p
18358 }
18359 run_test 234 "xattr cache should not crash on ENOMEM"
18360
18361 test_235() {
18362         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
18363                 skip "Need MDS version at least 2.4.52"
18364
18365         flock_deadlock $DIR/$tfile
18366         local RC=$?
18367         case $RC in
18368                 0)
18369                 ;;
18370                 124) error "process hangs on a deadlock"
18371                 ;;
18372                 *) error "error executing flock_deadlock $DIR/$tfile"
18373                 ;;
18374         esac
18375 }
18376 run_test 235 "LU-1715: flock deadlock detection does not work properly"
18377
18378 #LU-2935
18379 test_236() {
18380         check_swap_layouts_support
18381
18382         local ref1=/etc/passwd
18383         local ref2=/etc/group
18384         local file1=$DIR/$tdir/f1
18385         local file2=$DIR/$tdir/f2
18386
18387         test_mkdir -c1 $DIR/$tdir
18388         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
18389         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
18390         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
18391         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
18392         local fd=$(free_fd)
18393         local cmd="exec $fd<>$file2"
18394         eval $cmd
18395         rm $file2
18396         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
18397                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
18398         cmd="exec $fd>&-"
18399         eval $cmd
18400         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
18401
18402         #cleanup
18403         rm -rf $DIR/$tdir
18404 }
18405 run_test 236 "Layout swap on open unlinked file"
18406
18407 # LU-4659 linkea consistency
18408 test_238() {
18409         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
18410                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
18411                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
18412                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
18413
18414         touch $DIR/$tfile
18415         ln $DIR/$tfile $DIR/$tfile.lnk
18416         touch $DIR/$tfile.new
18417         mv $DIR/$tfile.new $DIR/$tfile
18418         local fid1=$($LFS path2fid $DIR/$tfile)
18419         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
18420         local path1=$($LFS fid2path $FSNAME "$fid1")
18421         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
18422         local path2=$($LFS fid2path $FSNAME "$fid2")
18423         [ $tfile.lnk == $path2 ] ||
18424                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
18425         rm -f $DIR/$tfile*
18426 }
18427 run_test 238 "Verify linkea consistency"
18428
18429 test_239A() { # was test_239
18430         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
18431                 skip "Need MDS version at least 2.5.60"
18432
18433         local list=$(comma_list $(mdts_nodes))
18434
18435         mkdir -p $DIR/$tdir
18436         createmany -o $DIR/$tdir/f- 5000
18437         unlinkmany $DIR/$tdir/f- 5000
18438         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
18439                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
18440         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
18441                         osp.*MDT*.sync_in_flight" | calc_sum)
18442         [ "$changes" -eq 0 ] || error "$changes not synced"
18443 }
18444 run_test 239A "osp_sync test"
18445
18446 test_239a() { #LU-5297
18447         remote_mds_nodsh && skip "remote MDS with nodsh"
18448
18449         touch $DIR/$tfile
18450         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
18451         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
18452         chgrp $RUNAS_GID $DIR/$tfile
18453         wait_delete_completed
18454 }
18455 run_test 239a "process invalid osp sync record correctly"
18456
18457 test_239b() { #LU-5297
18458         remote_mds_nodsh && skip "remote MDS with nodsh"
18459
18460         touch $DIR/$tfile1
18461         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
18462         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
18463         chgrp $RUNAS_GID $DIR/$tfile1
18464         wait_delete_completed
18465         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
18466         touch $DIR/$tfile2
18467         chgrp $RUNAS_GID $DIR/$tfile2
18468         wait_delete_completed
18469 }
18470 run_test 239b "process osp sync record with ENOMEM error correctly"
18471
18472 test_240() {
18473         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18474         remote_mds_nodsh && skip "remote MDS with nodsh"
18475
18476         mkdir -p $DIR/$tdir
18477
18478         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
18479                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
18480         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
18481                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
18482
18483         umount_client $MOUNT || error "umount failed"
18484         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
18485         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
18486         mount_client $MOUNT || error "failed to mount client"
18487
18488         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
18489         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
18490 }
18491 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
18492
18493 test_241_bio() {
18494         local count=$1
18495         local bsize=$2
18496
18497         for LOOP in $(seq $count); do
18498                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
18499                 cancel_lru_locks $OSC || true
18500         done
18501 }
18502
18503 test_241_dio() {
18504         local count=$1
18505         local bsize=$2
18506
18507         for LOOP in $(seq $1); do
18508                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
18509                         2>/dev/null
18510         done
18511 }
18512
18513 test_241a() { # was test_241
18514         local bsize=$PAGE_SIZE
18515
18516         (( bsize < 40960 )) && bsize=40960
18517         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
18518         ls -la $DIR/$tfile
18519         cancel_lru_locks $OSC
18520         test_241_bio 1000 $bsize &
18521         PID=$!
18522         test_241_dio 1000 $bsize
18523         wait $PID
18524 }
18525 run_test 241a "bio vs dio"
18526
18527 test_241b() {
18528         local bsize=$PAGE_SIZE
18529
18530         (( bsize < 40960 )) && bsize=40960
18531         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
18532         ls -la $DIR/$tfile
18533         test_241_dio 1000 $bsize &
18534         PID=$!
18535         test_241_dio 1000 $bsize
18536         wait $PID
18537 }
18538 run_test 241b "dio vs dio"
18539
18540 test_242() {
18541         remote_mds_nodsh && skip "remote MDS with nodsh"
18542
18543         mkdir -p $DIR/$tdir
18544         touch $DIR/$tdir/$tfile
18545
18546         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
18547         do_facet mds1 lctl set_param fail_loc=0x105
18548         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
18549
18550         do_facet mds1 lctl set_param fail_loc=0
18551         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
18552 }
18553 run_test 242 "mdt_readpage failure should not cause directory unreadable"
18554
18555 test_243()
18556 {
18557         test_mkdir $DIR/$tdir
18558         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
18559 }
18560 run_test 243 "various group lock tests"
18561
18562 test_244a()
18563 {
18564         test_mkdir $DIR/$tdir
18565         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
18566         sendfile_grouplock $DIR/$tdir/$tfile || \
18567                 error "sendfile+grouplock failed"
18568         rm -rf $DIR/$tdir
18569 }
18570 run_test 244a "sendfile with group lock tests"
18571
18572 test_244b()
18573 {
18574         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
18575
18576         local threads=50
18577         local size=$((1024*1024))
18578
18579         test_mkdir $DIR/$tdir
18580         for i in $(seq 1 $threads); do
18581                 local file=$DIR/$tdir/file_$((i / 10))
18582                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
18583                 local pids[$i]=$!
18584         done
18585         for i in $(seq 1 $threads); do
18586                 wait ${pids[$i]}
18587         done
18588 }
18589 run_test 244b "multi-threaded write with group lock"
18590
18591 test_245() {
18592         local flagname="multi_mod_rpcs"
18593         local connect_data_name="max_mod_rpcs"
18594         local out
18595
18596         # check if multiple modify RPCs flag is set
18597         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
18598                 grep "connect_flags:")
18599         echo "$out"
18600
18601         echo "$out" | grep -qw $flagname
18602         if [ $? -ne 0 ]; then
18603                 echo "connect flag $flagname is not set"
18604                 return
18605         fi
18606
18607         # check if multiple modify RPCs data is set
18608         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
18609         echo "$out"
18610
18611         echo "$out" | grep -qw $connect_data_name ||
18612                 error "import should have connect data $connect_data_name"
18613 }
18614 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
18615
18616 cleanup_247() {
18617         local submount=$1
18618
18619         trap 0
18620         umount_client $submount
18621         rmdir $submount
18622 }
18623
18624 test_247a() {
18625         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
18626                 grep -q subtree ||
18627                 skip_env "Fileset feature is not supported"
18628
18629         local submount=${MOUNT}_$tdir
18630
18631         mkdir $MOUNT/$tdir
18632         mkdir -p $submount || error "mkdir $submount failed"
18633         FILESET="$FILESET/$tdir" mount_client $submount ||
18634                 error "mount $submount failed"
18635         trap "cleanup_247 $submount" EXIT
18636         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
18637         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
18638                 error "read $MOUNT/$tdir/$tfile failed"
18639         cleanup_247 $submount
18640 }
18641 run_test 247a "mount subdir as fileset"
18642
18643 test_247b() {
18644         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18645                 skip_env "Fileset feature is not supported"
18646
18647         local submount=${MOUNT}_$tdir
18648
18649         rm -rf $MOUNT/$tdir
18650         mkdir -p $submount || error "mkdir $submount failed"
18651         SKIP_FILESET=1
18652         FILESET="$FILESET/$tdir" mount_client $submount &&
18653                 error "mount $submount should fail"
18654         rmdir $submount
18655 }
18656 run_test 247b "mount subdir that dose not exist"
18657
18658 test_247c() {
18659         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18660                 skip_env "Fileset feature is not supported"
18661
18662         local submount=${MOUNT}_$tdir
18663
18664         mkdir -p $MOUNT/$tdir/dir1
18665         mkdir -p $submount || error "mkdir $submount failed"
18666         trap "cleanup_247 $submount" EXIT
18667         FILESET="$FILESET/$tdir" mount_client $submount ||
18668                 error "mount $submount failed"
18669         local fid=$($LFS path2fid $MOUNT/)
18670         $LFS fid2path $submount $fid && error "fid2path should fail"
18671         cleanup_247 $submount
18672 }
18673 run_test 247c "running fid2path outside subdirectory root"
18674
18675 test_247d() {
18676         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18677                 skip "Fileset feature is not supported"
18678
18679         local submount=${MOUNT}_$tdir
18680
18681         mkdir -p $MOUNT/$tdir/dir1
18682         mkdir -p $submount || error "mkdir $submount failed"
18683         FILESET="$FILESET/$tdir" mount_client $submount ||
18684                 error "mount $submount failed"
18685         trap "cleanup_247 $submount" EXIT
18686
18687         local td=$submount/dir1
18688         local fid=$($LFS path2fid $td)
18689         [ -z "$fid" ] && error "path2fid unable to get $td FID"
18690
18691         # check that we get the same pathname back
18692         local rootpath
18693         local found
18694         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
18695                 echo "$rootpath $fid"
18696                 found=$($LFS fid2path $rootpath "$fid")
18697                 [ -n "found" ] || error "fid2path should succeed"
18698                 [ "$found" == "$td" ] || error "fid2path $found != $td"
18699         done
18700         # check wrong root path format
18701         rootpath=$submount"_wrong"
18702         found=$($LFS fid2path $rootpath "$fid")
18703         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
18704
18705         cleanup_247 $submount
18706 }
18707 run_test 247d "running fid2path inside subdirectory root"
18708
18709 # LU-8037
18710 test_247e() {
18711         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
18712                 grep -q subtree ||
18713                 skip "Fileset feature is not supported"
18714
18715         local submount=${MOUNT}_$tdir
18716
18717         mkdir $MOUNT/$tdir
18718         mkdir -p $submount || error "mkdir $submount failed"
18719         FILESET="$FILESET/.." mount_client $submount &&
18720                 error "mount $submount should fail"
18721         rmdir $submount
18722 }
18723 run_test 247e "mount .. as fileset"
18724
18725 test_247f() {
18726         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18727         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
18728                 skip "Need at least version 2.13.52"
18729         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
18730                 grep -q subtree ||
18731                 skip "Fileset feature is not supported"
18732
18733         mkdir $DIR/$tdir || error "mkdir $tdir failed"
18734         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
18735                 error "mkdir remote failed"
18736         mkdir $DIR/$tdir/remote/subdir || error "mkdir remote/subdir failed"
18737         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped ||
18738                 error "mkdir striped failed"
18739         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
18740
18741         local submount=${MOUNT}_$tdir
18742
18743         mkdir -p $submount || error "mkdir $submount failed"
18744
18745         local dir
18746         local fileset=$FILESET
18747
18748         for dir in $tdir/remote $tdir/remote/subdir \
18749                    $tdir/striped $tdir/striped/subdir $tdir/striped/. ; do
18750                 FILESET="$fileset/$dir" mount_client $submount ||
18751                         error "mount $dir failed"
18752                 umount_client $submount
18753         done
18754 }
18755 run_test 247f "mount striped or remote directory as fileset"
18756
18757 test_248a() {
18758         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
18759         [ -z "$fast_read_sav" ] && skip "no fast read support"
18760
18761         # create a large file for fast read verification
18762         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
18763
18764         # make sure the file is created correctly
18765         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
18766                 { rm -f $DIR/$tfile; skip "file creation error"; }
18767
18768         echo "Test 1: verify that fast read is 4 times faster on cache read"
18769
18770         # small read with fast read enabled
18771         $LCTL set_param -n llite.*.fast_read=1
18772         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
18773                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
18774                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
18775         # small read with fast read disabled
18776         $LCTL set_param -n llite.*.fast_read=0
18777         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
18778                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
18779                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
18780
18781         # verify that fast read is 4 times faster for cache read
18782         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
18783                 error_not_in_vm "fast read was not 4 times faster: " \
18784                            "$t_fast vs $t_slow"
18785
18786         echo "Test 2: verify the performance between big and small read"
18787         $LCTL set_param -n llite.*.fast_read=1
18788
18789         # 1k non-cache read
18790         cancel_lru_locks osc
18791         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
18792                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
18793                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
18794
18795         # 1M non-cache read
18796         cancel_lru_locks osc
18797         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
18798                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
18799                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
18800
18801         # verify that big IO is not 4 times faster than small IO
18802         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
18803                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
18804
18805         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
18806         rm -f $DIR/$tfile
18807 }
18808 run_test 248a "fast read verification"
18809
18810 test_248b() {
18811         # Default short_io_bytes=16384, try both smaller and larger sizes.
18812         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
18813         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
18814         echo "bs=53248 count=113 normal buffered write"
18815         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
18816                 error "dd of initial data file failed"
18817         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
18818
18819         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
18820         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
18821                 error "dd with sync normal writes failed"
18822         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
18823
18824         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
18825         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
18826                 error "dd with sync small writes failed"
18827         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
18828
18829         cancel_lru_locks osc
18830
18831         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
18832         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
18833         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
18834         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
18835                 iflag=direct || error "dd with O_DIRECT small read failed"
18836         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
18837         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
18838                 error "compare $TMP/$tfile.1 failed"
18839
18840         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
18841         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
18842
18843         # just to see what the maximum tunable value is, and test parsing
18844         echo "test invalid parameter 2MB"
18845         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
18846                 error "too-large short_io_bytes allowed"
18847         echo "test maximum parameter 512KB"
18848         # if we can set a larger short_io_bytes, run test regardless of version
18849         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
18850                 # older clients may not allow setting it this large, that's OK
18851                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
18852                         skip "Need at least client version 2.13.50"
18853                 error "medium short_io_bytes failed"
18854         fi
18855         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
18856         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
18857
18858         echo "test large parameter 64KB"
18859         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
18860         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
18861
18862         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
18863         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
18864                 error "dd with sync large writes failed"
18865         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
18866
18867         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
18868         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
18869         num=$((113 * 4096 / PAGE_SIZE))
18870         echo "bs=$size count=$num oflag=direct large write $tfile.3"
18871         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
18872                 error "dd with O_DIRECT large writes failed"
18873         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
18874                 error "compare $DIR/$tfile.3 failed"
18875
18876         cancel_lru_locks osc
18877
18878         echo "bs=$size count=$num iflag=direct large read $tfile.2"
18879         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
18880                 error "dd with O_DIRECT large read failed"
18881         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
18882                 error "compare $TMP/$tfile.2 failed"
18883
18884         echo "bs=$size count=$num iflag=direct large read $tfile.3"
18885         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
18886                 error "dd with O_DIRECT large read failed"
18887         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
18888                 error "compare $TMP/$tfile.3 failed"
18889 }
18890 run_test 248b "test short_io read and write for both small and large sizes"
18891
18892 test_249() { # LU-7890
18893         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
18894                 skip "Need at least version 2.8.54"
18895
18896         rm -f $DIR/$tfile
18897         $LFS setstripe -c 1 $DIR/$tfile
18898         # Offset 2T == 4k * 512M
18899         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
18900                 error "dd to 2T offset failed"
18901 }
18902 run_test 249 "Write above 2T file size"
18903
18904 test_250() {
18905         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
18906          && skip "no 16TB file size limit on ZFS"
18907
18908         $LFS setstripe -c 1 $DIR/$tfile
18909         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
18910         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
18911         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
18912         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
18913                 conv=notrunc,fsync && error "append succeeded"
18914         return 0
18915 }
18916 run_test 250 "Write above 16T limit"
18917
18918 test_251() {
18919         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
18920
18921         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
18922         #Skip once - writing the first stripe will succeed
18923         $LCTL set_param fail_loc=0xa0001407 fail_val=1
18924         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
18925                 error "short write happened"
18926
18927         $LCTL set_param fail_loc=0xa0001407 fail_val=1
18928         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
18929                 error "short read happened"
18930
18931         rm -f $DIR/$tfile
18932 }
18933 run_test 251 "Handling short read and write correctly"
18934
18935 test_252() {
18936         remote_mds_nodsh && skip "remote MDS with nodsh"
18937         remote_ost_nodsh && skip "remote OST with nodsh"
18938         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
18939                 skip_env "ldiskfs only test"
18940         fi
18941
18942         local tgt
18943         local dev
18944         local out
18945         local uuid
18946         local num
18947         local gen
18948
18949         # check lr_reader on OST0000
18950         tgt=ost1
18951         dev=$(facet_device $tgt)
18952         out=$(do_facet $tgt $LR_READER $dev)
18953         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
18954         echo "$out"
18955         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
18956         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
18957                 error "Invalid uuid returned by $LR_READER on target $tgt"
18958         echo -e "uuid returned by $LR_READER is '$uuid'\n"
18959
18960         # check lr_reader -c on MDT0000
18961         tgt=mds1
18962         dev=$(facet_device $tgt)
18963         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
18964                 skip "$LR_READER does not support additional options"
18965         fi
18966         out=$(do_facet $tgt $LR_READER -c $dev)
18967         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
18968         echo "$out"
18969         num=$(echo "$out" | grep -c "mdtlov")
18970         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
18971                 error "Invalid number of mdtlov clients returned by $LR_READER"
18972         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
18973
18974         # check lr_reader -cr on MDT0000
18975         out=$(do_facet $tgt $LR_READER -cr $dev)
18976         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
18977         echo "$out"
18978         echo "$out" | grep -q "^reply_data:$" ||
18979                 error "$LR_READER should have returned 'reply_data' section"
18980         num=$(echo "$out" | grep -c "client_generation")
18981         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
18982 }
18983 run_test 252 "check lr_reader tool"
18984
18985 test_253() {
18986         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18987         remote_mds_nodsh && skip "remote MDS with nodsh"
18988         remote_mgs_nodsh && skip "remote MGS with nodsh"
18989
18990         local ostidx=0
18991         local rc=0
18992         local ost_name=$(ostname_from_index $ostidx)
18993
18994         # on the mdt's osc
18995         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
18996         do_facet $SINGLEMDS $LCTL get_param -n \
18997                 osp.$mdtosc_proc1.reserved_mb_high ||
18998                 skip  "remote MDS does not support reserved_mb_high"
18999
19000         rm -rf $DIR/$tdir
19001         wait_mds_ost_sync
19002         wait_delete_completed
19003         mkdir $DIR/$tdir
19004
19005         pool_add $TESTNAME || error "Pool creation failed"
19006         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
19007
19008         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
19009                 error "Setstripe failed"
19010
19011         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
19012
19013         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
19014                     grep "watermarks")
19015         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
19016
19017         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
19018                         osp.$mdtosc_proc1.prealloc_status)
19019         echo "prealloc_status $oa_status"
19020
19021         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
19022                 error "File creation should fail"
19023
19024         #object allocation was stopped, but we still able to append files
19025         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
19026                 oflag=append || error "Append failed"
19027
19028         rm -f $DIR/$tdir/$tfile.0
19029
19030         # For this test, we want to delete the files we created to go out of
19031         # space but leave the watermark, so we remain nearly out of space
19032         ost_watermarks_enospc_delete_files $tfile $ostidx
19033
19034         wait_delete_completed
19035
19036         sleep_maxage
19037
19038         for i in $(seq 10 12); do
19039                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
19040                         2>/dev/null || error "File creation failed after rm"
19041         done
19042
19043         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
19044                         osp.$mdtosc_proc1.prealloc_status)
19045         echo "prealloc_status $oa_status"
19046
19047         if (( oa_status != 0 )); then
19048                 error "Object allocation still disable after rm"
19049         fi
19050 }
19051 run_test 253 "Check object allocation limit"
19052
19053 test_254() {
19054         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19055         remote_mds_nodsh && skip "remote MDS with nodsh"
19056         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
19057                 skip "MDS does not support changelog_size"
19058
19059         local cl_user
19060         local MDT0=$(facet_svc $SINGLEMDS)
19061
19062         changelog_register || error "changelog_register failed"
19063
19064         changelog_clear 0 || error "changelog_clear failed"
19065
19066         local size1=$(do_facet $SINGLEMDS \
19067                       $LCTL get_param -n mdd.$MDT0.changelog_size)
19068         echo "Changelog size $size1"
19069
19070         rm -rf $DIR/$tdir
19071         $LFS mkdir -i 0 $DIR/$tdir
19072         # change something
19073         mkdir -p $DIR/$tdir/pics/2008/zachy
19074         touch $DIR/$tdir/pics/2008/zachy/timestamp
19075         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
19076         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
19077         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
19078         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
19079         rm $DIR/$tdir/pics/desktop.jpg
19080
19081         local size2=$(do_facet $SINGLEMDS \
19082                       $LCTL get_param -n mdd.$MDT0.changelog_size)
19083         echo "Changelog size after work $size2"
19084
19085         (( $size2 > $size1 )) ||
19086                 error "new Changelog size=$size2 less than old size=$size1"
19087 }
19088 run_test 254 "Check changelog size"
19089
19090 ladvise_no_type()
19091 {
19092         local type=$1
19093         local file=$2
19094
19095         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
19096                 awk -F: '{print $2}' | grep $type > /dev/null
19097         if [ $? -ne 0 ]; then
19098                 return 0
19099         fi
19100         return 1
19101 }
19102
19103 ladvise_no_ioctl()
19104 {
19105         local file=$1
19106
19107         lfs ladvise -a willread $file > /dev/null 2>&1
19108         if [ $? -eq 0 ]; then
19109                 return 1
19110         fi
19111
19112         lfs ladvise -a willread $file 2>&1 |
19113                 grep "Inappropriate ioctl for device" > /dev/null
19114         if [ $? -eq 0 ]; then
19115                 return 0
19116         fi
19117         return 1
19118 }
19119
19120 percent() {
19121         bc <<<"scale=2; ($1 - $2) * 100 / $2"
19122 }
19123
19124 # run a random read IO workload
19125 # usage: random_read_iops <filename> <filesize> <iosize>
19126 random_read_iops() {
19127         local file=$1
19128         local fsize=$2
19129         local iosize=${3:-4096}
19130
19131         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
19132                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
19133 }
19134
19135 drop_file_oss_cache() {
19136         local file="$1"
19137         local nodes="$2"
19138
19139         $LFS ladvise -a dontneed $file 2>/dev/null ||
19140                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
19141 }
19142
19143 ladvise_willread_performance()
19144 {
19145         local repeat=10
19146         local average_origin=0
19147         local average_cache=0
19148         local average_ladvise=0
19149
19150         for ((i = 1; i <= $repeat; i++)); do
19151                 echo "Iter $i/$repeat: reading without willread hint"
19152                 cancel_lru_locks osc
19153                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
19154                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
19155                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
19156                 average_origin=$(bc <<<"$average_origin + $speed_origin")
19157
19158                 cancel_lru_locks osc
19159                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
19160                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
19161                 average_cache=$(bc <<<"$average_cache + $speed_cache")
19162
19163                 cancel_lru_locks osc
19164                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
19165                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
19166                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
19167                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
19168                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
19169         done
19170         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
19171         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
19172         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
19173
19174         speedup_cache=$(percent $average_cache $average_origin)
19175         speedup_ladvise=$(percent $average_ladvise $average_origin)
19176
19177         echo "Average uncached read: $average_origin"
19178         echo "Average speedup with OSS cached read: " \
19179                 "$average_cache = +$speedup_cache%"
19180         echo "Average speedup with ladvise willread: " \
19181                 "$average_ladvise = +$speedup_ladvise%"
19182
19183         local lowest_speedup=20
19184         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
19185                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
19186                         "got $average_cache%. Skipping ladvise willread check."
19187                 return 0
19188         fi
19189
19190         # the test won't work on ZFS until it supports 'ladvise dontneed', but
19191         # it is still good to run until then to exercise 'ladvise willread'
19192         ! $LFS ladvise -a dontneed $DIR/$tfile &&
19193                 [ "$ost1_FSTYPE" = "zfs" ] &&
19194                 echo "osd-zfs does not support dontneed or drop_caches" &&
19195                 return 0
19196
19197         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
19198         [ ${average_ladvise%.*} -gt $lowest_speedup ] ||
19199                 error_not_in_vm "Speedup with willread is less than " \
19200                         "$lowest_speedup%, got $average_ladvise%"
19201 }
19202
19203 test_255a() {
19204         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
19205                 skip "lustre < 2.8.54 does not support ladvise "
19206         remote_ost_nodsh && skip "remote OST with nodsh"
19207
19208         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
19209
19210         ladvise_no_type willread $DIR/$tfile &&
19211                 skip "willread ladvise is not supported"
19212
19213         ladvise_no_ioctl $DIR/$tfile &&
19214                 skip "ladvise ioctl is not supported"
19215
19216         local size_mb=100
19217         local size=$((size_mb * 1048576))
19218         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
19219                 error "dd to $DIR/$tfile failed"
19220
19221         lfs ladvise -a willread $DIR/$tfile ||
19222                 error "Ladvise failed with no range argument"
19223
19224         lfs ladvise -a willread -s 0 $DIR/$tfile ||
19225                 error "Ladvise failed with no -l or -e argument"
19226
19227         lfs ladvise -a willread -e 1 $DIR/$tfile ||
19228                 error "Ladvise failed with only -e argument"
19229
19230         lfs ladvise -a willread -l 1 $DIR/$tfile ||
19231                 error "Ladvise failed with only -l argument"
19232
19233         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
19234                 error "End offset should not be smaller than start offset"
19235
19236         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
19237                 error "End offset should not be equal to start offset"
19238
19239         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
19240                 error "Ladvise failed with overflowing -s argument"
19241
19242         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
19243                 error "Ladvise failed with overflowing -e argument"
19244
19245         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
19246                 error "Ladvise failed with overflowing -l argument"
19247
19248         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
19249                 error "Ladvise succeeded with conflicting -l and -e arguments"
19250
19251         echo "Synchronous ladvise should wait"
19252         local delay=4
19253 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
19254         do_nodes $(comma_list $(osts_nodes)) \
19255                 $LCTL set_param fail_val=$delay fail_loc=0x237
19256
19257         local start_ts=$SECONDS
19258         lfs ladvise -a willread $DIR/$tfile ||
19259                 error "Ladvise failed with no range argument"
19260         local end_ts=$SECONDS
19261         local inteval_ts=$((end_ts - start_ts))
19262
19263         if [ $inteval_ts -lt $(($delay - 1)) ]; then
19264                 error "Synchronous advice didn't wait reply"
19265         fi
19266
19267         echo "Asynchronous ladvise shouldn't wait"
19268         local start_ts=$SECONDS
19269         lfs ladvise -a willread -b $DIR/$tfile ||
19270                 error "Ladvise failed with no range argument"
19271         local end_ts=$SECONDS
19272         local inteval_ts=$((end_ts - start_ts))
19273
19274         if [ $inteval_ts -gt $(($delay / 2)) ]; then
19275                 error "Asynchronous advice blocked"
19276         fi
19277
19278         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
19279         ladvise_willread_performance
19280 }
19281 run_test 255a "check 'lfs ladvise -a willread'"
19282
19283 facet_meminfo() {
19284         local facet=$1
19285         local info=$2
19286
19287         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
19288 }
19289
19290 test_255b() {
19291         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
19292                 skip "lustre < 2.8.54 does not support ladvise "
19293         remote_ost_nodsh && skip "remote OST with nodsh"
19294
19295         lfs setstripe -c 1 -i 0 $DIR/$tfile
19296
19297         ladvise_no_type dontneed $DIR/$tfile &&
19298                 skip "dontneed ladvise is not supported"
19299
19300         ladvise_no_ioctl $DIR/$tfile &&
19301                 skip "ladvise ioctl is not supported"
19302
19303         ! $LFS ladvise -a dontneed $DIR/$tfile &&
19304                 [ "$ost1_FSTYPE" = "zfs" ] &&
19305                 skip "zfs-osd does not support 'ladvise dontneed'"
19306
19307         local size_mb=100
19308         local size=$((size_mb * 1048576))
19309         # In order to prevent disturbance of other processes, only check 3/4
19310         # of the memory usage
19311         local kibibytes=$((size_mb * 1024 * 3 / 4))
19312
19313         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
19314                 error "dd to $DIR/$tfile failed"
19315
19316         #force write to complete before dropping OST cache & checking memory
19317         sync
19318
19319         local total=$(facet_meminfo ost1 MemTotal)
19320         echo "Total memory: $total KiB"
19321
19322         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
19323         local before_read=$(facet_meminfo ost1 Cached)
19324         echo "Cache used before read: $before_read KiB"
19325
19326         lfs ladvise -a willread $DIR/$tfile ||
19327                 error "Ladvise willread failed"
19328         local after_read=$(facet_meminfo ost1 Cached)
19329         echo "Cache used after read: $after_read KiB"
19330
19331         lfs ladvise -a dontneed $DIR/$tfile ||
19332                 error "Ladvise dontneed again failed"
19333         local no_read=$(facet_meminfo ost1 Cached)
19334         echo "Cache used after dontneed ladvise: $no_read KiB"
19335
19336         if [ $total -lt $((before_read + kibibytes)) ]; then
19337                 echo "Memory is too small, abort checking"
19338                 return 0
19339         fi
19340
19341         if [ $((before_read + kibibytes)) -gt $after_read ]; then
19342                 error "Ladvise willread should use more memory" \
19343                         "than $kibibytes KiB"
19344         fi
19345
19346         if [ $((no_read + kibibytes)) -gt $after_read ]; then
19347                 error "Ladvise dontneed should release more memory" \
19348                         "than $kibibytes KiB"
19349         fi
19350 }
19351 run_test 255b "check 'lfs ladvise -a dontneed'"
19352
19353 test_255c() {
19354         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
19355                 skip "lustre < 2.10.50 does not support lockahead"
19356
19357         local count
19358         local new_count
19359         local difference
19360         local i
19361         local rc
19362
19363         test_mkdir -p $DIR/$tdir
19364         $LFS setstripe -i 0 -c 1 $DIR/$tdir
19365
19366         #test 10 returns only success/failure
19367         i=10
19368         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19369         rc=$?
19370         if [ $rc -eq 255 ]; then
19371                 error "Ladvise test${i} failed, ${rc}"
19372         fi
19373
19374         #test 11 counts lock enqueue requests, all others count new locks
19375         i=11
19376         count=$(do_facet ost1 \
19377                 $LCTL get_param -n ost.OSS.ost.stats)
19378         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
19379
19380         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19381         rc=$?
19382         if [ $rc -eq 255 ]; then
19383                 error "Ladvise test${i} failed, ${rc}"
19384         fi
19385
19386         new_count=$(do_facet ost1 \
19387                 $LCTL get_param -n ost.OSS.ost.stats)
19388         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
19389                    awk '{ print $2 }')
19390
19391         difference="$((new_count - count))"
19392         if [ $difference -ne $rc ]; then
19393                 error "Ladvise test${i}, bad enqueue count, returned " \
19394                       "${rc}, actual ${difference}"
19395         fi
19396
19397         for i in $(seq 12 21); do
19398                 # If we do not do this, we run the risk of having too many
19399                 # locks and starting lock cancellation while we are checking
19400                 # lock counts.
19401                 cancel_lru_locks osc
19402
19403                 count=$($LCTL get_param -n \
19404                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
19405
19406                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
19407                 rc=$?
19408                 if [ $rc -eq 255 ]; then
19409                         error "Ladvise test ${i} failed, ${rc}"
19410                 fi
19411
19412                 new_count=$($LCTL get_param -n \
19413                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
19414                 difference="$((new_count - count))"
19415
19416                 # Test 15 output is divided by 100 to map down to valid return
19417                 if [ $i -eq 15 ]; then
19418                         rc="$((rc * 100))"
19419                 fi
19420
19421                 if [ $difference -ne $rc ]; then
19422                         error "Ladvise test ${i}, bad lock count, returned " \
19423                               "${rc}, actual ${difference}"
19424                 fi
19425         done
19426
19427         #test 22 returns only success/failure
19428         i=22
19429         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19430         rc=$?
19431         if [ $rc -eq 255 ]; then
19432                 error "Ladvise test${i} failed, ${rc}"
19433         fi
19434 }
19435 run_test 255c "suite of ladvise lockahead tests"
19436
19437 test_256() {
19438         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19439         remote_mds_nodsh && skip "remote MDS with nodsh"
19440         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
19441         changelog_users $SINGLEMDS | grep "^cl" &&
19442                 skip "active changelog user"
19443
19444         local cl_user
19445         local cat_sl
19446         local mdt_dev
19447
19448         mdt_dev=$(mdsdevname 1)
19449         echo $mdt_dev
19450
19451         changelog_register || error "changelog_register failed"
19452
19453         rm -rf $DIR/$tdir
19454         mkdir -p $DIR/$tdir
19455
19456         changelog_clear 0 || error "changelog_clear failed"
19457
19458         # change something
19459         touch $DIR/$tdir/{1..10}
19460
19461         # stop the MDT
19462         stop $SINGLEMDS || error "Fail to stop MDT"
19463
19464         # remount the MDT
19465
19466         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
19467
19468         #after mount new plainllog is used
19469         touch $DIR/$tdir/{11..19}
19470         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
19471         stack_trap "rm -f $tmpfile"
19472         cat_sl=$(do_facet $SINGLEMDS "sync; \
19473                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
19474                  llog_reader $tmpfile | grep -c type=1064553b")
19475         do_facet $SINGLEMDS llog_reader $tmpfile
19476
19477         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
19478
19479         changelog_clear 0 || error "changelog_clear failed"
19480
19481         cat_sl=$(do_facet $SINGLEMDS "sync; \
19482                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
19483                  llog_reader $tmpfile | grep -c type=1064553b")
19484
19485         if (( cat_sl == 2 )); then
19486                 error "Empty plain llog was not deleted from changelog catalog"
19487         elif (( cat_sl != 1 )); then
19488                 error "Active plain llog shouldn't be deleted from catalog"
19489         fi
19490 }
19491 run_test 256 "Check llog delete for empty and not full state"
19492
19493 test_257() {
19494         remote_mds_nodsh && skip "remote MDS with nodsh"
19495         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
19496                 skip "Need MDS version at least 2.8.55"
19497
19498         test_mkdir $DIR/$tdir
19499
19500         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
19501                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
19502         stat $DIR/$tdir
19503
19504 #define OBD_FAIL_MDS_XATTR_REP                  0x161
19505         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
19506         local facet=mds$((mdtidx + 1))
19507         set_nodes_failloc $(facet_active_host $facet) 0x80000161
19508         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
19509
19510         stop $facet || error "stop MDS failed"
19511         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
19512                 error "start MDS fail"
19513         wait_recovery_complete $facet
19514 }
19515 run_test 257 "xattr locks are not lost"
19516
19517 # Verify we take the i_mutex when security requires it
19518 test_258a() {
19519 #define OBD_FAIL_IMUTEX_SEC 0x141c
19520         $LCTL set_param fail_loc=0x141c
19521         touch $DIR/$tfile
19522         chmod u+s $DIR/$tfile
19523         chmod a+rwx $DIR/$tfile
19524         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
19525         RC=$?
19526         if [ $RC -ne 0 ]; then
19527                 error "error, failed to take i_mutex, rc=$?"
19528         fi
19529         rm -f $DIR/$tfile
19530 }
19531 run_test 258a "verify i_mutex security behavior when suid attributes is set"
19532
19533 # Verify we do NOT take the i_mutex in the normal case
19534 test_258b() {
19535 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
19536         $LCTL set_param fail_loc=0x141d
19537         touch $DIR/$tfile
19538         chmod a+rwx $DIR
19539         chmod a+rw $DIR/$tfile
19540         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
19541         RC=$?
19542         if [ $RC -ne 0 ]; then
19543                 error "error, took i_mutex unnecessarily, rc=$?"
19544         fi
19545         rm -f $DIR/$tfile
19546
19547 }
19548 run_test 258b "verify i_mutex security behavior"
19549
19550 test_259() {
19551         local file=$DIR/$tfile
19552         local before
19553         local after
19554
19555         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
19556
19557         stack_trap "rm -f $file" EXIT
19558
19559         wait_delete_completed
19560         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19561         echo "before: $before"
19562
19563         $LFS setstripe -i 0 -c 1 $file
19564         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
19565         sync_all_data
19566         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19567         echo "after write: $after"
19568
19569 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
19570         do_facet ost1 $LCTL set_param fail_loc=0x2301
19571         $TRUNCATE $file 0
19572         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19573         echo "after truncate: $after"
19574
19575         stop ost1
19576         do_facet ost1 $LCTL set_param fail_loc=0
19577         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19578         sleep 2
19579         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19580         echo "after restart: $after"
19581         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
19582                 error "missing truncate?"
19583
19584         return 0
19585 }
19586 run_test 259 "crash at delayed truncate"
19587
19588 test_260() {
19589 #define OBD_FAIL_MDC_CLOSE               0x806
19590         $LCTL set_param fail_loc=0x80000806
19591         touch $DIR/$tfile
19592
19593 }
19594 run_test 260 "Check mdc_close fail"
19595
19596 ### Data-on-MDT sanity tests ###
19597 test_270a() {
19598         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19599                 skip "Need MDS version at least 2.10.55 for DoM"
19600
19601         # create DoM file
19602         local dom=$DIR/$tdir/dom_file
19603         local tmp=$DIR/$tdir/tmp_file
19604
19605         mkdir -p $DIR/$tdir
19606
19607         # basic checks for DoM component creation
19608         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
19609                 error "Can set MDT layout to non-first entry"
19610
19611         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
19612                 error "Can define multiple entries as MDT layout"
19613
19614         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
19615
19616         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
19617         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
19618         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
19619
19620         local mdtidx=$($LFS getstripe -m $dom)
19621         local mdtname=MDT$(printf %04x $mdtidx)
19622         local facet=mds$((mdtidx + 1))
19623         local space_check=1
19624
19625         # Skip free space checks with ZFS
19626         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
19627
19628         # write
19629         sync
19630         local size_tmp=$((65536 * 3))
19631         local mdtfree1=$(do_facet $facet \
19632                          lctl get_param -n osd*.*$mdtname.kbytesfree)
19633
19634         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
19635         # check also direct IO along write
19636         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
19637         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
19638         sync
19639         cmp $tmp $dom || error "file data is different"
19640         [ $(stat -c%s $dom) == $size_tmp ] ||
19641                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
19642         if [ $space_check == 1 ]; then
19643                 local mdtfree2=$(do_facet $facet \
19644                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
19645
19646                 # increase in usage from by $size_tmp
19647                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
19648                         error "MDT free space wrong after write: " \
19649                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
19650         fi
19651
19652         # truncate
19653         local size_dom=10000
19654
19655         $TRUNCATE $dom $size_dom
19656         [ $(stat -c%s $dom) == $size_dom ] ||
19657                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
19658         if [ $space_check == 1 ]; then
19659                 mdtfree1=$(do_facet $facet \
19660                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19661                 # decrease in usage from $size_tmp to new $size_dom
19662                 [ $(($mdtfree1 - $mdtfree2)) -ge \
19663                   $(((size_tmp - size_dom) / 1024)) ] ||
19664                         error "MDT free space is wrong after truncate: " \
19665                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
19666         fi
19667
19668         # append
19669         cat $tmp >> $dom
19670         sync
19671         size_dom=$((size_dom + size_tmp))
19672         [ $(stat -c%s $dom) == $size_dom ] ||
19673                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
19674         if [ $space_check == 1 ]; then
19675                 mdtfree2=$(do_facet $facet \
19676                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19677                 # increase in usage by $size_tmp from previous
19678                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
19679                         error "MDT free space is wrong after append: " \
19680                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
19681         fi
19682
19683         # delete
19684         rm $dom
19685         if [ $space_check == 1 ]; then
19686                 mdtfree1=$(do_facet $facet \
19687                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19688                 # decrease in usage by $size_dom from previous
19689                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
19690                         error "MDT free space is wrong after removal: " \
19691                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
19692         fi
19693
19694         # combined striping
19695         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
19696                 error "Can't create DoM + OST striping"
19697
19698         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
19699         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
19700         # check also direct IO along write
19701         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
19702         sync
19703         cmp $tmp $dom || error "file data is different"
19704         [ $(stat -c%s $dom) == $size_tmp ] ||
19705                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
19706         rm $dom $tmp
19707
19708         return 0
19709 }
19710 run_test 270a "DoM: basic functionality tests"
19711
19712 test_270b() {
19713         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19714                 skip "Need MDS version at least 2.10.55"
19715
19716         local dom=$DIR/$tdir/dom_file
19717         local max_size=1048576
19718
19719         mkdir -p $DIR/$tdir
19720         $LFS setstripe -E $max_size -L mdt $dom
19721
19722         # truncate over the limit
19723         $TRUNCATE $dom $(($max_size + 1)) &&
19724                 error "successful truncate over the maximum size"
19725         # write over the limit
19726         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
19727                 error "successful write over the maximum size"
19728         # append over the limit
19729         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
19730         echo "12345" >> $dom && error "successful append over the maximum size"
19731         rm $dom
19732
19733         return 0
19734 }
19735 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
19736
19737 test_270c() {
19738         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19739                 skip "Need MDS version at least 2.10.55"
19740
19741         mkdir -p $DIR/$tdir
19742         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
19743
19744         # check files inherit DoM EA
19745         touch $DIR/$tdir/first
19746         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
19747                 error "bad pattern"
19748         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
19749                 error "bad stripe count"
19750         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
19751                 error "bad stripe size"
19752
19753         # check directory inherits DoM EA and uses it as default
19754         mkdir $DIR/$tdir/subdir
19755         touch $DIR/$tdir/subdir/second
19756         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
19757                 error "bad pattern in sub-directory"
19758         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
19759                 error "bad stripe count in sub-directory"
19760         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
19761                 error "bad stripe size in sub-directory"
19762         return 0
19763 }
19764 run_test 270c "DoM: DoM EA inheritance tests"
19765
19766 test_270d() {
19767         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19768                 skip "Need MDS version at least 2.10.55"
19769
19770         mkdir -p $DIR/$tdir
19771         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
19772
19773         # inherit default DoM striping
19774         mkdir $DIR/$tdir/subdir
19775         touch $DIR/$tdir/subdir/f1
19776
19777         # change default directory striping
19778         $LFS setstripe -c 1 $DIR/$tdir/subdir
19779         touch $DIR/$tdir/subdir/f2
19780         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
19781                 error "wrong default striping in file 2"
19782         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
19783                 error "bad pattern in file 2"
19784         return 0
19785 }
19786 run_test 270d "DoM: change striping from DoM to RAID0"
19787
19788 test_270e() {
19789         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19790                 skip "Need MDS version at least 2.10.55"
19791
19792         mkdir -p $DIR/$tdir/dom
19793         mkdir -p $DIR/$tdir/norm
19794         DOMFILES=20
19795         NORMFILES=10
19796         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
19797         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
19798
19799         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
19800         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
19801
19802         # find DoM files by layout
19803         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
19804         [ $NUM -eq  $DOMFILES ] ||
19805                 error "lfs find -L: found $NUM, expected $DOMFILES"
19806         echo "Test 1: lfs find 20 DOM files by layout: OK"
19807
19808         # there should be 1 dir with default DOM striping
19809         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
19810         [ $NUM -eq  1 ] ||
19811                 error "lfs find -L: found $NUM, expected 1 dir"
19812         echo "Test 2: lfs find 1 DOM dir by layout: OK"
19813
19814         # find DoM files by stripe size
19815         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
19816         [ $NUM -eq  $DOMFILES ] ||
19817                 error "lfs find -S: found $NUM, expected $DOMFILES"
19818         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
19819
19820         # find files by stripe offset except DoM files
19821         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
19822         [ $NUM -eq  $NORMFILES ] ||
19823                 error "lfs find -i: found $NUM, expected $NORMFILES"
19824         echo "Test 5: lfs find no DOM files by stripe index: OK"
19825         return 0
19826 }
19827 run_test 270e "DoM: lfs find with DoM files test"
19828
19829 test_270f() {
19830         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19831                 skip "Need MDS version at least 2.10.55"
19832
19833         local mdtname=${FSNAME}-MDT0000-mdtlov
19834         local dom=$DIR/$tdir/dom_file
19835         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
19836                                                 lod.$mdtname.dom_stripesize)
19837         local dom_limit=131072
19838
19839         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
19840         local dom_current=$(do_facet mds1 $LCTL get_param -n \
19841                                                 lod.$mdtname.dom_stripesize)
19842         [ ${dom_limit} -eq ${dom_current} ] ||
19843                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
19844
19845         $LFS mkdir -i 0 -c 1 $DIR/$tdir
19846         $LFS setstripe -d $DIR/$tdir
19847         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
19848                 error "Can't set directory default striping"
19849
19850         # exceed maximum stripe size
19851         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
19852                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
19853         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
19854                 error "Able to create DoM component size more than LOD limit"
19855
19856         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
19857         dom_current=$(do_facet mds1 $LCTL get_param -n \
19858                                                 lod.$mdtname.dom_stripesize)
19859         [ 0 -eq ${dom_current} ] ||
19860                 error "Can't set zero DoM stripe limit"
19861         rm $dom
19862
19863         # attempt to create DoM file on server with disabled DoM should
19864         # remove DoM entry from layout and be succeed
19865         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
19866                 error "Can't create DoM file (DoM is disabled)"
19867         [ $($LFS getstripe -L $dom) == "mdt" ] &&
19868                 error "File has DoM component while DoM is disabled"
19869         rm $dom
19870
19871         # attempt to create DoM file with only DoM stripe should return error
19872         $LFS setstripe -E $dom_limit -L mdt $dom &&
19873                 error "Able to create DoM-only file while DoM is disabled"
19874
19875         # too low values to be aligned with smallest stripe size 64K
19876         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
19877         dom_current=$(do_facet mds1 $LCTL get_param -n \
19878                                                 lod.$mdtname.dom_stripesize)
19879         [ 30000 -eq ${dom_current} ] &&
19880                 error "Can set too small DoM stripe limit"
19881
19882         # 64K is a minimal stripe size in Lustre, expect limit of that size
19883         [ 65536 -eq ${dom_current} ] ||
19884                 error "Limit is not set to 64K but ${dom_current}"
19885
19886         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
19887         dom_current=$(do_facet mds1 $LCTL get_param -n \
19888                                                 lod.$mdtname.dom_stripesize)
19889         echo $dom_current
19890         [ 2147483648 -eq ${dom_current} ] &&
19891                 error "Can set too large DoM stripe limit"
19892
19893         do_facet mds1 $LCTL set_param -n \
19894                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
19895         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
19896                 error "Can't create DoM component size after limit change"
19897         do_facet mds1 $LCTL set_param -n \
19898                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
19899         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
19900                 error "Can't create DoM file after limit decrease"
19901         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
19902                 error "Can create big DoM component after limit decrease"
19903         touch ${dom}_def ||
19904                 error "Can't create file with old default layout"
19905
19906         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
19907         return 0
19908 }
19909 run_test 270f "DoM: maximum DoM stripe size checks"
19910
19911 test_270g() {
19912         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
19913                 skip "Need MDS version at least 2.13.52"
19914         local dom=$DIR/$tdir/$tfile
19915
19916         $LFS mkdir -i 0 -c 1 $DIR/$tdir
19917         local lodname=${FSNAME}-MDT0000-mdtlov
19918
19919         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
19920         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
19921         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
19922         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
19923
19924         local dom_limit=1024
19925         local dom_threshold="50%"
19926
19927         $LFS setstripe -d $DIR/$tdir
19928         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
19929                 error "Can't set directory default striping"
19930
19931         do_facet mds1 $LCTL set_param -n \
19932                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
19933         # set 0 threshold and create DOM file to change tunable stripesize
19934         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
19935         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
19936                 error "Failed to create $dom file"
19937         # now tunable dom_cur_stripesize should reach maximum
19938         local dom_current=$(do_facet mds1 $LCTL get_param -n \
19939                                         lod.${lodname}.dom_stripesize_cur_kb)
19940         [[ $dom_current == $dom_limit ]] ||
19941                 error "Current DOM stripesize is not maximum"
19942         rm $dom
19943
19944         # set threshold for further tests
19945         do_facet mds1 $LCTL set_param -n \
19946                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
19947         echo "DOM threshold is $dom_threshold free space"
19948         local dom_def
19949         local dom_set
19950         # Spoof bfree to exceed threshold
19951         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
19952         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
19953         for spfree in 40 20 0 15 30 55; do
19954                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
19955                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
19956                         error "Failed to create $dom file"
19957                 dom_def=$(do_facet mds1 $LCTL get_param -n \
19958                                         lod.${lodname}.dom_stripesize_cur_kb)
19959                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
19960                 [[ $dom_def != $dom_current ]] ||
19961                         error "Default stripe size was not changed"
19962                 if [[ $spfree > 0 ]] ; then
19963                         dom_set=$($LFS getstripe -S $dom)
19964                         [[ $dom_set == $((dom_def * 1024)) ]] ||
19965                                 error "DOM component size is still old"
19966                 else
19967                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
19968                                 error "DoM component is set with no free space"
19969                 fi
19970                 rm $dom
19971                 dom_current=$dom_def
19972         done
19973 }
19974 run_test 270g "DoM: default DoM stripe size depends on free space"
19975
19976 test_270h() {
19977         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
19978                 skip "Need MDS version at least 2.13.53"
19979
19980         local mdtname=${FSNAME}-MDT0000-mdtlov
19981         local dom=$DIR/$tdir/$tfile
19982         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
19983
19984         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
19985         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
19986
19987         $LFS mkdir -i 0 -c 1 $DIR/$tdir
19988         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
19989                 error "can't create OST file"
19990         # mirrored file with DOM entry in the second mirror
19991         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
19992                 error "can't create mirror with DoM component"
19993
19994         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
19995
19996         # DOM component in the middle and has other enries in the same mirror,
19997         # should succeed but lost DoM component
19998         $LFS setstripe --copy=${dom}_1 $dom ||
19999                 error "Can't create file from OST|DOM mirror layout"
20000         # check new file has no DoM layout after all
20001         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
20002                 error "File has DoM component while DoM is disabled"
20003 }
20004 run_test 270h "DoM: DoM stripe removal when disabled on server"
20005
20006 test_271a() {
20007         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20008                 skip "Need MDS version at least 2.10.55"
20009
20010         local dom=$DIR/$tdir/dom
20011
20012         mkdir -p $DIR/$tdir
20013
20014         $LFS setstripe -E 1024K -L mdt $dom
20015
20016         lctl set_param -n mdc.*.stats=clear
20017         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
20018         cat $dom > /dev/null
20019         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
20020         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
20021         ls $dom
20022         rm -f $dom
20023 }
20024 run_test 271a "DoM: data is cached for read after write"
20025
20026 test_271b() {
20027         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20028                 skip "Need MDS version at least 2.10.55"
20029
20030         local dom=$DIR/$tdir/dom
20031
20032         mkdir -p $DIR/$tdir
20033
20034         $LFS setstripe -E 1024K -L mdt -E EOF $dom
20035
20036         lctl set_param -n mdc.*.stats=clear
20037         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
20038         cancel_lru_locks mdc
20039         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
20040         # second stat to check size is cached on client
20041         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
20042         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
20043         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
20044         rm -f $dom
20045 }
20046 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
20047
20048 test_271ba() {
20049         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20050                 skip "Need MDS version at least 2.10.55"
20051
20052         local dom=$DIR/$tdir/dom
20053
20054         mkdir -p $DIR/$tdir
20055
20056         $LFS setstripe -E 1024K -L mdt -E EOF $dom
20057
20058         lctl set_param -n mdc.*.stats=clear
20059         lctl set_param -n osc.*.stats=clear
20060         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
20061         cancel_lru_locks mdc
20062         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
20063         # second stat to check size is cached on client
20064         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
20065         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
20066         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
20067         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
20068         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
20069         rm -f $dom
20070 }
20071 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
20072
20073
20074 get_mdc_stats() {
20075         local mdtidx=$1
20076         local param=$2
20077         local mdt=MDT$(printf %04x $mdtidx)
20078
20079         if [ -z $param ]; then
20080                 lctl get_param -n mdc.*$mdt*.stats
20081         else
20082                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
20083         fi
20084 }
20085
20086 test_271c() {
20087         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20088                 skip "Need MDS version at least 2.10.55"
20089
20090         local dom=$DIR/$tdir/dom
20091
20092         mkdir -p $DIR/$tdir
20093
20094         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20095
20096         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
20097         local facet=mds$((mdtidx + 1))
20098
20099         cancel_lru_locks mdc
20100         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
20101         createmany -o $dom 1000
20102         lctl set_param -n mdc.*.stats=clear
20103         smalliomany -w $dom 1000 200
20104         get_mdc_stats $mdtidx
20105         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
20106         # Each file has 1 open, 1 IO enqueues, total 2000
20107         # but now we have also +1 getxattr for security.capability, total 3000
20108         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
20109         unlinkmany $dom 1000
20110
20111         cancel_lru_locks mdc
20112         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
20113         createmany -o $dom 1000
20114         lctl set_param -n mdc.*.stats=clear
20115         smalliomany -w $dom 1000 200
20116         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
20117         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
20118         # for OPEN and IO lock.
20119         [ $((enq - enq_2)) -ge 1000 ] ||
20120                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
20121         unlinkmany $dom 1000
20122         return 0
20123 }
20124 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
20125
20126 cleanup_271def_tests() {
20127         trap 0
20128         rm -f $1
20129 }
20130
20131 test_271d() {
20132         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
20133                 skip "Need MDS version at least 2.10.57"
20134
20135         local dom=$DIR/$tdir/dom
20136         local tmp=$TMP/$tfile
20137         trap "cleanup_271def_tests $tmp" EXIT
20138
20139         mkdir -p $DIR/$tdir
20140
20141         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20142
20143         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
20144
20145         cancel_lru_locks mdc
20146         dd if=/dev/urandom of=$tmp bs=1000 count=1
20147         dd if=$tmp of=$dom bs=1000 count=1
20148         cancel_lru_locks mdc
20149
20150         cat /etc/hosts >> $tmp
20151         lctl set_param -n mdc.*.stats=clear
20152
20153         # append data to the same file it should update local page
20154         echo "Append to the same page"
20155         cat /etc/hosts >> $dom
20156         local num=$(get_mdc_stats $mdtidx ost_read)
20157         local ra=$(get_mdc_stats $mdtidx req_active)
20158         local rw=$(get_mdc_stats $mdtidx req_waittime)
20159
20160         [ -z $num ] || error "$num READ RPC occured"
20161         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20162         echo "... DONE"
20163
20164         # compare content
20165         cmp $tmp $dom || error "file miscompare"
20166
20167         cancel_lru_locks mdc
20168         lctl set_param -n mdc.*.stats=clear
20169
20170         echo "Open and read file"
20171         cat $dom > /dev/null
20172         local num=$(get_mdc_stats $mdtidx ost_read)
20173         local ra=$(get_mdc_stats $mdtidx req_active)
20174         local rw=$(get_mdc_stats $mdtidx req_waittime)
20175
20176         [ -z $num ] || error "$num READ RPC occured"
20177         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20178         echo "... DONE"
20179
20180         # compare content
20181         cmp $tmp $dom || error "file miscompare"
20182
20183         return 0
20184 }
20185 run_test 271d "DoM: read on open (1K file in reply buffer)"
20186
20187 test_271f() {
20188         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
20189                 skip "Need MDS version at least 2.10.57"
20190
20191         local dom=$DIR/$tdir/dom
20192         local tmp=$TMP/$tfile
20193         trap "cleanup_271def_tests $tmp" EXIT
20194
20195         mkdir -p $DIR/$tdir
20196
20197         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20198
20199         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
20200
20201         cancel_lru_locks mdc
20202         dd if=/dev/urandom of=$tmp bs=265000 count=1
20203         dd if=$tmp of=$dom bs=265000 count=1
20204         cancel_lru_locks mdc
20205         cat /etc/hosts >> $tmp
20206         lctl set_param -n mdc.*.stats=clear
20207
20208         echo "Append to the same page"
20209         cat /etc/hosts >> $dom
20210         local num=$(get_mdc_stats $mdtidx ost_read)
20211         local ra=$(get_mdc_stats $mdtidx req_active)
20212         local rw=$(get_mdc_stats $mdtidx req_waittime)
20213
20214         [ -z $num ] || error "$num READ RPC occured"
20215         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20216         echo "... DONE"
20217
20218         # compare content
20219         cmp $tmp $dom || error "file miscompare"
20220
20221         cancel_lru_locks mdc
20222         lctl set_param -n mdc.*.stats=clear
20223
20224         echo "Open and read file"
20225         cat $dom > /dev/null
20226         local num=$(get_mdc_stats $mdtidx ost_read)
20227         local ra=$(get_mdc_stats $mdtidx req_active)
20228         local rw=$(get_mdc_stats $mdtidx req_waittime)
20229
20230         [ -z $num ] && num=0
20231         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
20232         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20233         echo "... DONE"
20234
20235         # compare content
20236         cmp $tmp $dom || error "file miscompare"
20237
20238         return 0
20239 }
20240 run_test 271f "DoM: read on open (200K file and read tail)"
20241
20242 test_271g() {
20243         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
20244                 skip "Skipping due to old client or server version"
20245
20246         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
20247         # to get layout
20248         $CHECKSTAT -t file $DIR1/$tfile
20249
20250         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
20251         MULTIOP_PID=$!
20252         sleep 1
20253         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
20254         $LCTL set_param fail_loc=0x80000314
20255         rm $DIR1/$tfile || error "Unlink fails"
20256         RC=$?
20257         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
20258         [ $RC -eq 0 ] || error "Failed write to stale object"
20259 }
20260 run_test 271g "Discard DoM data vs client flush race"
20261
20262 test_272a() {
20263         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20264                 skip "Need MDS version at least 2.11.50"
20265
20266         local dom=$DIR/$tdir/dom
20267         mkdir -p $DIR/$tdir
20268
20269         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
20270         dd if=/dev/urandom of=$dom bs=512K count=1 ||
20271                 error "failed to write data into $dom"
20272         local old_md5=$(md5sum $dom)
20273
20274         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
20275                 error "failed to migrate to the same DoM component"
20276
20277         local new_md5=$(md5sum $dom)
20278
20279         [ "$old_md5" == "$new_md5" ] ||
20280                 error "md5sum differ: $old_md5, $new_md5"
20281
20282         [ $($LFS getstripe -c $dom) -eq 2 ] ||
20283                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
20284 }
20285 run_test 272a "DoM migration: new layout with the same DOM component"
20286
20287 test_272b() {
20288         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20289                 skip "Need MDS version at least 2.11.50"
20290
20291         local dom=$DIR/$tdir/dom
20292         mkdir -p $DIR/$tdir
20293         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20294
20295         local mdtidx=$($LFS getstripe -m $dom)
20296         local mdtname=MDT$(printf %04x $mdtidx)
20297         local facet=mds$((mdtidx + 1))
20298
20299         local mdtfree1=$(do_facet $facet \
20300                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20301         dd if=/dev/urandom of=$dom bs=2M count=1 ||
20302                 error "failed to write data into $dom"
20303         local old_md5=$(md5sum $dom)
20304         cancel_lru_locks mdc
20305         local mdtfree1=$(do_facet $facet \
20306                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20307
20308         $LFS migrate -c2 $dom ||
20309                 error "failed to migrate to the new composite layout"
20310         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20311                 error "MDT stripe was not removed"
20312
20313         cancel_lru_locks mdc
20314         local new_md5=$(md5sum $dom)
20315         [ "$old_md5" == "$new_md5" ] ||
20316                 error "$old_md5 != $new_md5"
20317
20318         # Skip free space checks with ZFS
20319         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20320                 local mdtfree2=$(do_facet $facet \
20321                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20322                 [ $mdtfree2 -gt $mdtfree1 ] ||
20323                         error "MDT space is not freed after migration"
20324         fi
20325         return 0
20326 }
20327 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
20328
20329 test_272c() {
20330         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20331                 skip "Need MDS version at least 2.11.50"
20332
20333         local dom=$DIR/$tdir/$tfile
20334         mkdir -p $DIR/$tdir
20335         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20336
20337         local mdtidx=$($LFS getstripe -m $dom)
20338         local mdtname=MDT$(printf %04x $mdtidx)
20339         local facet=mds$((mdtidx + 1))
20340
20341         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
20342                 error "failed to write data into $dom"
20343         local old_md5=$(md5sum $dom)
20344         cancel_lru_locks mdc
20345         local mdtfree1=$(do_facet $facet \
20346                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20347
20348         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
20349                 error "failed to migrate to the new composite layout"
20350         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
20351                 error "MDT stripe was not removed"
20352
20353         cancel_lru_locks mdc
20354         local new_md5=$(md5sum $dom)
20355         [ "$old_md5" == "$new_md5" ] ||
20356                 error "$old_md5 != $new_md5"
20357
20358         # Skip free space checks with ZFS
20359         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20360                 local mdtfree2=$(do_facet $facet \
20361                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20362                 [ $mdtfree2 -gt $mdtfree1 ] ||
20363                         error "MDS space is not freed after migration"
20364         fi
20365         return 0
20366 }
20367 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
20368
20369 test_272d() {
20370         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20371                 skip "Need MDS version at least 2.12.55"
20372
20373         local dom=$DIR/$tdir/$tfile
20374         mkdir -p $DIR/$tdir
20375         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20376
20377         local mdtidx=$($LFS getstripe -m $dom)
20378         local mdtname=MDT$(printf %04x $mdtidx)
20379         local facet=mds$((mdtidx + 1))
20380
20381         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
20382                 error "failed to write data into $dom"
20383         local old_md5=$(md5sum $dom)
20384         cancel_lru_locks mdc
20385         local mdtfree1=$(do_facet $facet \
20386                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20387
20388         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
20389                 error "failed mirroring to the new composite layout"
20390         $LFS mirror resync $dom ||
20391                 error "failed mirror resync"
20392         $LFS mirror split --mirror-id 1 -d $dom ||
20393                 error "failed mirror split"
20394
20395         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20396                 error "MDT stripe was not removed"
20397
20398         cancel_lru_locks mdc
20399         local new_md5=$(md5sum $dom)
20400         [ "$old_md5" == "$new_md5" ] ||
20401                 error "$old_md5 != $new_md5"
20402
20403         # Skip free space checks with ZFS
20404         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20405                 local mdtfree2=$(do_facet $facet \
20406                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20407                 [ $mdtfree2 -gt $mdtfree1 ] ||
20408                         error "MDS space is not freed after DOM mirror deletion"
20409         fi
20410         return 0
20411 }
20412 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
20413
20414 test_272e() {
20415         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20416                 skip "Need MDS version at least 2.12.55"
20417
20418         local dom=$DIR/$tdir/$tfile
20419         mkdir -p $DIR/$tdir
20420         $LFS setstripe -c 2 $dom
20421
20422         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
20423                 error "failed to write data into $dom"
20424         local old_md5=$(md5sum $dom)
20425         cancel_lru_locks mdc
20426
20427         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
20428                 error "failed mirroring to the DOM layout"
20429         $LFS mirror resync $dom ||
20430                 error "failed mirror resync"
20431         $LFS mirror split --mirror-id 1 -d $dom ||
20432                 error "failed mirror split"
20433
20434         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20435                 error "MDT stripe was not removed"
20436
20437         cancel_lru_locks mdc
20438         local new_md5=$(md5sum $dom)
20439         [ "$old_md5" == "$new_md5" ] ||
20440                 error "$old_md5 != $new_md5"
20441
20442         return 0
20443 }
20444 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
20445
20446 test_272f() {
20447         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20448                 skip "Need MDS version at least 2.12.55"
20449
20450         local dom=$DIR/$tdir/$tfile
20451         mkdir -p $DIR/$tdir
20452         $LFS setstripe -c 2 $dom
20453
20454         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
20455                 error "failed to write data into $dom"
20456         local old_md5=$(md5sum $dom)
20457         cancel_lru_locks mdc
20458
20459         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
20460                 error "failed migrating to the DOM file"
20461
20462         cancel_lru_locks mdc
20463         local new_md5=$(md5sum $dom)
20464         [ "$old_md5" != "$new_md5" ] &&
20465                 error "$old_md5 != $new_md5"
20466
20467         return 0
20468 }
20469 run_test 272f "DoM migration: OST-striped file to DOM file"
20470
20471 test_273a() {
20472         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20473                 skip "Need MDS version at least 2.11.50"
20474
20475         # Layout swap cannot be done if either file has DOM component,
20476         # this will never be supported, migration should be used instead
20477
20478         local dom=$DIR/$tdir/$tfile
20479         mkdir -p $DIR/$tdir
20480
20481         $LFS setstripe -c2 ${dom}_plain
20482         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
20483         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
20484                 error "can swap layout with DoM component"
20485         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
20486                 error "can swap layout with DoM component"
20487
20488         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
20489         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
20490                 error "can swap layout with DoM component"
20491         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
20492                 error "can swap layout with DoM component"
20493         return 0
20494 }
20495 run_test 273a "DoM: layout swapping should fail with DOM"
20496
20497 test_275() {
20498         remote_ost_nodsh && skip "remote OST with nodsh"
20499         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
20500                 skip "Need OST version >= 2.10.57"
20501
20502         local file=$DIR/$tfile
20503         local oss
20504
20505         oss=$(comma_list $(osts_nodes))
20506
20507         dd if=/dev/urandom of=$file bs=1M count=2 ||
20508                 error "failed to create a file"
20509         cancel_lru_locks osc
20510
20511         #lock 1
20512         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
20513                 error "failed to read a file"
20514
20515 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
20516         $LCTL set_param fail_loc=0x8000031f
20517
20518         cancel_lru_locks osc &
20519         sleep 1
20520
20521 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
20522         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
20523         #IO takes another lock, but matches the PENDING one
20524         #and places it to the IO RPC
20525         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
20526                 error "failed to read a file with PENDING lock"
20527 }
20528 run_test 275 "Read on a canceled duplicate lock"
20529
20530 test_276() {
20531         remote_ost_nodsh && skip "remote OST with nodsh"
20532         local pid
20533
20534         do_facet ost1 "(while true; do \
20535                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
20536                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
20537         pid=$!
20538
20539         for LOOP in $(seq 20); do
20540                 stop ost1
20541                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
20542         done
20543         kill -9 $pid
20544         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
20545                 rm $TMP/sanity_276_pid"
20546 }
20547 run_test 276 "Race between mount and obd_statfs"
20548
20549 test_277() {
20550         $LCTL set_param ldlm.namespaces.*.lru_size=0
20551         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
20552         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
20553                         grep ^used_mb | awk '{print $2}')
20554         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
20555         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
20556                 oflag=direct conv=notrunc
20557         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
20558                         grep ^used_mb | awk '{print $2}')
20559         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
20560 }
20561 run_test 277 "Direct IO shall drop page cache"
20562
20563 test_278() {
20564         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
20565         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
20566         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
20567                 skip "needs the same host for mdt1 mdt2" && return
20568
20569         local pid1
20570         local pid2
20571
20572 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
20573         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
20574         stop mds2 &
20575         pid2=$!
20576
20577         stop mds1
20578
20579         echo "Starting MDTs"
20580         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
20581         wait $pid2
20582 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
20583 #will return NULL
20584         do_facet mds2 $LCTL set_param fail_loc=0
20585
20586         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
20587         wait_recovery_complete mds2
20588 }
20589 run_test 278 "Race starting MDS between MDTs stop/start"
20590
20591 test_280() {
20592         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
20593                 skip "Need MGS version at least 2.13.52"
20594         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20595         combined_mgs_mds || skip "needs combined MGS/MDT"
20596
20597         umount_client $MOUNT
20598 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
20599         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
20600
20601         mount_client $MOUNT &
20602         sleep 1
20603         stop mgs || error "stop mgs failed"
20604         #for a race mgs would crash
20605         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
20606         mount_client $MOUNT || error "mount client failed"
20607 }
20608 run_test 280 "Race between MGS umount and client llog processing"
20609
20610 cleanup_test_300() {
20611         trap 0
20612         umask $SAVE_UMASK
20613 }
20614 test_striped_dir() {
20615         local mdt_index=$1
20616         local stripe_count
20617         local stripe_index
20618
20619         mkdir -p $DIR/$tdir
20620
20621         SAVE_UMASK=$(umask)
20622         trap cleanup_test_300 RETURN EXIT
20623
20624         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
20625                                                 $DIR/$tdir/striped_dir ||
20626                 error "set striped dir error"
20627
20628         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
20629         [ "$mode" = "755" ] || error "expect 755 got $mode"
20630
20631         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
20632                 error "getdirstripe failed"
20633         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
20634         if [ "$stripe_count" != "2" ]; then
20635                 error "1:stripe_count is $stripe_count, expect 2"
20636         fi
20637         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
20638         if [ "$stripe_count" != "2" ]; then
20639                 error "2:stripe_count is $stripe_count, expect 2"
20640         fi
20641
20642         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
20643         if [ "$stripe_index" != "$mdt_index" ]; then
20644                 error "stripe_index is $stripe_index, expect $mdt_index"
20645         fi
20646
20647         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
20648                 error "nlink error after create striped dir"
20649
20650         mkdir $DIR/$tdir/striped_dir/a
20651         mkdir $DIR/$tdir/striped_dir/b
20652
20653         stat $DIR/$tdir/striped_dir/a ||
20654                 error "create dir under striped dir failed"
20655         stat $DIR/$tdir/striped_dir/b ||
20656                 error "create dir under striped dir failed"
20657
20658         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
20659                 error "nlink error after mkdir"
20660
20661         rmdir $DIR/$tdir/striped_dir/a
20662         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
20663                 error "nlink error after rmdir"
20664
20665         rmdir $DIR/$tdir/striped_dir/b
20666         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
20667                 error "nlink error after rmdir"
20668
20669         chattr +i $DIR/$tdir/striped_dir
20670         createmany -o $DIR/$tdir/striped_dir/f 10 &&
20671                 error "immutable flags not working under striped dir!"
20672         chattr -i $DIR/$tdir/striped_dir
20673
20674         rmdir $DIR/$tdir/striped_dir ||
20675                 error "rmdir striped dir error"
20676
20677         cleanup_test_300
20678
20679         true
20680 }
20681
20682 test_300a() {
20683         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20684                 skip "skipped for lustre < 2.7.0"
20685         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20686         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20687
20688         test_striped_dir 0 || error "failed on striped dir on MDT0"
20689         test_striped_dir 1 || error "failed on striped dir on MDT0"
20690 }
20691 run_test 300a "basic striped dir sanity test"
20692
20693 test_300b() {
20694         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20695                 skip "skipped for lustre < 2.7.0"
20696         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20697         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20698
20699         local i
20700         local mtime1
20701         local mtime2
20702         local mtime3
20703
20704         test_mkdir $DIR/$tdir || error "mkdir fail"
20705         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
20706                 error "set striped dir error"
20707         for i in {0..9}; do
20708                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
20709                 sleep 1
20710                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
20711                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
20712                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
20713                 sleep 1
20714                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
20715                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
20716                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
20717         done
20718         true
20719 }
20720 run_test 300b "check ctime/mtime for striped dir"
20721
20722 test_300c() {
20723         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20724                 skip "skipped for lustre < 2.7.0"
20725         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20726         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20727
20728         local file_count
20729
20730         mkdir -p $DIR/$tdir
20731         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
20732                 error "set striped dir error"
20733
20734         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
20735                 error "chown striped dir failed"
20736
20737         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
20738                 error "create 5k files failed"
20739
20740         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
20741
20742         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
20743
20744         rm -rf $DIR/$tdir
20745 }
20746 run_test 300c "chown && check ls under striped directory"
20747
20748 test_300d() {
20749         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20750                 skip "skipped for lustre < 2.7.0"
20751         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20752         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20753
20754         local stripe_count
20755         local file
20756
20757         mkdir -p $DIR/$tdir
20758         $LFS setstripe -c 2 $DIR/$tdir
20759
20760         #local striped directory
20761         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
20762                 error "set striped dir error"
20763         #look at the directories for debug purposes
20764         ls -l $DIR/$tdir
20765         $LFS getdirstripe $DIR/$tdir
20766         ls -l $DIR/$tdir/striped_dir
20767         $LFS getdirstripe $DIR/$tdir/striped_dir
20768         createmany -o $DIR/$tdir/striped_dir/f 10 ||
20769                 error "create 10 files failed"
20770
20771         #remote striped directory
20772         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
20773                 error "set striped dir error"
20774         #look at the directories for debug purposes
20775         ls -l $DIR/$tdir
20776         $LFS getdirstripe $DIR/$tdir
20777         ls -l $DIR/$tdir/remote_striped_dir
20778         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
20779         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
20780                 error "create 10 files failed"
20781
20782         for file in $(find $DIR/$tdir); do
20783                 stripe_count=$($LFS getstripe -c $file)
20784                 [ $stripe_count -eq 2 ] ||
20785                         error "wrong stripe $stripe_count for $file"
20786         done
20787
20788         rm -rf $DIR/$tdir
20789 }
20790 run_test 300d "check default stripe under striped directory"
20791
20792 test_300e() {
20793         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20794                 skip "Need MDS version at least 2.7.55"
20795         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20796         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20797
20798         local stripe_count
20799         local file
20800
20801         mkdir -p $DIR/$tdir
20802
20803         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
20804                 error "set striped dir error"
20805
20806         touch $DIR/$tdir/striped_dir/a
20807         touch $DIR/$tdir/striped_dir/b
20808         touch $DIR/$tdir/striped_dir/c
20809
20810         mkdir $DIR/$tdir/striped_dir/dir_a
20811         mkdir $DIR/$tdir/striped_dir/dir_b
20812         mkdir $DIR/$tdir/striped_dir/dir_c
20813
20814         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
20815                 error "set striped adir under striped dir error"
20816
20817         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
20818                 error "set striped bdir under striped dir error"
20819
20820         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
20821                 error "set striped cdir under striped dir error"
20822
20823         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
20824                 error "rename dir under striped dir fails"
20825
20826         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
20827                 error "rename dir under different stripes fails"
20828
20829         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
20830                 error "rename file under striped dir should succeed"
20831
20832         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
20833                 error "rename dir under striped dir should succeed"
20834
20835         rm -rf $DIR/$tdir
20836 }
20837 run_test 300e "check rename under striped directory"
20838
20839 test_300f() {
20840         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20841         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20842         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20843                 skip "Need MDS version at least 2.7.55"
20844
20845         local stripe_count
20846         local file
20847
20848         rm -rf $DIR/$tdir
20849         mkdir -p $DIR/$tdir
20850
20851         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
20852                 error "set striped dir error"
20853
20854         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
20855                 error "set striped dir error"
20856
20857         touch $DIR/$tdir/striped_dir/a
20858         mkdir $DIR/$tdir/striped_dir/dir_a
20859         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
20860                 error "create striped dir under striped dir fails"
20861
20862         touch $DIR/$tdir/striped_dir1/b
20863         mkdir $DIR/$tdir/striped_dir1/dir_b
20864         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
20865                 error "create striped dir under striped dir fails"
20866
20867         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
20868                 error "rename dir under different striped dir should fail"
20869
20870         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
20871                 error "rename striped dir under diff striped dir should fail"
20872
20873         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
20874                 error "rename file under diff striped dirs fails"
20875
20876         rm -rf $DIR/$tdir
20877 }
20878 run_test 300f "check rename cross striped directory"
20879
20880 test_300_check_default_striped_dir()
20881 {
20882         local dirname=$1
20883         local default_count=$2
20884         local default_index=$3
20885         local stripe_count
20886         local stripe_index
20887         local dir_stripe_index
20888         local dir
20889
20890         echo "checking $dirname $default_count $default_index"
20891         $LFS setdirstripe -D -c $default_count -i $default_index \
20892                                 -t all_char $DIR/$tdir/$dirname ||
20893                 error "set default stripe on striped dir error"
20894         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
20895         [ $stripe_count -eq $default_count ] ||
20896                 error "expect $default_count get $stripe_count for $dirname"
20897
20898         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
20899         [ $stripe_index -eq $default_index ] ||
20900                 error "expect $default_index get $stripe_index for $dirname"
20901
20902         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
20903                                                 error "create dirs failed"
20904
20905         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
20906         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
20907         for dir in $(find $DIR/$tdir/$dirname/*); do
20908                 stripe_count=$($LFS getdirstripe -c $dir)
20909                 [ $stripe_count -eq $default_count ] ||
20910                 [ $stripe_count -eq 0 ] || [ $default_count -eq 1 ] ||
20911                 error "stripe count $default_count != $stripe_count for $dir"
20912
20913                 stripe_index=$($LFS getdirstripe -i $dir)
20914                 [ $default_index -eq -1 ] ||
20915                         [ $stripe_index -eq $default_index ] ||
20916                         error "$stripe_index != $default_index for $dir"
20917
20918                 #check default stripe
20919                 stripe_count=$($LFS getdirstripe -D -c $dir)
20920                 [ $stripe_count -eq $default_count ] ||
20921                 error "default count $default_count != $stripe_count for $dir"
20922
20923                 stripe_index=$($LFS getdirstripe -D -i $dir)
20924                 [ $stripe_index -eq $default_index ] ||
20925                 error "default index $default_index != $stripe_index for $dir"
20926         done
20927         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
20928 }
20929
20930 test_300g() {
20931         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20932         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20933                 skip "Need MDS version at least 2.7.55"
20934
20935         local dir
20936         local stripe_count
20937         local stripe_index
20938
20939         mkdir $DIR/$tdir
20940         mkdir $DIR/$tdir/normal_dir
20941
20942         #Checking when client cache stripe index
20943         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
20944         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
20945                 error "create striped_dir failed"
20946
20947         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
20948                 error "create dir0 fails"
20949         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
20950         [ $stripe_index -eq 0 ] ||
20951                 error "dir0 expect index 0 got $stripe_index"
20952
20953         mkdir $DIR/$tdir/striped_dir/dir1 ||
20954                 error "create dir1 fails"
20955         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
20956         [ $stripe_index -eq 1 ] ||
20957                 error "dir1 expect index 1 got $stripe_index"
20958
20959         #check default stripe count/stripe index
20960         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
20961         test_300_check_default_striped_dir normal_dir 1 0
20962         test_300_check_default_striped_dir normal_dir 2 1
20963         test_300_check_default_striped_dir normal_dir 2 -1
20964
20965         #delete default stripe information
20966         echo "delete default stripeEA"
20967         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
20968                 error "set default stripe on striped dir error"
20969
20970         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
20971         for dir in $(find $DIR/$tdir/normal_dir/*); do
20972                 stripe_count=$($LFS getdirstripe -c $dir)
20973                 [ $stripe_count -eq 0 ] ||
20974                         error "expect 1 get $stripe_count for $dir"
20975                 stripe_index=$($LFS getdirstripe -i $dir)
20976                 [ $stripe_index -eq 0 ] ||
20977                         error "expect 0 get $stripe_index for $dir"
20978         done
20979 }
20980 run_test 300g "check default striped directory for normal directory"
20981
20982 test_300h() {
20983         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20984         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20985                 skip "Need MDS version at least 2.7.55"
20986
20987         local dir
20988         local stripe_count
20989
20990         mkdir $DIR/$tdir
20991         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
20992                 error "set striped dir error"
20993
20994         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
20995         test_300_check_default_striped_dir striped_dir 1 0
20996         test_300_check_default_striped_dir striped_dir 2 1
20997         test_300_check_default_striped_dir striped_dir 2 -1
20998
20999         #delete default stripe information
21000         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
21001                 error "set default stripe on striped dir error"
21002
21003         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
21004         for dir in $(find $DIR/$tdir/striped_dir/*); do
21005                 stripe_count=$($LFS getdirstripe -c $dir)
21006                 [ $stripe_count -eq 0 ] ||
21007                         error "expect 1 get $stripe_count for $dir"
21008         done
21009 }
21010 run_test 300h "check default striped directory for striped directory"
21011
21012 test_300i() {
21013         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21014         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21015         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21016                 skip "Need MDS version at least 2.7.55"
21017
21018         local stripe_count
21019         local file
21020
21021         mkdir $DIR/$tdir
21022
21023         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21024                 error "set striped dir error"
21025
21026         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
21027                 error "create files under striped dir failed"
21028
21029         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
21030                 error "set striped hashdir error"
21031
21032         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
21033                 error "create dir0 under hash dir failed"
21034         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
21035                 error "create dir1 under hash dir failed"
21036
21037         # unfortunately, we need to umount to clear dir layout cache for now
21038         # once we fully implement dir layout, we can drop this
21039         umount_client $MOUNT || error "umount failed"
21040         mount_client $MOUNT || error "mount failed"
21041
21042         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
21043         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
21044         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
21045
21046         #set the stripe to be unknown hash type
21047         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
21048         $LCTL set_param fail_loc=0x1901
21049         for ((i = 0; i < 10; i++)); do
21050                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
21051                         error "stat f-$i failed"
21052                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
21053         done
21054
21055         touch $DIR/$tdir/striped_dir/f0 &&
21056                 error "create under striped dir with unknown hash should fail"
21057
21058         $LCTL set_param fail_loc=0
21059
21060         umount_client $MOUNT || error "umount failed"
21061         mount_client $MOUNT || error "mount failed"
21062
21063         return 0
21064 }
21065 run_test 300i "client handle unknown hash type striped directory"
21066
21067 test_300j() {
21068         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21069         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21070         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21071                 skip "Need MDS version at least 2.7.55"
21072
21073         local stripe_count
21074         local file
21075
21076         mkdir $DIR/$tdir
21077
21078         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
21079         $LCTL set_param fail_loc=0x1702
21080         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21081                 error "set striped dir error"
21082
21083         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
21084                 error "create files under striped dir failed"
21085
21086         $LCTL set_param fail_loc=0
21087
21088         rm -rf $DIR/$tdir || error "unlink striped dir fails"
21089
21090         return 0
21091 }
21092 run_test 300j "test large update record"
21093
21094 test_300k() {
21095         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21096         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21097         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21098                 skip "Need MDS version at least 2.7.55"
21099
21100         # this test needs a huge transaction
21101         local kb
21102         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21103              osd*.$FSNAME-MDT0000.kbytestotal")
21104         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
21105
21106         local stripe_count
21107         local file
21108
21109         mkdir $DIR/$tdir
21110
21111         #define OBD_FAIL_LARGE_STRIPE   0x1703
21112         $LCTL set_param fail_loc=0x1703
21113         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
21114                 error "set striped dir error"
21115         $LCTL set_param fail_loc=0
21116
21117         $LFS getdirstripe $DIR/$tdir/striped_dir ||
21118                 error "getstripeddir fails"
21119         rm -rf $DIR/$tdir/striped_dir ||
21120                 error "unlink striped dir fails"
21121
21122         return 0
21123 }
21124 run_test 300k "test large striped directory"
21125
21126 test_300l() {
21127         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21128         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21129         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21130                 skip "Need MDS version at least 2.7.55"
21131
21132         local stripe_index
21133
21134         test_mkdir -p $DIR/$tdir/striped_dir
21135         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
21136                         error "chown $RUNAS_ID failed"
21137         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
21138                 error "set default striped dir failed"
21139
21140         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
21141         $LCTL set_param fail_loc=0x80000158
21142         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
21143
21144         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
21145         [ $stripe_index -eq 1 ] ||
21146                 error "expect 1 get $stripe_index for $dir"
21147 }
21148 run_test 300l "non-root user to create dir under striped dir with stale layout"
21149
21150 test_300m() {
21151         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21152         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
21153         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21154                 skip "Need MDS version at least 2.7.55"
21155
21156         mkdir -p $DIR/$tdir/striped_dir
21157         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
21158                 error "set default stripes dir error"
21159
21160         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
21161
21162         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
21163         [ $stripe_count -eq 0 ] ||
21164                         error "expect 0 get $stripe_count for a"
21165
21166         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
21167                 error "set default stripes dir error"
21168
21169         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
21170
21171         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
21172         [ $stripe_count -eq 0 ] ||
21173                         error "expect 0 get $stripe_count for b"
21174
21175         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
21176                 error "set default stripes dir error"
21177
21178         mkdir $DIR/$tdir/striped_dir/c &&
21179                 error "default stripe_index is invalid, mkdir c should fails"
21180
21181         rm -rf $DIR/$tdir || error "rmdir fails"
21182 }
21183 run_test 300m "setstriped directory on single MDT FS"
21184
21185 cleanup_300n() {
21186         local list=$(comma_list $(mdts_nodes))
21187
21188         trap 0
21189         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21190 }
21191
21192 test_300n() {
21193         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21194         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21195         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21196                 skip "Need MDS version at least 2.7.55"
21197         remote_mds_nodsh && skip "remote MDS with nodsh"
21198
21199         local stripe_index
21200         local list=$(comma_list $(mdts_nodes))
21201
21202         trap cleanup_300n RETURN EXIT
21203         mkdir -p $DIR/$tdir
21204         chmod 777 $DIR/$tdir
21205         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
21206                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
21207                 error "create striped dir succeeds with gid=0"
21208
21209         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
21210         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
21211                 error "create striped dir fails with gid=-1"
21212
21213         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21214         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
21215                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
21216                 error "set default striped dir succeeds with gid=0"
21217
21218
21219         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
21220         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
21221                 error "set default striped dir fails with gid=-1"
21222
21223
21224         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21225         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
21226                                         error "create test_dir fails"
21227         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
21228                                         error "create test_dir1 fails"
21229         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
21230                                         error "create test_dir2 fails"
21231         cleanup_300n
21232 }
21233 run_test 300n "non-root user to create dir under striped dir with default EA"
21234
21235 test_300o() {
21236         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21237         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21238         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21239                 skip "Need MDS version at least 2.7.55"
21240
21241         local numfree1
21242         local numfree2
21243
21244         mkdir -p $DIR/$tdir
21245
21246         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
21247         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
21248         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
21249                 skip "not enough free inodes $numfree1 $numfree2"
21250         fi
21251
21252         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
21253         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
21254         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
21255                 skip "not enough free space $numfree1 $numfree2"
21256         fi
21257
21258         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
21259                 error "setdirstripe fails"
21260
21261         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
21262                 error "create dirs fails"
21263
21264         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
21265         ls $DIR/$tdir/striped_dir > /dev/null ||
21266                 error "ls striped dir fails"
21267         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
21268                 error "unlink big striped dir fails"
21269 }
21270 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
21271
21272 test_300p() {
21273         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21274         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21275         remote_mds_nodsh && skip "remote MDS with nodsh"
21276
21277         mkdir -p $DIR/$tdir
21278
21279         #define OBD_FAIL_OUT_ENOSPC     0x1704
21280         do_facet mds2 lctl set_param fail_loc=0x80001704
21281         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
21282                  && error "create striped directory should fail"
21283
21284         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
21285
21286         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
21287         true
21288 }
21289 run_test 300p "create striped directory without space"
21290
21291 test_300q() {
21292         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21293         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21294
21295         local fd=$(free_fd)
21296         local cmd="exec $fd<$tdir"
21297         cd $DIR
21298         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
21299         eval $cmd
21300         cmd="exec $fd<&-"
21301         trap "eval $cmd" EXIT
21302         cd $tdir || error "cd $tdir fails"
21303         rmdir  ../$tdir || error "rmdir $tdir fails"
21304         mkdir local_dir && error "create dir succeeds"
21305         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
21306         eval $cmd
21307         return 0
21308 }
21309 run_test 300q "create remote directory under orphan directory"
21310
21311 test_300r() {
21312         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21313                 skip "Need MDS version at least 2.7.55" && return
21314         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
21315
21316         mkdir $DIR/$tdir
21317
21318         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
21319                 error "set striped dir error"
21320
21321         $LFS getdirstripe $DIR/$tdir/striped_dir ||
21322                 error "getstripeddir fails"
21323
21324         local stripe_count
21325         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
21326                       awk '/lmv_stripe_count:/ { print $2 }')
21327
21328         [ $MDSCOUNT -ne $stripe_count ] &&
21329                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
21330
21331         rm -rf $DIR/$tdir/striped_dir ||
21332                 error "unlink striped dir fails"
21333 }
21334 run_test 300r "test -1 striped directory"
21335
21336 prepare_remote_file() {
21337         mkdir $DIR/$tdir/src_dir ||
21338                 error "create remote source failed"
21339
21340         cp /etc/hosts $DIR/$tdir/src_dir/a ||
21341                  error "cp to remote source failed"
21342         touch $DIR/$tdir/src_dir/a
21343
21344         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
21345                 error "create remote target dir failed"
21346
21347         touch $DIR/$tdir/tgt_dir/b
21348
21349         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
21350                 error "rename dir cross MDT failed!"
21351
21352         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
21353                 error "src_child still exists after rename"
21354
21355         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
21356                 error "missing file(a) after rename"
21357
21358         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
21359                 error "diff after rename"
21360 }
21361
21362 test_310a() {
21363         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
21364         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21365
21366         local remote_file=$DIR/$tdir/tgt_dir/b
21367
21368         mkdir -p $DIR/$tdir
21369
21370         prepare_remote_file || error "prepare remote file failed"
21371
21372         #open-unlink file
21373         $OPENUNLINK $remote_file $remote_file ||
21374                 error "openunlink $remote_file failed"
21375         $CHECKSTAT -a $remote_file || error "$remote_file exists"
21376 }
21377 run_test 310a "open unlink remote file"
21378
21379 test_310b() {
21380         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
21381         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21382
21383         local remote_file=$DIR/$tdir/tgt_dir/b
21384
21385         mkdir -p $DIR/$tdir
21386
21387         prepare_remote_file || error "prepare remote file failed"
21388
21389         ln $remote_file $DIR/$tfile || error "link failed for remote file"
21390         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
21391         $CHECKSTAT -t file $remote_file || error "check file failed"
21392 }
21393 run_test 310b "unlink remote file with multiple links while open"
21394
21395 test_310c() {
21396         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21397         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
21398
21399         local remote_file=$DIR/$tdir/tgt_dir/b
21400
21401         mkdir -p $DIR/$tdir
21402
21403         prepare_remote_file || error "prepare remote file failed"
21404
21405         ln $remote_file $DIR/$tfile || error "link failed for remote file"
21406         multiop_bg_pause $remote_file O_uc ||
21407                         error "mulitop failed for remote file"
21408         MULTIPID=$!
21409         $MULTIOP $DIR/$tfile Ouc
21410         kill -USR1 $MULTIPID
21411         wait $MULTIPID
21412 }
21413 run_test 310c "open-unlink remote file with multiple links"
21414
21415 #LU-4825
21416 test_311() {
21417         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21418         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
21419         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
21420                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
21421         remote_mds_nodsh && skip "remote MDS with nodsh"
21422
21423         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
21424         local mdts=$(comma_list $(mdts_nodes))
21425
21426         mkdir -p $DIR/$tdir
21427         $LFS setstripe -i 0 -c 1 $DIR/$tdir
21428         createmany -o $DIR/$tdir/$tfile. 1000
21429
21430         # statfs data is not real time, let's just calculate it
21431         old_iused=$((old_iused + 1000))
21432
21433         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21434                         osp.*OST0000*MDT0000.create_count")
21435         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21436                                 osp.*OST0000*MDT0000.max_create_count")
21437         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
21438
21439         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
21440         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
21441         [ $index -ne 0 ] || error "$tfile stripe index is 0"
21442
21443         unlinkmany $DIR/$tdir/$tfile. 1000
21444
21445         do_nodes $mdts "$LCTL set_param -n \
21446                         osp.*OST0000*.max_create_count=$max_count"
21447         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
21448                 do_nodes $mdts "$LCTL set_param -n \
21449                                 osp.*OST0000*.create_count=$count"
21450         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
21451                         grep "=0" && error "create_count is zero"
21452
21453         local new_iused
21454         for i in $(seq 120); do
21455                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
21456                 # system may be too busy to destroy all objs in time, use
21457                 # a somewhat small value to not fail autotest
21458                 [ $((old_iused - new_iused)) -gt 400 ] && break
21459                 sleep 1
21460         done
21461
21462         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
21463         [ $((old_iused - new_iused)) -gt 400 ] ||
21464                 error "objs not destroyed after unlink"
21465 }
21466 run_test 311 "disable OSP precreate, and unlink should destroy objs"
21467
21468 zfs_oid_to_objid()
21469 {
21470         local ost=$1
21471         local objid=$2
21472
21473         local vdevdir=$(dirname $(facet_vdevice $ost))
21474         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
21475         local zfs_zapid=$(do_facet $ost $cmd |
21476                           grep -w "/O/0/d$((objid%32))" -C 5 |
21477                           awk '/Object/{getline; print $1}')
21478         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
21479                           awk "/$objid = /"'{printf $3}')
21480
21481         echo $zfs_objid
21482 }
21483
21484 zfs_object_blksz() {
21485         local ost=$1
21486         local objid=$2
21487
21488         local vdevdir=$(dirname $(facet_vdevice $ost))
21489         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
21490         local blksz=$(do_facet $ost $cmd $objid |
21491                       awk '/dblk/{getline; printf $4}')
21492
21493         case "${blksz: -1}" in
21494                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
21495                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
21496                 *) ;;
21497         esac
21498
21499         echo $blksz
21500 }
21501
21502 test_312() { # LU-4856
21503         remote_ost_nodsh && skip "remote OST with nodsh"
21504         [ "$ost1_FSTYPE" = "zfs" ] ||
21505                 skip_env "the test only applies to zfs"
21506
21507         local max_blksz=$(do_facet ost1 \
21508                           $ZFS get -p recordsize $(facet_device ost1) |
21509                           awk '!/VALUE/{print $3}')
21510
21511         # to make life a little bit easier
21512         $LFS mkdir -c 1 -i 0 $DIR/$tdir
21513         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21514
21515         local tf=$DIR/$tdir/$tfile
21516         touch $tf
21517         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
21518
21519         # Get ZFS object id
21520         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
21521         # block size change by sequential overwrite
21522         local bs
21523
21524         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
21525                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
21526
21527                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
21528                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
21529         done
21530         rm -f $tf
21531
21532         # block size change by sequential append write
21533         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
21534         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
21535         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
21536         local count
21537
21538         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
21539                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
21540                         oflag=sync conv=notrunc
21541
21542                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
21543                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
21544                         error "blksz error, actual $blksz, " \
21545                                 "expected: 2 * $count * $PAGE_SIZE"
21546         done
21547         rm -f $tf
21548
21549         # random write
21550         touch $tf
21551         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
21552         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
21553
21554         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
21555         blksz=$(zfs_object_blksz ost1 $zfs_objid)
21556         [ $blksz -eq $PAGE_SIZE ] ||
21557                 error "blksz error: $blksz, expected: $PAGE_SIZE"
21558
21559         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
21560         blksz=$(zfs_object_blksz ost1 $zfs_objid)
21561         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
21562
21563         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
21564         blksz=$(zfs_object_blksz ost1 $zfs_objid)
21565         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
21566 }
21567 run_test 312 "make sure ZFS adjusts its block size by write pattern"
21568
21569 test_313() {
21570         remote_ost_nodsh && skip "remote OST with nodsh"
21571
21572         local file=$DIR/$tfile
21573
21574         rm -f $file
21575         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
21576
21577         # define OBD_FAIL_TGT_RCVD_EIO           0x720
21578         do_facet ost1 "$LCTL set_param fail_loc=0x720"
21579         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
21580                 error "write should failed"
21581         do_facet ost1 "$LCTL set_param fail_loc=0"
21582         rm -f $file
21583 }
21584 run_test 313 "io should fail after last_rcvd update fail"
21585
21586 test_314() {
21587         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
21588
21589         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
21590         do_facet ost1 "$LCTL set_param fail_loc=0x720"
21591         rm -f $DIR/$tfile
21592         wait_delete_completed
21593         do_facet ost1 "$LCTL set_param fail_loc=0"
21594 }
21595 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
21596
21597 test_315() { # LU-618
21598         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
21599
21600         local file=$DIR/$tfile
21601         rm -f $file
21602
21603         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
21604                 error "multiop file write failed"
21605         $MULTIOP $file oO_RDONLY:r4063232_c &
21606         PID=$!
21607
21608         sleep 2
21609
21610         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
21611         kill -USR1 $PID
21612
21613         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
21614         rm -f $file
21615 }
21616 run_test 315 "read should be accounted"
21617
21618 test_316() {
21619         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21620         large_xattr_enabled || skip_env "ea_inode feature disabled"
21621
21622         rm -rf $DIR/$tdir/d
21623         mkdir -p $DIR/$tdir/d
21624         chown nobody $DIR/$tdir/d
21625         touch $DIR/$tdir/d/file
21626
21627         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
21628 }
21629 run_test 316 "lfs mv"
21630
21631 test_317() {
21632         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
21633                 skip "Need MDS version at least 2.11.53"
21634         if [ "$ost1_FSTYPE" == "zfs" ]; then
21635                 skip "LU-10370: no implementation for ZFS"
21636         fi
21637
21638         local trunc_sz
21639         local grant_blk_size
21640
21641         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
21642                         awk '/grant_block_size:/ { print $2; exit; }')
21643         #
21644         # Create File of size 5M. Truncate it to below size's and verify
21645         # blocks count.
21646         #
21647         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
21648                 error "Create file $DIR/$tfile failed"
21649         stack_trap "rm -f $DIR/$tfile" EXIT
21650
21651         for trunc_sz in 2097152 4097 4000 509 0; do
21652                 $TRUNCATE $DIR/$tfile $trunc_sz ||
21653                         error "truncate $tfile to $trunc_sz failed"
21654                 local sz=$(stat --format=%s $DIR/$tfile)
21655                 local blk=$(stat --format=%b $DIR/$tfile)
21656                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
21657                                      grant_blk_size) * 8))
21658
21659                 if [[ $blk -ne $trunc_blk ]]; then
21660                         $(which stat) $DIR/$tfile
21661                         error "Expected Block $trunc_blk got $blk for $tfile"
21662                 fi
21663
21664                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
21665                         error "Expected Size $trunc_sz got $sz for $tfile"
21666         done
21667
21668         #
21669         # sparse file test
21670         # Create file with a hole and write actual two blocks. Block count
21671         # must be 16.
21672         #
21673         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
21674                 conv=fsync || error "Create file : $DIR/$tfile"
21675
21676         # Calculate the final truncate size.
21677         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
21678
21679         #
21680         # truncate to size $trunc_sz bytes. Strip the last block
21681         # The block count must drop to 8
21682         #
21683         $TRUNCATE $DIR/$tfile $trunc_sz ||
21684                 error "truncate $tfile to $trunc_sz failed"
21685
21686         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
21687         sz=$(stat --format=%s $DIR/$tfile)
21688         blk=$(stat --format=%b $DIR/$tfile)
21689
21690         if [[ $blk -ne $trunc_bsz ]]; then
21691                 $(which stat) $DIR/$tfile
21692                 error "Expected Block $trunc_bsz got $blk for $tfile"
21693         fi
21694
21695         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
21696                 error "Expected Size $trunc_sz got $sz for $tfile"
21697 }
21698 run_test 317 "Verify blocks get correctly update after truncate"
21699
21700 test_318() {
21701         local old_max_active=$($LCTL get_param -n \
21702                             llite.*.max_read_ahead_async_active 2>/dev/null)
21703
21704         $LCTL set_param llite.*.max_read_ahead_async_active=256
21705         local max_active=$($LCTL get_param -n \
21706                            llite.*.max_read_ahead_async_active 2>/dev/null)
21707         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
21708
21709         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
21710                 error "set max_read_ahead_async_active should succeed"
21711
21712         $LCTL set_param llite.*.max_read_ahead_async_active=512
21713         max_active=$($LCTL get_param -n \
21714                      llite.*.max_read_ahead_async_active 2>/dev/null)
21715         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
21716
21717         # restore @max_active
21718         [ $old_max_active -ne 0 ] && $LCTL set_param \
21719                 llite.*.max_read_ahead_async_active=$old_max_active
21720
21721         local old_threshold=$($LCTL get_param -n \
21722                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
21723         local max_per_file_mb=$($LCTL get_param -n \
21724                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
21725
21726         local invalid=$(($max_per_file_mb + 1))
21727         $LCTL set_param \
21728                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
21729                         && error "set $invalid should fail"
21730
21731         local valid=$(($invalid - 1))
21732         $LCTL set_param \
21733                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
21734                         error "set $valid should succeed"
21735         local threshold=$($LCTL get_param -n \
21736                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
21737         [ $threshold -eq $valid ] || error \
21738                 "expect threshold $valid got $threshold"
21739         $LCTL set_param \
21740                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
21741 }
21742 run_test 318 "Verify async readahead tunables"
21743
21744 test_319() {
21745         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
21746
21747         local before=$(date +%s)
21748         local evict
21749         local mdir=$DIR/$tdir
21750         local file=$mdir/xxx
21751
21752         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
21753         touch $file
21754
21755 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
21756         $LCTL set_param fail_val=5 fail_loc=0x8000032c
21757         $LFS mv -m1 $file &
21758
21759         sleep 1
21760         dd if=$file of=/dev/null
21761         wait
21762         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
21763           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
21764
21765         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
21766 }
21767 run_test 319 "lost lease lock on migrate error"
21768
21769 test_398a() { # LU-4198
21770         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21771         $LCTL set_param ldlm.namespaces.*.lru_size=clear
21772
21773         # request a new lock on client
21774         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
21775
21776         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
21777         local lock_count=$($LCTL get_param -n \
21778                            ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
21779         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
21780
21781         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
21782
21783         # no lock cached, should use lockless IO and not enqueue new lock
21784         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
21785         lock_count=$($LCTL get_param -n \
21786                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
21787         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
21788 }
21789 run_test 398a "direct IO should cancel lock otherwise lockless"
21790
21791 test_398b() { # LU-4198
21792         which fio || skip_env "no fio installed"
21793         $LFS setstripe -c -1 $DIR/$tfile
21794
21795         local size=12
21796         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
21797
21798         local njobs=4
21799         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
21800         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
21801                 --numjobs=$njobs --fallocate=none \
21802                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
21803                 --filename=$DIR/$tfile &
21804         bg_pid=$!
21805
21806         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
21807         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
21808                 --numjobs=$njobs --fallocate=none \
21809                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
21810                 --filename=$DIR/$tfile || true
21811         wait $bg_pid
21812
21813         rm -rf $DIR/$tfile
21814 }
21815 run_test 398b "DIO and buffer IO race"
21816
21817 test_398c() { # LU-4198
21818         which fio || skip_env "no fio installed"
21819
21820         saved_debug=$($LCTL get_param -n debug)
21821         $LCTL set_param debug=0
21822
21823         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
21824         ((size /= 1024)) # by megabytes
21825         ((size /= 2)) # write half of the OST at most
21826         [ $size -gt 40 ] && size=40 #reduce test time anyway
21827
21828         $LFS setstripe -c 1 $DIR/$tfile
21829
21830         # it seems like ldiskfs reserves more space than necessary if the
21831         # writing blocks are not mapped, so it extends the file firstly
21832         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
21833         cancel_lru_locks osc
21834
21835         # clear and verify rpc_stats later
21836         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
21837
21838         local njobs=4
21839         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
21840         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
21841                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
21842                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
21843                 --filename=$DIR/$tfile
21844         [ $? -eq 0 ] || error "fio write error"
21845
21846         [ $($LCTL get_param -n \
21847          ldlm.namespaces.${FSNAME}-OST0000-osc-ffff*.lock_count) -eq 0 ] ||
21848                 error "Locks were requested while doing AIO"
21849
21850         # get the percentage of 1-page I/O
21851         pct=$($LCTL get_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats |
21852                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
21853                 awk '{print $7}')
21854         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
21855
21856         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
21857         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
21858                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
21859                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
21860                 --filename=$DIR/$tfile
21861         [ $? -eq 0 ] || error "fio mixed read write error"
21862
21863         echo "AIO with large block size ${size}M"
21864         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
21865                 --numjobs=1 --fallocate=none --ioengine=libaio \
21866                 --iodepth=16 --allow_file_create=0 --size=${size}M \
21867                 --filename=$DIR/$tfile
21868         [ $? -eq 0 ] || error "fio large block size failed"
21869
21870         rm -rf $DIR/$tfile
21871         $LCTL set_param debug="$saved_debug"
21872 }
21873 run_test 398c "run fio to test AIO"
21874
21875 test_fake_rw() {
21876         local read_write=$1
21877         if [ "$read_write" = "write" ]; then
21878                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
21879         elif [ "$read_write" = "read" ]; then
21880                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
21881         else
21882                 error "argument error"
21883         fi
21884
21885         # turn off debug for performance testing
21886         local saved_debug=$($LCTL get_param -n debug)
21887         $LCTL set_param debug=0
21888
21889         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21890
21891         # get ost1 size - $FSNAME-OST0000
21892         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
21893         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
21894         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
21895
21896         if [ "$read_write" = "read" ]; then
21897                 truncate -s $(expr 1048576 \* $blocks) $DIR/$tfile
21898         fi
21899
21900         local start_time=$(date +%s.%N)
21901         $dd_cmd bs=1M count=$blocks oflag=sync ||
21902                 error "real dd $read_write error"
21903         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
21904
21905         if [ "$read_write" = "write" ]; then
21906                 rm -f $DIR/$tfile
21907         fi
21908
21909         # define OBD_FAIL_OST_FAKE_RW           0x238
21910         do_facet ost1 $LCTL set_param fail_loc=0x238
21911
21912         local start_time=$(date +%s.%N)
21913         $dd_cmd bs=1M count=$blocks oflag=sync ||
21914                 error "fake dd $read_write error"
21915         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
21916
21917         if [ "$read_write" = "write" ]; then
21918                 # verify file size
21919                 cancel_lru_locks osc
21920                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
21921                         error "$tfile size not $blocks MB"
21922         fi
21923         do_facet ost1 $LCTL set_param fail_loc=0
21924
21925         echo "fake $read_write $duration_fake vs. normal $read_write" \
21926                 "$duration in seconds"
21927         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
21928                 error_not_in_vm "fake write is slower"
21929
21930         $LCTL set_param -n debug="$saved_debug"
21931         rm -f $DIR/$tfile
21932 }
21933 test_399a() { # LU-7655 for OST fake write
21934         remote_ost_nodsh && skip "remote OST with nodsh"
21935
21936         test_fake_rw write
21937 }
21938 run_test 399a "fake write should not be slower than normal write"
21939
21940 test_399b() { # LU-8726 for OST fake read
21941         remote_ost_nodsh && skip "remote OST with nodsh"
21942         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
21943                 skip_env "ldiskfs only test"
21944         fi
21945
21946         test_fake_rw read
21947 }
21948 run_test 399b "fake read should not be slower than normal read"
21949
21950 test_400a() { # LU-1606, was conf-sanity test_74
21951         if ! which $CC > /dev/null 2>&1; then
21952                 skip_env "$CC is not installed"
21953         fi
21954
21955         local extra_flags=''
21956         local out=$TMP/$tfile
21957         local prefix=/usr/include/lustre
21958         local prog
21959
21960         # Oleg removes c files in his test rig so test if any c files exist
21961         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
21962                 skip_env "Needed c test files are missing"
21963
21964         if ! [[ -d $prefix ]]; then
21965                 # Assume we're running in tree and fixup the include path.
21966                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
21967                 extra_flags+=" -L$LUSTRE/utils/.lib"
21968         fi
21969
21970         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
21971                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
21972                         error "client api broken"
21973         done
21974         rm -f $out
21975 }
21976 run_test 400a "Lustre client api program can compile and link"
21977
21978 test_400b() { # LU-1606, LU-5011
21979         local header
21980         local out=$TMP/$tfile
21981         local prefix=/usr/include/linux/lustre
21982
21983         # We use a hard coded prefix so that this test will not fail
21984         # when run in tree. There are headers in lustre/include/lustre/
21985         # that are not packaged (like lustre_idl.h) and have more
21986         # complicated include dependencies (like config.h and lnet/types.h).
21987         # Since this test about correct packaging we just skip them when
21988         # they don't exist (see below) rather than try to fixup cppflags.
21989
21990         if ! which $CC > /dev/null 2>&1; then
21991                 skip_env "$CC is not installed"
21992         fi
21993
21994         for header in $prefix/*.h; do
21995                 if ! [[ -f "$header" ]]; then
21996                         continue
21997                 fi
21998
21999                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
22000                         continue # lustre_ioctl.h is internal header
22001                 fi
22002
22003                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
22004                         error "cannot compile '$header'"
22005         done
22006         rm -f $out
22007 }
22008 run_test 400b "packaged headers can be compiled"
22009
22010 test_401a() { #LU-7437
22011         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
22012         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
22013
22014         #count the number of parameters by "list_param -R"
22015         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
22016         #count the number of parameters by listing proc files
22017         local proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
22018         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
22019         echo "proc_dirs='$proc_dirs'"
22020         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
22021         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
22022                       sort -u | wc -l)
22023
22024         [ $params -eq $procs ] ||
22025                 error "found $params parameters vs. $procs proc files"
22026
22027         # test the list_param -D option only returns directories
22028         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
22029         #count the number of parameters by listing proc directories
22030         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
22031                 sort -u | wc -l)
22032
22033         [ $params -eq $procs ] ||
22034                 error "found $params parameters vs. $procs proc files"
22035 }
22036 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
22037
22038 test_401b() {
22039         local save=$($LCTL get_param -n jobid_var)
22040         local tmp=testing
22041
22042         $LCTL set_param foo=bar jobid_var=$tmp bar=baz &&
22043                 error "no error returned when setting bad parameters"
22044
22045         local jobid_new=$($LCTL get_param -n foe jobid_var baz)
22046         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
22047
22048         $LCTL set_param -n fog=bam jobid_var=$save bat=fog
22049         local jobid_old=$($LCTL get_param -n foe jobid_var bag)
22050         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
22051 }
22052 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
22053
22054 test_401c() {
22055         local jobid_var_old=$($LCTL get_param -n jobid_var)
22056         local jobid_var_new
22057
22058         $LCTL set_param jobid_var= &&
22059                 error "no error returned for 'set_param a='"
22060
22061         jobid_var_new=$($LCTL get_param -n jobid_var)
22062         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
22063                 error "jobid_var was changed by setting without value"
22064
22065         $LCTL set_param jobid_var &&
22066                 error "no error returned for 'set_param a'"
22067
22068         jobid_var_new=$($LCTL get_param -n jobid_var)
22069         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
22070                 error "jobid_var was changed by setting without value"
22071 }
22072 run_test 401c "Verify 'lctl set_param' without value fails in either format."
22073
22074 test_401d() {
22075         local jobid_var_old=$($LCTL get_param -n jobid_var)
22076         local jobid_var_new
22077         local new_value="foo=bar"
22078
22079         $LCTL set_param jobid_var=$new_value ||
22080                 error "'set_param a=b' did not accept a value containing '='"
22081
22082         jobid_var_new=$($LCTL get_param -n jobid_var)
22083         [[ "$jobid_var_new" == "$new_value" ]] ||
22084                 error "'set_param a=b' failed on a value containing '='"
22085
22086         # Reset the jobid_var to test the other format
22087         $LCTL set_param jobid_var=$jobid_var_old
22088         jobid_var_new=$($LCTL get_param -n jobid_var)
22089         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
22090                 error "failed to reset jobid_var"
22091
22092         $LCTL set_param jobid_var $new_value ||
22093                 error "'set_param a b' did not accept a value containing '='"
22094
22095         jobid_var_new=$($LCTL get_param -n jobid_var)
22096         [[ "$jobid_var_new" == "$new_value" ]] ||
22097                 error "'set_param a b' failed on a value containing '='"
22098
22099         $LCTL set_param jobid_var $jobid_var_old
22100         jobid_var_new=$($LCTL get_param -n jobid_var)
22101         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
22102                 error "failed to reset jobid_var"
22103 }
22104 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
22105
22106 test_402() {
22107         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
22108         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
22109                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
22110         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
22111                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
22112                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
22113         remote_mds_nodsh && skip "remote MDS with nodsh"
22114
22115         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
22116 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
22117         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
22118         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
22119                 echo "Touch failed - OK"
22120 }
22121 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
22122
22123 test_403() {
22124         local file1=$DIR/$tfile.1
22125         local file2=$DIR/$tfile.2
22126         local tfile=$TMP/$tfile
22127
22128         rm -f $file1 $file2 $tfile
22129
22130         touch $file1
22131         ln $file1 $file2
22132
22133         # 30 sec OBD_TIMEOUT in ll_getattr()
22134         # right before populating st_nlink
22135         $LCTL set_param fail_loc=0x80001409
22136         stat -c %h $file1 > $tfile &
22137
22138         # create an alias, drop all locks and reclaim the dentry
22139         < $file2
22140         cancel_lru_locks mdc
22141         cancel_lru_locks osc
22142         sysctl -w vm.drop_caches=2
22143
22144         wait
22145
22146         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
22147
22148         rm -f $tfile $file1 $file2
22149 }
22150 run_test 403 "i_nlink should not drop to zero due to aliasing"
22151
22152 test_404() { # LU-6601
22153         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
22154                 skip "Need server version newer than 2.8.52"
22155         remote_mds_nodsh && skip "remote MDS with nodsh"
22156
22157         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
22158                 awk '/osp .*-osc-MDT/ { print $4}')
22159
22160         local osp
22161         for osp in $mosps; do
22162                 echo "Deactivate: " $osp
22163                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
22164                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
22165                         awk -vp=$osp '$4 == p { print $2 }')
22166                 [ $stat = IN ] || {
22167                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
22168                         error "deactivate error"
22169                 }
22170                 echo "Activate: " $osp
22171                 do_facet $SINGLEMDS $LCTL --device %$osp activate
22172                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
22173                         awk -vp=$osp '$4 == p { print $2 }')
22174                 [ $stat = UP ] || {
22175                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
22176                         error "activate error"
22177                 }
22178         done
22179 }
22180 run_test 404 "validate manual {de}activated works properly for OSPs"
22181
22182 test_405() {
22183         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
22184         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
22185                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
22186                         skip "Layout swap lock is not supported"
22187
22188         check_swap_layouts_support
22189
22190         test_mkdir $DIR/$tdir
22191         swap_lock_test -d $DIR/$tdir ||
22192                 error "One layout swap locked test failed"
22193 }
22194 run_test 405 "Various layout swap lock tests"
22195
22196 test_406() {
22197         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22198         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
22199         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
22200         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22201         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
22202                 skip "Need MDS version at least 2.8.50"
22203
22204         local def_stripe_size=$($LFS getstripe -S $MOUNT)
22205         local test_pool=$TESTNAME
22206
22207         pool_add $test_pool || error "pool_add failed"
22208         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
22209                 error "pool_add_targets failed"
22210
22211         save_layout_restore_at_exit $MOUNT
22212
22213         # parent set default stripe count only, child will stripe from both
22214         # parent and fs default
22215         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
22216                 error "setstripe $MOUNT failed"
22217         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
22218         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
22219         for i in $(seq 10); do
22220                 local f=$DIR/$tdir/$tfile.$i
22221                 touch $f || error "touch failed"
22222                 local count=$($LFS getstripe -c $f)
22223                 [ $count -eq $OSTCOUNT ] ||
22224                         error "$f stripe count $count != $OSTCOUNT"
22225                 local offset=$($LFS getstripe -i $f)
22226                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
22227                 local size=$($LFS getstripe -S $f)
22228                 [ $size -eq $((def_stripe_size * 2)) ] ||
22229                         error "$f stripe size $size != $((def_stripe_size * 2))"
22230                 local pool=$($LFS getstripe -p $f)
22231                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
22232         done
22233
22234         # change fs default striping, delete parent default striping, now child
22235         # will stripe from new fs default striping only
22236         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
22237                 error "change $MOUNT default stripe failed"
22238         $LFS setstripe -c 0 $DIR/$tdir ||
22239                 error "delete $tdir default stripe failed"
22240         for i in $(seq 11 20); do
22241                 local f=$DIR/$tdir/$tfile.$i
22242                 touch $f || error "touch $f failed"
22243                 local count=$($LFS getstripe -c $f)
22244                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
22245                 local offset=$($LFS getstripe -i $f)
22246                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
22247                 local size=$($LFS getstripe -S $f)
22248                 [ $size -eq $def_stripe_size ] ||
22249                         error "$f stripe size $size != $def_stripe_size"
22250                 local pool=$($LFS getstripe -p $f)
22251                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
22252         done
22253
22254         unlinkmany $DIR/$tdir/$tfile. 1 20
22255
22256         local f=$DIR/$tdir/$tfile
22257         pool_remove_all_targets $test_pool $f
22258         pool_remove $test_pool $f
22259 }
22260 run_test 406 "DNE support fs default striping"
22261
22262 test_407() {
22263         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22264         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
22265                 skip "Need MDS version at least 2.8.55"
22266         remote_mds_nodsh && skip "remote MDS with nodsh"
22267
22268         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
22269                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
22270         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
22271                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
22272         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
22273
22274         #define OBD_FAIL_DT_TXN_STOP    0x2019
22275         for idx in $(seq $MDSCOUNT); do
22276                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
22277         done
22278         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
22279         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
22280                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
22281         true
22282 }
22283 run_test 407 "transaction fail should cause operation fail"
22284
22285 test_408() {
22286         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
22287
22288         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
22289         lctl set_param fail_loc=0x8000040a
22290         # let ll_prepare_partial_page() fail
22291         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
22292
22293         rm -f $DIR/$tfile
22294
22295         # create at least 100 unused inodes so that
22296         # shrink_icache_memory(0) should not return 0
22297         touch $DIR/$tfile-{0..100}
22298         rm -f $DIR/$tfile-{0..100}
22299         sync
22300
22301         echo 2 > /proc/sys/vm/drop_caches
22302 }
22303 run_test 408 "drop_caches should not hang due to page leaks"
22304
22305 test_409()
22306 {
22307         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22308
22309         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
22310         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
22311         touch $DIR/$tdir/guard || error "(2) Fail to create"
22312
22313         local PREFIX=$(str_repeat 'A' 128)
22314         echo "Create 1K hard links start at $(date)"
22315         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
22316                 error "(3) Fail to hard link"
22317
22318         echo "Links count should be right although linkEA overflow"
22319         stat $DIR/$tdir/guard || error "(4) Fail to stat"
22320         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
22321         [ $linkcount -eq 1001 ] ||
22322                 error "(5) Unexpected hard links count: $linkcount"
22323
22324         echo "List all links start at $(date)"
22325         ls -l $DIR/$tdir/foo > /dev/null ||
22326                 error "(6) Fail to list $DIR/$tdir/foo"
22327
22328         echo "Unlink hard links start at $(date)"
22329         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
22330                 error "(7) Fail to unlink"
22331         echo "Unlink hard links finished at $(date)"
22332 }
22333 run_test 409 "Large amount of cross-MDTs hard links on the same file"
22334
22335 test_410()
22336 {
22337         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
22338                 skip "Need client version at least 2.9.59"
22339
22340         # Create a file, and stat it from the kernel
22341         local testfile=$DIR/$tfile
22342         touch $testfile
22343
22344         local run_id=$RANDOM
22345         local my_ino=$(stat --format "%i" $testfile)
22346
22347         # Try to insert the module. This will always fail as the
22348         # module is designed to not be inserted.
22349         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
22350             &> /dev/null
22351
22352         # Anything but success is a test failure
22353         dmesg | grep -q \
22354             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
22355             error "no inode match"
22356 }
22357 run_test 410 "Test inode number returned from kernel thread"
22358
22359 cleanup_test411_cgroup() {
22360         trap 0
22361         rmdir "$1"
22362 }
22363
22364 test_411() {
22365         local cg_basedir=/sys/fs/cgroup/memory
22366         # LU-9966
22367         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
22368                 skip "no setup for cgroup"
22369
22370         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
22371                 error "test file creation failed"
22372         cancel_lru_locks osc
22373
22374         # Create a very small memory cgroup to force a slab allocation error
22375         local cgdir=$cg_basedir/osc_slab_alloc
22376         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
22377         trap "cleanup_test411_cgroup $cgdir" EXIT
22378         echo 2M > $cgdir/memory.kmem.limit_in_bytes
22379         echo 1M > $cgdir/memory.limit_in_bytes
22380
22381         # Should not LBUG, just be killed by oom-killer
22382         # dd will return 0 even allocation failure in some environment.
22383         # So don't check return value
22384         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
22385         cleanup_test411_cgroup $cgdir
22386
22387         return 0
22388 }
22389 run_test 411 "Slab allocation error with cgroup does not LBUG"
22390
22391 test_412() {
22392         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22393         if [ $MDS1_VERSION -lt $(version_code 2.10.55) ]; then
22394                 skip "Need server version at least 2.10.55"
22395         fi
22396
22397         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
22398                 error "mkdir failed"
22399         $LFS getdirstripe $DIR/$tdir
22400         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
22401         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
22402                 error "expect $((MDSCOUT - 1)) get $stripe_index"
22403         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
22404         [ $stripe_count -eq 2 ] ||
22405                 error "expect 2 get $stripe_count"
22406 }
22407 run_test 412 "mkdir on specific MDTs"
22408
22409 test_qos_mkdir() {
22410         local mkdir_cmd=$1
22411         local stripe_count=$2
22412         local mdts=$(comma_list $(mdts_nodes))
22413
22414         local testdir
22415         local lmv_qos_prio_free
22416         local lmv_qos_threshold_rr
22417         local lmv_qos_maxage
22418         local lod_qos_prio_free
22419         local lod_qos_threshold_rr
22420         local lod_qos_maxage
22421         local count
22422         local i
22423
22424         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
22425         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
22426         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
22427                 head -n1)
22428         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
22429         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
22430         stack_trap "$LCTL set_param \
22431                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null" EXIT
22432         stack_trap "$LCTL set_param \
22433                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
22434         stack_trap "$LCTL set_param \
22435                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" EXIT
22436
22437         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
22438                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
22439         lod_qos_prio_free=${lod_qos_prio_free%%%}
22440         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
22441                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
22442         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
22443         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
22444                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
22445         stack_trap "do_nodes $mdts $LCTL set_param \
22446                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null" EXIT
22447         stack_trap "do_nodes $mdts $LCTL set_param \
22448                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null" \
22449                 EXIT
22450         stack_trap "do_nodes $mdts $LCTL set_param \
22451                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" EXIT
22452
22453         echo
22454         echo "Mkdir (stripe_count $stripe_count) roundrobin:"
22455
22456         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
22457         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
22458
22459         testdir=$DIR/$tdir-s$stripe_count/rr
22460
22461         for i in $(seq $((100 * MDSCOUNT))); do
22462                 eval $mkdir_cmd $testdir/subdir$i ||
22463                         error "$mkdir_cmd subdir$i failed"
22464         done
22465
22466         for i in $(seq $MDSCOUNT); do
22467                 count=$($LFS getdirstripe -i $testdir/* |
22468                                 grep ^$((i - 1))$ | wc -l)
22469                 echo "$count directories created on MDT$((i - 1))"
22470                 [ $count -eq 100 ] || error "subdirs are not evenly distributed"
22471
22472                 if [ $stripe_count -gt 1 ]; then
22473                         count=$($LFS getdirstripe $testdir/* |
22474                                 grep -P "^\s+$((i - 1))\t" | wc -l)
22475                         echo "$count stripes created on MDT$((i - 1))"
22476                         # deviation should < 5% of average
22477                         [ $count -lt $((95 * stripe_count)) ] ||
22478                         [ $count -gt $((105 * stripe_count)) ] &&
22479                                 error "stripes are not evenly distributed"
22480                 fi
22481         done
22482
22483         $LCTL set_param lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null
22484         do_nodes $mdts $LCTL set_param \
22485                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null
22486
22487         echo
22488         echo "Check for uneven MDTs: "
22489
22490         local ffree
22491         local bavail
22492         local max
22493         local min
22494         local max_index
22495         local min_index
22496         local tmp
22497
22498         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
22499         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
22500         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
22501
22502         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
22503         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
22504         max_index=0
22505         min_index=0
22506         for ((i = 1; i < ${#ffree[@]}; i++)); do
22507                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
22508                 if [ $tmp -gt $max ]; then
22509                         max=$tmp
22510                         max_index=$i
22511                 fi
22512                 if [ $tmp -lt $min ]; then
22513                         min=$tmp
22514                         min_index=$i
22515                 fi
22516         done
22517
22518         [ ${ffree[min_index]} -eq 0 ] &&
22519                 skip "no free files in MDT$min_index"
22520         [ ${ffree[min_index]} -gt 100000000 ] &&
22521                 skip "too much free files in MDT$min_index"
22522
22523         # Check if we need to generate uneven MDTs
22524         local threshold=50
22525         local diff=$(((max - min) * 100 / min))
22526         local value="$(generate_string 1024)"
22527
22528         while [ $diff -lt $threshold ]; do
22529                 # generate uneven MDTs, create till $threshold% diff
22530                 echo -n "weight diff=$diff% must be > $threshold% ..."
22531                 count=$((${ffree[min_index]} / 10))
22532                 # 50 sec per 10000 files in vm
22533                 [ $count -gt 40000 ] && [ "$SLOW" = "no" ] &&
22534                         skip "$count files to create"
22535                 echo "Fill MDT$min_index with $count files"
22536                 [ -d $DIR/$tdir-MDT$min_index ] ||
22537                         $LFS mkdir -i $min_index $DIR/$tdir-MDT$min_index ||
22538                         error "mkdir $tdir-MDT$min_index failed"
22539                 for i in $(seq $count); do
22540                         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE \
22541                                 $DIR/$tdir-MDT$min_index/f$j_$i > /dev/null ||
22542                                 error "create f$j_$i failed"
22543                         setfattr -n user.413b -v $value \
22544                                 $DIR/$tdir-MDT$min_index/f$j_$i ||
22545                                 error "setfattr f$j_$i failed"
22546                 done
22547
22548                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
22549                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
22550                 max=$(((${ffree[max_index]} >> 8) * \
22551                         (${bavail[max_index]} * bsize >> 16)))
22552                 min=$(((${ffree[min_index]} >> 8) * \
22553                         (${bavail[min_index]} * bsize >> 16)))
22554                 diff=$(((max - min) * 100 / min))
22555         done
22556
22557         echo "MDT filesfree available: ${ffree[@]}"
22558         echo "MDT blocks available: ${bavail[@]}"
22559         echo "weight diff=$diff%"
22560
22561         echo
22562         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
22563
22564         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
22565         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
22566         # decrease statfs age, so that it can be updated in time
22567         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
22568         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
22569
22570         sleep 1
22571
22572         testdir=$DIR/$tdir-s$stripe_count/qos
22573
22574         for i in $(seq $((100 * MDSCOUNT))); do
22575                 eval $mkdir_cmd $testdir/subdir$i ||
22576                         error "$mkdir_cmd subdir$i failed"
22577         done
22578
22579         for i in $(seq $MDSCOUNT); do
22580                 count=$($LFS getdirstripe -i $testdir/* | grep ^$((i - 1))$ |
22581                         wc -l)
22582                 echo "$count directories created on MDT$((i - 1))"
22583
22584                 if [ $stripe_count -gt 1 ]; then
22585                         count=$($LFS getdirstripe $testdir/* |
22586                                 grep -P "^\s+$((i - 1))\t" | wc -l)
22587                         echo "$count stripes created on MDT$((i - 1))"
22588                 fi
22589         done
22590
22591         max=$($LFS getdirstripe -i $testdir/* | grep ^$max_index$ | wc -l)
22592         min=$($LFS getdirstripe -i $testdir/* | grep ^$min_index$ | wc -l)
22593
22594         # D-value should > 10% of averge
22595         [ $((max - min)) -lt 10 ] &&
22596                 error "subdirs shouldn't be evenly distributed"
22597
22598         # ditto
22599         if [ $stripe_count -gt 1 ]; then
22600                 max=$($LFS getdirstripe $testdir/* |
22601                         grep -P "^\s+$max_index\t" | wc -l)
22602                 min=$($LFS getdirstripe $testdir/* |
22603                         grep -P "^\s+$min_index\t" | wc -l)
22604                 [ $((max - min)) -le $((10 * stripe_count)) ] &&
22605                         error "stripes shouldn't be evenly distributed"|| true
22606         fi
22607 }
22608
22609 test_413a() {
22610         [ $MDSCOUNT -lt 2 ] &&
22611                 skip "We need at least 2 MDTs for this test"
22612
22613         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
22614                 skip "Need server version at least 2.12.52"
22615
22616         local stripe_count
22617
22618         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
22619                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
22620                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
22621                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
22622                 test_qos_mkdir "$LFS mkdir -c $stripe_count" $stripe_count
22623         done
22624 }
22625 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
22626
22627 test_413b() {
22628         [ $MDSCOUNT -lt 2 ] &&
22629                 skip "We need at least 2 MDTs for this test"
22630
22631         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
22632                 skip "Need server version at least 2.12.52"
22633
22634         local stripe_count
22635
22636         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
22637                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
22638                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
22639                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
22640                 $LFS setdirstripe -D -c $stripe_count \
22641                         $DIR/$tdir-s$stripe_count/rr ||
22642                         error "setdirstripe failed"
22643                 $LFS setdirstripe -D -c $stripe_count \
22644                         $DIR/$tdir-s$stripe_count/qos ||
22645                         error "setdirstripe failed"
22646                 test_qos_mkdir "mkdir" $stripe_count
22647         done
22648 }
22649 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
22650
22651 test_414() {
22652 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
22653         $LCTL set_param fail_loc=0x80000521
22654         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
22655         rm -f $DIR/$tfile
22656 }
22657 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
22658
22659 test_415() {
22660         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22661         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22662                 skip "Need server version at least 2.11.52"
22663
22664         # LU-11102
22665         local total
22666         local setattr_pid
22667         local start_time
22668         local end_time
22669         local duration
22670
22671         total=500
22672         # this test may be slow on ZFS
22673         [ "$mds1_FSTYPE" == "zfs" ] && total=100
22674
22675         # though this test is designed for striped directory, let's test normal
22676         # directory too since lock is always saved as CoS lock.
22677         test_mkdir $DIR/$tdir || error "mkdir $tdir"
22678         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
22679
22680         (
22681                 while true; do
22682                         touch $DIR/$tdir
22683                 done
22684         ) &
22685         setattr_pid=$!
22686
22687         start_time=$(date +%s)
22688         for i in $(seq $total); do
22689                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
22690                         > /dev/null
22691         done
22692         end_time=$(date +%s)
22693         duration=$((end_time - start_time))
22694
22695         kill -9 $setattr_pid
22696
22697         echo "rename $total files took $duration sec"
22698         [ $duration -lt 100 ] || error "rename took $duration sec"
22699 }
22700 run_test 415 "lock revoke is not missing"
22701
22702 test_416() {
22703         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
22704                 skip "Need server version at least 2.11.55"
22705
22706         # define OBD_FAIL_OSD_TXN_START    0x19a
22707         do_facet mds1 lctl set_param fail_loc=0x19a
22708
22709         lfs mkdir -c $MDSCOUNT $DIR/$tdir
22710
22711         true
22712 }
22713 run_test 416 "transaction start failure won't cause system hung"
22714
22715 cleanup_417() {
22716         trap 0
22717         do_nodes $(comma_list $(mdts_nodes)) \
22718                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
22719         do_nodes $(comma_list $(mdts_nodes)) \
22720                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
22721         do_nodes $(comma_list $(mdts_nodes)) \
22722                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
22723 }
22724
22725 test_417() {
22726         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22727         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
22728                 skip "Need MDS version at least 2.11.56"
22729
22730         trap cleanup_417 RETURN EXIT
22731
22732         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
22733         do_nodes $(comma_list $(mdts_nodes)) \
22734                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
22735         $LFS migrate -m 0 $DIR/$tdir.1 &&
22736                 error "migrate dir $tdir.1 should fail"
22737
22738         do_nodes $(comma_list $(mdts_nodes)) \
22739                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
22740         $LFS mkdir -i 1 $DIR/$tdir.2 &&
22741                 error "create remote dir $tdir.2 should fail"
22742
22743         do_nodes $(comma_list $(mdts_nodes)) \
22744                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
22745         $LFS mkdir -c 2 $DIR/$tdir.3 &&
22746                 error "create striped dir $tdir.3 should fail"
22747         true
22748 }
22749 run_test 417 "disable remote dir, striped dir and dir migration"
22750
22751 # Checks that the outputs of df [-i] and lfs df [-i] match
22752 #
22753 # usage: check_lfs_df <blocks | inodes> <mountpoint>
22754 check_lfs_df() {
22755         local dir=$2
22756         local inodes
22757         local df_out
22758         local lfs_df_out
22759         local count
22760         local passed=false
22761
22762         # blocks or inodes
22763         [ "$1" == "blocks" ] && inodes= || inodes="-i"
22764
22765         for count in {1..100}; do
22766                 cancel_lru_locks
22767                 sync; sleep 0.2
22768
22769                 # read the lines of interest
22770                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
22771                         error "df $inodes $dir | tail -n +2 failed"
22772                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
22773                         error "lfs df $inodes $dir | grep summary: failed"
22774
22775                 # skip first substrings of each output as they are different
22776                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
22777                 # compare the two outputs
22778                 passed=true
22779                 for i in {1..5}; do
22780                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
22781                 done
22782                 $passed && break
22783         done
22784
22785         if ! $passed; then
22786                 df -P $inodes $dir
22787                 echo
22788                 lfs df $inodes $dir
22789                 error "df and lfs df $1 output mismatch: "      \
22790                       "df ${inodes}: ${df_out[*]}, "            \
22791                       "lfs df ${inodes}: ${lfs_df_out[*]}"
22792         fi
22793 }
22794
22795 test_418() {
22796         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22797
22798         local dir=$DIR/$tdir
22799         local numfiles=$((RANDOM % 4096 + 2))
22800         local numblocks=$((RANDOM % 256 + 1))
22801
22802         wait_delete_completed
22803         test_mkdir $dir
22804
22805         # check block output
22806         check_lfs_df blocks $dir
22807         # check inode output
22808         check_lfs_df inodes $dir
22809
22810         # create a single file and retest
22811         echo "Creating a single file and testing"
22812         createmany -o $dir/$tfile- 1 &>/dev/null ||
22813                 error "creating 1 file in $dir failed"
22814         check_lfs_df blocks $dir
22815         check_lfs_df inodes $dir
22816
22817         # create a random number of files
22818         echo "Creating $((numfiles - 1)) files and testing"
22819         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
22820                 error "creating $((numfiles - 1)) files in $dir failed"
22821
22822         # write a random number of blocks to the first test file
22823         echo "Writing $numblocks 4K blocks and testing"
22824         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
22825                 count=$numblocks &>/dev/null ||
22826                 error "dd to $dir/${tfile}-0 failed"
22827
22828         # retest
22829         check_lfs_df blocks $dir
22830         check_lfs_df inodes $dir
22831
22832         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
22833                 error "unlinking $numfiles files in $dir failed"
22834 }
22835 run_test 418 "df and lfs df outputs match"
22836
22837 test_419()
22838 {
22839         local dir=$DIR/$tdir
22840
22841         mkdir -p $dir
22842         touch $dir/file
22843
22844         cancel_lru_locks mdc
22845
22846         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
22847         $LCTL set_param fail_loc=0x1410
22848         cat $dir/file
22849         $LCTL set_param fail_loc=0
22850         rm -rf $dir
22851 }
22852 run_test 419 "Verify open file by name doesn't crash kernel"
22853
22854 test_420()
22855 {
22856         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
22857                 skip "Need MDS version at least 2.12.53"
22858
22859         local SAVE_UMASK=$(umask)
22860         local dir=$DIR/$tdir
22861         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
22862
22863         mkdir -p $dir
22864         umask 0000
22865         mkdir -m03777 $dir/testdir
22866         ls -dn $dir/testdir
22867         # Need to remove trailing '.' when SELinux is enabled
22868         local dirperms=$(ls -dn $dir/testdir |
22869                          awk '{ sub(/\.$/, "", $1); print $1}')
22870         [ $dirperms == "drwxrwsrwt" ] ||
22871                 error "incorrect perms on $dir/testdir"
22872
22873         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
22874                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
22875         ls -n $dir/testdir/testfile
22876         local fileperms=$(ls -n $dir/testdir/testfile |
22877                           awk '{ sub(/\.$/, "", $1); print $1}')
22878         [ $fileperms == "-rwxr-xr-x" ] ||
22879                 error "incorrect perms on $dir/testdir/testfile"
22880
22881         umask $SAVE_UMASK
22882 }
22883 run_test 420 "clear SGID bit on non-directories for non-members"
22884
22885 test_421a() {
22886         local cnt
22887         local fid1
22888         local fid2
22889
22890         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
22891                 skip "Need MDS version at least 2.12.54"
22892
22893         test_mkdir $DIR/$tdir
22894         createmany -o $DIR/$tdir/f 3
22895         cnt=$(ls -1 $DIR/$tdir | wc -l)
22896         [ $cnt != 3 ] && error "unexpected #files: $cnt"
22897
22898         fid1=$(lfs path2fid $DIR/$tdir/f1)
22899         fid2=$(lfs path2fid $DIR/$tdir/f2)
22900         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
22901
22902         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
22903         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
22904
22905         cnt=$(ls -1 $DIR/$tdir | wc -l)
22906         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
22907
22908         rm -f $DIR/$tdir/f3 || error "can't remove f3"
22909         createmany -o $DIR/$tdir/f 3
22910         cnt=$(ls -1 $DIR/$tdir | wc -l)
22911         [ $cnt != 3 ] && error "unexpected #files: $cnt"
22912
22913         fid1=$(lfs path2fid $DIR/$tdir/f1)
22914         fid2=$(lfs path2fid $DIR/$tdir/f2)
22915         echo "remove using fsname $FSNAME"
22916         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
22917
22918         cnt=$(ls -1 $DIR/$tdir | wc -l)
22919         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
22920 }
22921 run_test 421a "simple rm by fid"
22922
22923 test_421b() {
22924         local cnt
22925         local FID1
22926         local FID2
22927
22928         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
22929                 skip "Need MDS version at least 2.12.54"
22930
22931         test_mkdir $DIR/$tdir
22932         createmany -o $DIR/$tdir/f 3
22933         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
22934         MULTIPID=$!
22935
22936         FID1=$(lfs path2fid $DIR/$tdir/f1)
22937         FID2=$(lfs path2fid $DIR/$tdir/f2)
22938         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
22939
22940         kill -USR1 $MULTIPID
22941         wait
22942
22943         cnt=$(ls $DIR/$tdir | wc -l)
22944         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
22945 }
22946 run_test 421b "rm by fid on open file"
22947
22948 test_421c() {
22949         local cnt
22950         local FIDS
22951
22952         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
22953                 skip "Need MDS version at least 2.12.54"
22954
22955         test_mkdir $DIR/$tdir
22956         createmany -o $DIR/$tdir/f 3
22957         touch $DIR/$tdir/$tfile
22958         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
22959         cnt=$(ls -1 $DIR/$tdir | wc -l)
22960         [ $cnt != 184 ] && error "unexpected #files: $cnt"
22961
22962         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
22963         $LFS rmfid $DIR $FID1 || error "rmfid failed"
22964
22965         cnt=$(ls $DIR/$tdir | wc -l)
22966         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
22967 }
22968 run_test 421c "rm by fid against hardlinked files"
22969
22970 test_421d() {
22971         local cnt
22972         local FIDS
22973
22974         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
22975                 skip "Need MDS version at least 2.12.54"
22976
22977         test_mkdir $DIR/$tdir
22978         createmany -o $DIR/$tdir/f 4097
22979         cnt=$(ls -1 $DIR/$tdir | wc -l)
22980         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
22981
22982         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
22983         $LFS rmfid $DIR $FIDS || error "rmfid failed"
22984
22985         cnt=$(ls $DIR/$tdir | wc -l)
22986         rm -rf $DIR/$tdir
22987         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
22988 }
22989 run_test 421d "rmfid en masse"
22990
22991 test_421e() {
22992         local cnt
22993         local FID
22994
22995         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22996         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
22997                 skip "Need MDS version at least 2.12.54"
22998
22999         mkdir -p $DIR/$tdir
23000         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23001         createmany -o $DIR/$tdir/striped_dir/f 512
23002         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23003         [ $cnt != 512 ] && error "unexpected #files: $cnt"
23004
23005         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
23006                 sed "s/[/][^:]*://g")
23007         $LFS rmfid $DIR $FIDS || error "rmfid failed"
23008
23009         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
23010         rm -rf $DIR/$tdir
23011         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23012 }
23013 run_test 421e "rmfid in DNE"
23014
23015 test_421f() {
23016         local cnt
23017         local FID
23018
23019         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23020                 skip "Need MDS version at least 2.12.54"
23021
23022         test_mkdir $DIR/$tdir
23023         touch $DIR/$tdir/f
23024         cnt=$(ls -1 $DIR/$tdir | wc -l)
23025         [ $cnt != 1 ] && error "unexpected #files: $cnt"
23026
23027         FID=$(lfs path2fid $DIR/$tdir/f)
23028         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
23029         # rmfid should fail
23030         cnt=$(ls -1 $DIR/$tdir | wc -l)
23031         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
23032
23033         chmod a+rw $DIR/$tdir
23034         ls -la $DIR/$tdir
23035         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
23036         # rmfid should fail
23037         cnt=$(ls -1 $DIR/$tdir | wc -l)
23038         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
23039
23040         rm -f $DIR/$tdir/f
23041         $RUNAS touch $DIR/$tdir/f
23042         FID=$(lfs path2fid $DIR/$tdir/f)
23043         echo "rmfid as root"
23044         $LFS rmfid $DIR $FID || error "rmfid as root failed"
23045         cnt=$(ls -1 $DIR/$tdir | wc -l)
23046         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
23047
23048         rm -f $DIR/$tdir/f
23049         $RUNAS touch $DIR/$tdir/f
23050         cnt=$(ls -1 $DIR/$tdir | wc -l)
23051         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
23052         FID=$(lfs path2fid $DIR/$tdir/f)
23053         # rmfid w/o user_fid2path mount option should fail
23054         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
23055         cnt=$(ls -1 $DIR/$tdir | wc -l)
23056         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
23057
23058         umount_client $MOUNT || error "failed to umount client"
23059         mount_client $MOUNT "$MOUNT_OPTS,user_fid2path" ||
23060                 error "failed to mount client'"
23061
23062         $RUNAS $LFS rmfid $DIR $FID || error "rmfid failed"
23063         # rmfid should succeed
23064         cnt=$(ls -1 $DIR/$tdir | wc -l)
23065         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
23066
23067         # rmfid shouldn't allow to remove files due to dir's permission
23068         chmod a+rwx $DIR/$tdir
23069         touch $DIR/$tdir/f
23070         ls -la $DIR/$tdir
23071         FID=$(lfs path2fid $DIR/$tdir/f)
23072         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail"
23073
23074         umount_client $MOUNT || error "failed to umount client"
23075         mount_client $MOUNT "$MOUNT_OPTS" ||
23076                 error "failed to mount client'"
23077
23078 }
23079 run_test 421f "rmfid checks permissions"
23080
23081 test_421g() {
23082         local cnt
23083         local FIDS
23084
23085         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23086         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23087                 skip "Need MDS version at least 2.12.54"
23088
23089         mkdir -p $DIR/$tdir
23090         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23091         createmany -o $DIR/$tdir/striped_dir/f 512
23092         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23093         [ $cnt != 512 ] && error "unexpected #files: $cnt"
23094
23095         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
23096                 sed "s/[/][^:]*://g")
23097
23098         rm -f $DIR/$tdir/striped_dir/f1*
23099         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23100         removed=$((512 - cnt))
23101
23102         # few files have been just removed, so we expect
23103         # rmfid to fail on their fids
23104         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
23105         [ $removed != $errors ] && error "$errors != $removed"
23106
23107         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
23108         rm -rf $DIR/$tdir
23109         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23110 }
23111 run_test 421g "rmfid to return errors properly"
23112
23113 test_422() {
23114         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
23115         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
23116         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
23117         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
23118         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
23119
23120         local amc=$(at_max_get client)
23121         local amo=$(at_max_get mds1)
23122         local timeout=`lctl get_param -n timeout`
23123
23124         at_max_set 0 client
23125         at_max_set 0 mds1
23126
23127 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
23128         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
23129                         fail_val=$(((2*timeout + 10)*1000))
23130         touch $DIR/$tdir/d3/file &
23131         sleep 2
23132 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
23133         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
23134                         fail_val=$((2*timeout + 5))
23135         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
23136         local pid=$!
23137         sleep 1
23138         kill -9 $pid
23139         sleep $((2 * timeout))
23140         echo kill $pid
23141         kill -9 $pid
23142         lctl mark touch
23143         touch $DIR/$tdir/d2/file3
23144         touch $DIR/$tdir/d2/file4
23145         touch $DIR/$tdir/d2/file5
23146
23147         wait
23148         at_max_set $amc client
23149         at_max_set $amo mds1
23150
23151         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
23152         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
23153                 error "Watchdog is always throttled"
23154 }
23155 run_test 422 "kill a process with RPC in progress"
23156
23157 stat_test() {
23158     df -h $MOUNT &
23159     df -h $MOUNT &
23160     df -h $MOUNT &
23161     df -h $MOUNT &
23162     df -h $MOUNT &
23163     df -h $MOUNT &
23164 }
23165
23166 test_423() {
23167     local _stats
23168     # ensure statfs cache is expired
23169     sleep 2;
23170
23171     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
23172     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
23173
23174     return 0
23175 }
23176 run_test 423 "statfs should return a right data"
23177
23178 test_424() {
23179 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
23180         $LCTL set_param fail_loc=0x80000522
23181         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
23182         rm -f $DIR/$tfile
23183 }
23184 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
23185
23186 prep_801() {
23187         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
23188         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
23189                 skip "Need server version at least 2.9.55"
23190
23191         start_full_debug_logging
23192 }
23193
23194 post_801() {
23195         stop_full_debug_logging
23196 }
23197
23198 barrier_stat() {
23199         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
23200                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
23201                            awk '/The barrier for/ { print $7 }')
23202                 echo $st
23203         else
23204                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
23205                 echo \'$st\'
23206         fi
23207 }
23208
23209 barrier_expired() {
23210         local expired
23211
23212         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
23213                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
23214                           awk '/will be expired/ { print $7 }')
23215         else
23216                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
23217         fi
23218
23219         echo $expired
23220 }
23221
23222 test_801a() {
23223         prep_801
23224
23225         echo "Start barrier_freeze at: $(date)"
23226         #define OBD_FAIL_BARRIER_DELAY          0x2202
23227         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
23228         # Do not reduce barrier time - See LU-11873
23229         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
23230
23231         sleep 2
23232         local b_status=$(barrier_stat)
23233         echo "Got barrier status at: $(date)"
23234         [ "$b_status" = "'freezing_p1'" ] ||
23235                 error "(1) unexpected barrier status $b_status"
23236
23237         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
23238         wait
23239         b_status=$(barrier_stat)
23240         [ "$b_status" = "'frozen'" ] ||
23241                 error "(2) unexpected barrier status $b_status"
23242
23243         local expired=$(barrier_expired)
23244         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
23245         sleep $((expired + 3))
23246
23247         b_status=$(barrier_stat)
23248         [ "$b_status" = "'expired'" ] ||
23249                 error "(3) unexpected barrier status $b_status"
23250
23251         # Do not reduce barrier time - See LU-11873
23252         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
23253                 error "(4) fail to freeze barrier"
23254
23255         b_status=$(barrier_stat)
23256         [ "$b_status" = "'frozen'" ] ||
23257                 error "(5) unexpected barrier status $b_status"
23258
23259         echo "Start barrier_thaw at: $(date)"
23260         #define OBD_FAIL_BARRIER_DELAY          0x2202
23261         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
23262         do_facet mgs $LCTL barrier_thaw $FSNAME &
23263
23264         sleep 2
23265         b_status=$(barrier_stat)
23266         echo "Got barrier status at: $(date)"
23267         [ "$b_status" = "'thawing'" ] ||
23268                 error "(6) unexpected barrier status $b_status"
23269
23270         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
23271         wait
23272         b_status=$(barrier_stat)
23273         [ "$b_status" = "'thawed'" ] ||
23274                 error "(7) unexpected barrier status $b_status"
23275
23276         #define OBD_FAIL_BARRIER_FAILURE        0x2203
23277         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
23278         do_facet mgs $LCTL barrier_freeze $FSNAME
23279
23280         b_status=$(barrier_stat)
23281         [ "$b_status" = "'failed'" ] ||
23282                 error "(8) unexpected barrier status $b_status"
23283
23284         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
23285         do_facet mgs $LCTL barrier_thaw $FSNAME
23286
23287         post_801
23288 }
23289 run_test 801a "write barrier user interfaces and stat machine"
23290
23291 test_801b() {
23292         prep_801
23293
23294         mkdir $DIR/$tdir || error "(1) fail to mkdir"
23295         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
23296         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
23297         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
23298         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
23299
23300         cancel_lru_locks mdc
23301
23302         # 180 seconds should be long enough
23303         do_facet mgs $LCTL barrier_freeze $FSNAME 180
23304
23305         local b_status=$(barrier_stat)
23306         [ "$b_status" = "'frozen'" ] ||
23307                 error "(6) unexpected barrier status $b_status"
23308
23309         mkdir $DIR/$tdir/d0/d10 &
23310         mkdir_pid=$!
23311
23312         touch $DIR/$tdir/d1/f13 &
23313         touch_pid=$!
23314
23315         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
23316         ln_pid=$!
23317
23318         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
23319         mv_pid=$!
23320
23321         rm -f $DIR/$tdir/d4/f12 &
23322         rm_pid=$!
23323
23324         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
23325
23326         # To guarantee taht the 'stat' is not blocked
23327         b_status=$(barrier_stat)
23328         [ "$b_status" = "'frozen'" ] ||
23329                 error "(8) unexpected barrier status $b_status"
23330
23331         # let above commands to run at background
23332         sleep 5
23333
23334         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
23335         ps -p $touch_pid || error "(10) touch should be blocked"
23336         ps -p $ln_pid || error "(11) link should be blocked"
23337         ps -p $mv_pid || error "(12) rename should be blocked"
23338         ps -p $rm_pid || error "(13) unlink should be blocked"
23339
23340         b_status=$(barrier_stat)
23341         [ "$b_status" = "'frozen'" ] ||
23342                 error "(14) unexpected barrier status $b_status"
23343
23344         do_facet mgs $LCTL barrier_thaw $FSNAME
23345         b_status=$(barrier_stat)
23346         [ "$b_status" = "'thawed'" ] ||
23347                 error "(15) unexpected barrier status $b_status"
23348
23349         wait $mkdir_pid || error "(16) mkdir should succeed"
23350         wait $touch_pid || error "(17) touch should succeed"
23351         wait $ln_pid || error "(18) link should succeed"
23352         wait $mv_pid || error "(19) rename should succeed"
23353         wait $rm_pid || error "(20) unlink should succeed"
23354
23355         post_801
23356 }
23357 run_test 801b "modification will be blocked by write barrier"
23358
23359 test_801c() {
23360         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
23361
23362         prep_801
23363
23364         stop mds2 || error "(1) Fail to stop mds2"
23365
23366         do_facet mgs $LCTL barrier_freeze $FSNAME 30
23367
23368         local b_status=$(barrier_stat)
23369         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
23370                 do_facet mgs $LCTL barrier_thaw $FSNAME
23371                 error "(2) unexpected barrier status $b_status"
23372         }
23373
23374         do_facet mgs $LCTL barrier_rescan $FSNAME ||
23375                 error "(3) Fail to rescan barrier bitmap"
23376
23377         # Do not reduce barrier time - See LU-11873
23378         do_facet mgs $LCTL barrier_freeze $FSNAME 20
23379
23380         b_status=$(barrier_stat)
23381         [ "$b_status" = "'frozen'" ] ||
23382                 error "(4) unexpected barrier status $b_status"
23383
23384         do_facet mgs $LCTL barrier_thaw $FSNAME
23385         b_status=$(barrier_stat)
23386         [ "$b_status" = "'thawed'" ] ||
23387                 error "(5) unexpected barrier status $b_status"
23388
23389         local devname=$(mdsdevname 2)
23390
23391         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
23392
23393         do_facet mgs $LCTL barrier_rescan $FSNAME ||
23394                 error "(7) Fail to rescan barrier bitmap"
23395
23396         post_801
23397 }
23398 run_test 801c "rescan barrier bitmap"
23399
23400 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
23401 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
23402 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
23403 saved_MOUNT_OPTS=$MOUNT_OPTS
23404
23405 cleanup_802a() {
23406         trap 0
23407
23408         stopall
23409         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
23410         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
23411         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
23412         MOUNT_OPTS=$saved_MOUNT_OPTS
23413         setupall
23414 }
23415
23416 test_802a() {
23417         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
23418         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
23419         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
23420                 skip "Need server version at least 2.9.55"
23421
23422         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
23423
23424         mkdir $DIR/$tdir || error "(1) fail to mkdir"
23425
23426         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
23427                 error "(2) Fail to copy"
23428
23429         trap cleanup_802a EXIT
23430
23431         # sync by force before remount as readonly
23432         sync; sync_all_data; sleep 3; sync_all_data
23433
23434         stopall
23435
23436         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
23437         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
23438         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
23439
23440         echo "Mount the server as read only"
23441         setupall server_only || error "(3) Fail to start servers"
23442
23443         echo "Mount client without ro should fail"
23444         mount_client $MOUNT &&
23445                 error "(4) Mount client without 'ro' should fail"
23446
23447         echo "Mount client with ro should succeed"
23448         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
23449         mount_client $MOUNT ||
23450                 error "(5) Mount client with 'ro' should succeed"
23451
23452         echo "Modify should be refused"
23453         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
23454
23455         echo "Read should be allowed"
23456         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
23457                 error "(7) Read should succeed under ro mode"
23458
23459         cleanup_802a
23460 }
23461 run_test 802a "simulate readonly device"
23462
23463 test_802b() {
23464         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23465         remote_mds_nodsh && skip "remote MDS with nodsh"
23466
23467         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
23468                 skip "readonly option not available"
23469
23470         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
23471
23472         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
23473                 error "(2) Fail to copy"
23474
23475         # write back all cached data before setting MDT to readonly
23476         cancel_lru_locks
23477         sync_all_data
23478
23479         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
23480         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
23481
23482         echo "Modify should be refused"
23483         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
23484
23485         echo "Read should be allowed"
23486         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
23487                 error "(7) Read should succeed under ro mode"
23488
23489         # disable readonly
23490         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
23491 }
23492 run_test 802b "be able to set MDTs to readonly"
23493
23494 test_803() {
23495         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
23496         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
23497                 skip "MDS needs to be newer than 2.10.54"
23498
23499         mkdir -p $DIR/$tdir
23500         # Create some objects on all MDTs to trigger related logs objects
23501         for idx in $(seq $MDSCOUNT); do
23502                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
23503                         $DIR/$tdir/dir${idx} ||
23504                         error "Fail to create $DIR/$tdir/dir${idx}"
23505         done
23506
23507         sync; sleep 3
23508         wait_delete_completed # ensure old test cleanups are finished
23509         echo "before create:"
23510         $LFS df -i $MOUNT
23511         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
23512
23513         for i in {1..10}; do
23514                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
23515                         error "Fail to create $DIR/$tdir/foo$i"
23516         done
23517
23518         sync; sleep 3
23519         echo "after create:"
23520         $LFS df -i $MOUNT
23521         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
23522
23523         # allow for an llog to be cleaned up during the test
23524         [ $after_used -ge $((before_used + 10 - 1)) ] ||
23525                 error "before ($before_used) + 10 > after ($after_used)"
23526
23527         for i in {1..10}; do
23528                 rm -rf $DIR/$tdir/foo$i ||
23529                         error "Fail to remove $DIR/$tdir/foo$i"
23530         done
23531
23532         sleep 3 # avoid MDT return cached statfs
23533         wait_delete_completed
23534         echo "after unlink:"
23535         $LFS df -i $MOUNT
23536         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
23537
23538         # allow for an llog to be created during the test
23539         [ $after_used -le $((before_used + 1)) ] ||
23540                 error "after ($after_used) > before ($before_used) + 1"
23541 }
23542 run_test 803 "verify agent object for remote object"
23543
23544 test_804() {
23545         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
23546         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
23547                 skip "MDS needs to be newer than 2.10.54"
23548         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
23549
23550         mkdir -p $DIR/$tdir
23551         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
23552                 error "Fail to create $DIR/$tdir/dir0"
23553
23554         local fid=$($LFS path2fid $DIR/$tdir/dir0)
23555         local dev=$(mdsdevname 2)
23556
23557         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23558                 grep ${fid} || error "NOT found agent entry for dir0"
23559
23560         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
23561                 error "Fail to create $DIR/$tdir/dir1"
23562
23563         touch $DIR/$tdir/dir1/foo0 ||
23564                 error "Fail to create $DIR/$tdir/dir1/foo0"
23565         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
23566         local rc=0
23567
23568         for idx in $(seq $MDSCOUNT); do
23569                 dev=$(mdsdevname $idx)
23570                 do_facet mds${idx} \
23571                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23572                         grep ${fid} && rc=$idx
23573         done
23574
23575         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
23576                 error "Fail to rename foo0 to foo1"
23577         if [ $rc -eq 0 ]; then
23578                 for idx in $(seq $MDSCOUNT); do
23579                         dev=$(mdsdevname $idx)
23580                         do_facet mds${idx} \
23581                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23582                         grep ${fid} && rc=$idx
23583                 done
23584         fi
23585
23586         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
23587                 error "Fail to rename foo1 to foo2"
23588         if [ $rc -eq 0 ]; then
23589                 for idx in $(seq $MDSCOUNT); do
23590                         dev=$(mdsdevname $idx)
23591                         do_facet mds${idx} \
23592                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23593                         grep ${fid} && rc=$idx
23594                 done
23595         fi
23596
23597         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
23598
23599         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
23600                 error "Fail to link to $DIR/$tdir/dir1/foo2"
23601         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
23602                 error "Fail to rename foo2 to foo0"
23603         unlink $DIR/$tdir/dir1/foo0 ||
23604                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
23605         rm -rf $DIR/$tdir/dir0 ||
23606                 error "Fail to rm $DIR/$tdir/dir0"
23607
23608         for idx in $(seq $MDSCOUNT); do
23609                 dev=$(mdsdevname $idx)
23610                 rc=0
23611
23612                 stop mds${idx}
23613                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
23614                         rc=$?
23615                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
23616                         error "mount mds$idx failed"
23617                 df $MOUNT > /dev/null 2>&1
23618
23619                 # e2fsck should not return error
23620                 [ $rc -eq 0 ] ||
23621                         error "e2fsck detected error on MDT${idx}: rc=$rc"
23622         done
23623 }
23624 run_test 804 "verify agent entry for remote entry"
23625
23626 cleanup_805() {
23627         do_facet $SINGLEMDS zfs set quota=$old $fsset
23628         unlinkmany $DIR/$tdir/f- 1000000
23629         trap 0
23630 }
23631
23632 test_805() {
23633         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
23634         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
23635         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
23636                 skip "netfree not implemented before 0.7"
23637         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
23638                 skip "Need MDS version at least 2.10.57"
23639
23640         local fsset
23641         local freekb
23642         local usedkb
23643         local old
23644         local quota
23645         local pref="osd-zfs.$FSNAME-MDT0000."
23646
23647         # limit available space on MDS dataset to meet nospace issue
23648         # quickly. then ZFS 0.7.2 can use reserved space if asked
23649         # properly (using netfree flag in osd_declare_destroy()
23650         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
23651         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
23652                 gawk '{print $3}')
23653         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
23654         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
23655         let "usedkb=usedkb-freekb"
23656         let "freekb=freekb/2"
23657         if let "freekb > 5000"; then
23658                 let "freekb=5000"
23659         fi
23660         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
23661         trap cleanup_805 EXIT
23662         mkdir $DIR/$tdir
23663         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
23664                 error "Can't set PFL layout"
23665         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
23666         rm -rf $DIR/$tdir || error "not able to remove"
23667         do_facet $SINGLEMDS zfs set quota=$old $fsset
23668         trap 0
23669 }
23670 run_test 805 "ZFS can remove from full fs"
23671
23672 # Size-on-MDS test
23673 check_lsom_data()
23674 {
23675         local file=$1
23676         local size=$($LFS getsom -s $file)
23677         local expect=$(stat -c %s $file)
23678
23679         [[ $size == $expect ]] ||
23680                 error "$file expected size: $expect, got: $size"
23681
23682         local blocks=$($LFS getsom -b $file)
23683         expect=$(stat -c %b $file)
23684         [[ $blocks == $expect ]] ||
23685                 error "$file expected blocks: $expect, got: $blocks"
23686 }
23687
23688 check_lsom_size()
23689 {
23690         local size=$($LFS getsom -s $1)
23691         local expect=$2
23692
23693         [[ $size == $expect ]] ||
23694                 error "$file expected size: $expect, got: $size"
23695 }
23696
23697 test_806() {
23698         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
23699                 skip "Need MDS version at least 2.11.52"
23700
23701         local bs=1048576
23702
23703         touch $DIR/$tfile || error "touch $tfile failed"
23704
23705         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23706         save_lustre_params client "llite.*.xattr_cache" > $save
23707         lctl set_param llite.*.xattr_cache=0
23708         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23709
23710         # single-threaded write
23711         echo "Test SOM for single-threaded write"
23712         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
23713                 error "write $tfile failed"
23714         check_lsom_size $DIR/$tfile $bs
23715
23716         local num=32
23717         local size=$(($num * $bs))
23718         local offset=0
23719         local i
23720
23721         echo "Test SOM for single client multi-threaded($num) write"
23722         $TRUNCATE $DIR/$tfile 0
23723         for ((i = 0; i < $num; i++)); do
23724                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
23725                 local pids[$i]=$!
23726                 offset=$((offset + $bs))
23727         done
23728         for (( i=0; i < $num; i++ )); do
23729                 wait ${pids[$i]}
23730         done
23731         check_lsom_size $DIR/$tfile $size
23732
23733         $TRUNCATE $DIR/$tfile 0
23734         for ((i = 0; i < $num; i++)); do
23735                 offset=$((offset - $bs))
23736                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
23737                 local pids[$i]=$!
23738         done
23739         for (( i=0; i < $num; i++ )); do
23740                 wait ${pids[$i]}
23741         done
23742         check_lsom_size $DIR/$tfile $size
23743
23744         # multi-client writes
23745         num=$(get_node_count ${CLIENTS//,/ })
23746         size=$(($num * $bs))
23747         offset=0
23748         i=0
23749
23750         echo "Test SOM for multi-client ($num) writes"
23751         $TRUNCATE $DIR/$tfile 0
23752         for client in ${CLIENTS//,/ }; do
23753                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
23754                 local pids[$i]=$!
23755                 i=$((i + 1))
23756                 offset=$((offset + $bs))
23757         done
23758         for (( i=0; i < $num; i++ )); do
23759                 wait ${pids[$i]}
23760         done
23761         check_lsom_size $DIR/$tfile $offset
23762
23763         i=0
23764         $TRUNCATE $DIR/$tfile 0
23765         for client in ${CLIENTS//,/ }; do
23766                 offset=$((offset - $bs))
23767                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
23768                 local pids[$i]=$!
23769                 i=$((i + 1))
23770         done
23771         for (( i=0; i < $num; i++ )); do
23772                 wait ${pids[$i]}
23773         done
23774         check_lsom_size $DIR/$tfile $size
23775
23776         # verify truncate
23777         echo "Test SOM for truncate"
23778         $TRUNCATE $DIR/$tfile 1048576
23779         check_lsom_size $DIR/$tfile 1048576
23780         $TRUNCATE $DIR/$tfile 1234
23781         check_lsom_size $DIR/$tfile 1234
23782
23783         # verify SOM blocks count
23784         echo "Verify SOM block count"
23785         $TRUNCATE $DIR/$tfile 0
23786         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
23787                 error "failed to write file $tfile"
23788         check_lsom_data $DIR/$tfile
23789 }
23790 run_test 806 "Verify Lazy Size on MDS"
23791
23792 test_807() {
23793         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
23794         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
23795                 skip "Need MDS version at least 2.11.52"
23796
23797         # Registration step
23798         changelog_register || error "changelog_register failed"
23799         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
23800         changelog_users $SINGLEMDS | grep -q $cl_user ||
23801                 error "User $cl_user not found in changelog_users"
23802
23803         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23804         save_lustre_params client "llite.*.xattr_cache" > $save
23805         lctl set_param llite.*.xattr_cache=0
23806         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23807
23808         rm -rf $DIR/$tdir || error "rm $tdir failed"
23809         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
23810         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
23811         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
23812         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
23813                 error "truncate $tdir/trunc failed"
23814
23815         local bs=1048576
23816         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
23817                 error "write $tfile failed"
23818
23819         # multi-client wirtes
23820         local num=$(get_node_count ${CLIENTS//,/ })
23821         local offset=0
23822         local i=0
23823
23824         echo "Test SOM for multi-client ($num) writes"
23825         touch $DIR/$tfile || error "touch $tfile failed"
23826         $TRUNCATE $DIR/$tfile 0
23827         for client in ${CLIENTS//,/ }; do
23828                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
23829                 local pids[$i]=$!
23830                 i=$((i + 1))
23831                 offset=$((offset + $bs))
23832         done
23833         for (( i=0; i < $num; i++ )); do
23834                 wait ${pids[$i]}
23835         done
23836
23837         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
23838         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
23839         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
23840         check_lsom_data $DIR/$tdir/trunc
23841         check_lsom_data $DIR/$tdir/single_dd
23842         check_lsom_data $DIR/$tfile
23843
23844         rm -rf $DIR/$tdir
23845         # Deregistration step
23846         changelog_deregister || error "changelog_deregister failed"
23847 }
23848 run_test 807 "verify LSOM syncing tool"
23849
23850 check_som_nologged()
23851 {
23852         local lines=$($LFS changelog $FSNAME-MDT0000 |
23853                 grep 'x=trusted.som' | wc -l)
23854         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
23855 }
23856
23857 test_808() {
23858         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
23859                 skip "Need MDS version at least 2.11.55"
23860
23861         # Registration step
23862         changelog_register || error "changelog_register failed"
23863
23864         touch $DIR/$tfile || error "touch $tfile failed"
23865         check_som_nologged
23866
23867         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
23868                 error "write $tfile failed"
23869         check_som_nologged
23870
23871         $TRUNCATE $DIR/$tfile 1234
23872         check_som_nologged
23873
23874         $TRUNCATE $DIR/$tfile 1048576
23875         check_som_nologged
23876
23877         # Deregistration step
23878         changelog_deregister || error "changelog_deregister failed"
23879 }
23880 run_test 808 "Check trusted.som xattr not logged in Changelogs"
23881
23882 check_som_nodata()
23883 {
23884         $LFS getsom $1
23885         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
23886 }
23887
23888 test_809() {
23889         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
23890                 skip "Need MDS version at least 2.11.56"
23891
23892         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
23893                 error "failed to create DoM-only file $DIR/$tfile"
23894         touch $DIR/$tfile || error "touch $tfile failed"
23895         check_som_nodata $DIR/$tfile
23896
23897         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
23898                 error "write $tfile failed"
23899         check_som_nodata $DIR/$tfile
23900
23901         $TRUNCATE $DIR/$tfile 1234
23902         check_som_nodata $DIR/$tfile
23903
23904         $TRUNCATE $DIR/$tfile 4097
23905         check_som_nodata $DIR/$file
23906 }
23907 run_test 809 "Verify no SOM xattr store for DoM-only files"
23908
23909 test_810() {
23910         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23911         $GSS && skip_env "could not run with gss"
23912         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
23913                 skip "OST < 2.12.58 doesn't align checksum"
23914
23915         set_checksums 1
23916         stack_trap "set_checksums $ORIG_CSUM" EXIT
23917         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
23918
23919         local csum
23920         local before
23921         local after
23922         for csum in $CKSUM_TYPES; do
23923                 #define OBD_FAIL_OSC_NO_GRANT   0x411
23924                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
23925                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
23926                         eval set -- $i
23927                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
23928                         before=$(md5sum $DIR/$tfile)
23929                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
23930                         after=$(md5sum $DIR/$tfile)
23931                         [ "$before" == "$after" ] ||
23932                                 error "$csum: $before != $after bs=$1 seek=$2"
23933                 done
23934         done
23935 }
23936 run_test 810 "partial page writes on ZFS (LU-11663)"
23937
23938 test_812a() {
23939         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
23940                 skip "OST < 2.12.51 doesn't support this fail_loc"
23941         [ "$SHARED_KEY" = true ] &&
23942                 skip "OSC connections never go IDLE with Shared-Keys enabled"
23943
23944         $LFS setstripe -c 1 -i 0 $DIR/$tfile
23945         # ensure ost1 is connected
23946         stat $DIR/$tfile >/dev/null || error "can't stat"
23947         wait_osc_import_state client ost1 FULL
23948         # no locks, no reqs to let the connection idle
23949         cancel_lru_locks osc
23950
23951         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
23952 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
23953         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
23954         wait_osc_import_state client ost1 CONNECTING
23955         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
23956
23957         stat $DIR/$tfile >/dev/null || error "can't stat file"
23958 }
23959 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
23960
23961 test_812b() { # LU-12378
23962         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
23963                 skip "OST < 2.12.51 doesn't support this fail_loc"
23964         [ "$SHARED_KEY" = true ] &&
23965                 skip "OSC connections never go IDLE with Shared-Keys enabled"
23966
23967         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
23968         # ensure ost1 is connected
23969         stat $DIR/$tfile >/dev/null || error "can't stat"
23970         wait_osc_import_state client ost1 FULL
23971         # no locks, no reqs to let the connection idle
23972         cancel_lru_locks osc
23973
23974         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
23975 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
23976         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
23977         wait_osc_import_state client ost1 CONNECTING
23978         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
23979
23980         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
23981         wait_osc_import_state client ost1 IDLE
23982 }
23983 run_test 812b "do not drop no resend request for idle connect"
23984
23985 test_813() {
23986         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
23987         [ -z "$file_heat_sav" ] && skip "no file heat support"
23988
23989         local readsample
23990         local writesample
23991         local readbyte
23992         local writebyte
23993         local readsample1
23994         local writesample1
23995         local readbyte1
23996         local writebyte1
23997
23998         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
23999         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
24000
24001         $LCTL set_param -n llite.*.file_heat=1
24002         echo "Turn on file heat"
24003         echo "Period second: $period_second, Decay percentage: $decay_pct"
24004
24005         echo "QQQQ" > $DIR/$tfile
24006         echo "QQQQ" > $DIR/$tfile
24007         echo "QQQQ" > $DIR/$tfile
24008         cat $DIR/$tfile > /dev/null
24009         cat $DIR/$tfile > /dev/null
24010         cat $DIR/$tfile > /dev/null
24011         cat $DIR/$tfile > /dev/null
24012
24013         local out=$($LFS heat_get $DIR/$tfile)
24014
24015         $LFS heat_get $DIR/$tfile
24016         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24017         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24018         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24019         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24020
24021         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
24022         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
24023         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
24024         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
24025
24026         sleep $((period_second + 3))
24027         echo "Sleep $((period_second + 3)) seconds..."
24028         # The recursion formula to calculate the heat of the file f is as
24029         # follow:
24030         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
24031         # Where Hi is the heat value in the period between time points i*I and
24032         # (i+1)*I; Ci is the access count in the period; the symbol P refers
24033         # to the weight of Ci.
24034         out=$($LFS heat_get $DIR/$tfile)
24035         $LFS heat_get $DIR/$tfile
24036         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24037         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24038         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24039         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24040
24041         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
24042                 error "read sample ($readsample) is wrong"
24043         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
24044                 error "write sample ($writesample) is wrong"
24045         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
24046                 error "read bytes ($readbyte) is wrong"
24047         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
24048                 error "write bytes ($writebyte) is wrong"
24049
24050         echo "QQQQ" > $DIR/$tfile
24051         echo "QQQQ" > $DIR/$tfile
24052         echo "QQQQ" > $DIR/$tfile
24053         cat $DIR/$tfile > /dev/null
24054         cat $DIR/$tfile > /dev/null
24055         cat $DIR/$tfile > /dev/null
24056         cat $DIR/$tfile > /dev/null
24057
24058         sleep $((period_second + 3))
24059         echo "Sleep $((period_second + 3)) seconds..."
24060
24061         out=$($LFS heat_get $DIR/$tfile)
24062         $LFS heat_get $DIR/$tfile
24063         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24064         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24065         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24066         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24067
24068         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
24069                 4 * $decay_pct) / 100") -eq 1 ] ||
24070                 error "read sample ($readsample1) is wrong"
24071         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
24072                 3 * $decay_pct) / 100") -eq 1 ] ||
24073                 error "write sample ($writesample1) is wrong"
24074         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
24075                 20 * $decay_pct) / 100") -eq 1 ] ||
24076                 error "read bytes ($readbyte1) is wrong"
24077         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
24078                 15 * $decay_pct) / 100") -eq 1 ] ||
24079                 error "write bytes ($writebyte1) is wrong"
24080
24081         echo "Turn off file heat for the file $DIR/$tfile"
24082         $LFS heat_set -o $DIR/$tfile
24083
24084         echo "QQQQ" > $DIR/$tfile
24085         echo "QQQQ" > $DIR/$tfile
24086         echo "QQQQ" > $DIR/$tfile
24087         cat $DIR/$tfile > /dev/null
24088         cat $DIR/$tfile > /dev/null
24089         cat $DIR/$tfile > /dev/null
24090         cat $DIR/$tfile > /dev/null
24091
24092         out=$($LFS heat_get $DIR/$tfile)
24093         $LFS heat_get $DIR/$tfile
24094         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24095         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24096         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24097         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24098
24099         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
24100         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
24101         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
24102         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
24103
24104         echo "Trun on file heat for the file $DIR/$tfile"
24105         $LFS heat_set -O $DIR/$tfile
24106
24107         echo "QQQQ" > $DIR/$tfile
24108         echo "QQQQ" > $DIR/$tfile
24109         echo "QQQQ" > $DIR/$tfile
24110         cat $DIR/$tfile > /dev/null
24111         cat $DIR/$tfile > /dev/null
24112         cat $DIR/$tfile > /dev/null
24113         cat $DIR/$tfile > /dev/null
24114
24115         out=$($LFS heat_get $DIR/$tfile)
24116         $LFS heat_get $DIR/$tfile
24117         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24118         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24119         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24120         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24121
24122         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
24123         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
24124         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
24125         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
24126
24127         $LFS heat_set -c $DIR/$tfile
24128         $LCTL set_param -n llite.*.file_heat=0
24129         echo "Turn off file heat support for the Lustre filesystem"
24130
24131         echo "QQQQ" > $DIR/$tfile
24132         echo "QQQQ" > $DIR/$tfile
24133         echo "QQQQ" > $DIR/$tfile
24134         cat $DIR/$tfile > /dev/null
24135         cat $DIR/$tfile > /dev/null
24136         cat $DIR/$tfile > /dev/null
24137         cat $DIR/$tfile > /dev/null
24138
24139         out=$($LFS heat_get $DIR/$tfile)
24140         $LFS heat_get $DIR/$tfile
24141         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24142         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24143         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24144         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24145
24146         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
24147         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
24148         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
24149         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
24150
24151         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
24152         rm -f $DIR/$tfile
24153 }
24154 run_test 813 "File heat verfication"
24155
24156 test_814()
24157 {
24158         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
24159         echo -n y >> $DIR/$tfile
24160         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
24161         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
24162 }
24163 run_test 814 "sparse cp works as expected (LU-12361)"
24164
24165 test_815()
24166 {
24167         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
24168         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
24169 }
24170 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
24171
24172 test_816() {
24173         [ "$SHARED_KEY" = true ] &&
24174                 skip "OSC connections never go IDLE with Shared-Keys enabled"
24175
24176         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24177         # ensure ost1 is connected
24178         stat $DIR/$tfile >/dev/null || error "can't stat"
24179         wait_osc_import_state client ost1 FULL
24180         # no locks, no reqs to let the connection idle
24181         cancel_lru_locks osc
24182         lru_resize_disable osc
24183         local before
24184         local now
24185         before=$($LCTL get_param -n \
24186                  ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
24187
24188         wait_osc_import_state client ost1 IDLE
24189         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
24190         now=$($LCTL get_param -n \
24191               ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
24192         [ $before == $now ] || error "lru_size changed $before != $now"
24193 }
24194 run_test 816 "do not reset lru_resize on idle reconnect"
24195
24196 cleanup_817() {
24197         umount $tmpdir
24198         exportfs -u localhost:$DIR/nfsexp
24199         rm -rf $DIR/nfsexp
24200 }
24201
24202 test_817() {
24203         systemctl restart nfs-server.service || skip "failed to restart nfsd"
24204
24205         mkdir -p $DIR/nfsexp
24206         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
24207                 error "failed to export nfs"
24208
24209         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
24210         stack_trap cleanup_817 EXIT
24211
24212         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
24213                 error "failed to mount nfs to $tmpdir"
24214
24215         cp /bin/true $tmpdir
24216         $DIR/nfsexp/true || error "failed to execute 'true' command"
24217 }
24218 run_test 817 "nfsd won't cache write lock for exec file"
24219
24220 test_818() {
24221         mkdir $DIR/$tdir
24222         $LFS setstripe -c1 -i0 $DIR/$tfile
24223         $LFS setstripe -c1 -i1 $DIR/$tfile
24224         stop $SINGLEMDS
24225         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
24226         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
24227         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
24228                 error "start $SINGLEMDS failed"
24229         rm -rf $DIR/$tdir
24230 }
24231 run_test 818 "unlink with failed llog"
24232
24233 test_819a() {
24234         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24235         cancel_lru_locks osc
24236         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
24237         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
24238         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
24239         rm -f $TDIR/$tfile
24240 }
24241 run_test 819a "too big niobuf in read"
24242
24243 test_819b() {
24244         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
24245         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
24246         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24247         cancel_lru_locks osc
24248         sleep 1
24249         rm -f $TDIR/$tfile
24250 }
24251 run_test 819b "too big niobuf in write"
24252
24253
24254 function test_820_start_ost() {
24255         sleep 5
24256
24257         for num in $(seq $OSTCOUNT); do
24258                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
24259         done
24260 }
24261
24262 test_820() {
24263         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24264
24265         mkdir $DIR/$tdir
24266         umount_client $MOUNT || error "umount failed"
24267         for num in $(seq $OSTCOUNT); do
24268                 stop ost$num
24269         done
24270
24271         # mount client with no active OSTs
24272         # so that the client can't initialize max LOV EA size
24273         # from OSC notifications
24274         mount_client $MOUNT || error "mount failed"
24275         # delay OST starting to keep this 0 max EA size for a while
24276         test_820_start_ost &
24277
24278         # create a directory on MDS2
24279         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
24280                 error "Failed to create directory"
24281         # open intent should update default EA size
24282         # see mdc_update_max_ea_from_body()
24283         # notice this is the very first RPC to MDS2
24284         cp /etc/services $DIR/$tdir/mds2 ||
24285                 error "Failed to copy files to mds$n"
24286 }
24287 run_test 820 "update max EA from open intent"
24288
24289 #
24290 # tests that do cleanup/setup should be run at the end
24291 #
24292
24293 test_900() {
24294         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24295         local ls
24296
24297         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
24298         $LCTL set_param fail_loc=0x903
24299
24300         cancel_lru_locks MGC
24301
24302         FAIL_ON_ERROR=true cleanup
24303         FAIL_ON_ERROR=true setup
24304 }
24305 run_test 900 "umount should not race with any mgc requeue thread"
24306
24307 # LUS-6253/LU-11185
24308 test_901() {
24309         local oldc
24310         local newc
24311         local olds
24312         local news
24313         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24314
24315         # some get_param have a bug to handle dot in param name
24316         cancel_lru_locks MGC
24317         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
24318         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
24319         umount_client $MOUNT || error "umount failed"
24320         mount_client $MOUNT || error "mount failed"
24321         cancel_lru_locks MGC
24322         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
24323         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
24324
24325         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
24326         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
24327
24328         return 0
24329 }
24330 run_test 901 "don't leak a mgc lock on client umount"
24331
24332 # LU-13377
24333 test_902() {
24334         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
24335                 skip "client does not have LU-13377 fix"
24336         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
24337         $LCTL set_param fail_loc=0x1415
24338         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24339         cancel_lru_locks osc
24340         rm -f $DIR/$tfile
24341 }
24342 run_test 902 "test short write doesn't hang lustre"
24343
24344 complete $SECONDS
24345 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
24346 check_and_cleanup_lustre
24347 if [ "$I_MOUNTED" != "yes" ]; then
24348         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
24349 fi
24350 exit_status