Whamcloud - gitweb
LU-13425 lfs: support numeric hash type by "lfs migrate -H"
[fs/lustre-release.git] / lustre / tests / sanity.sh
1 #!/bin/bash
2 #
3 # Run select tests by setting ONLY, or as arguments to the script.
4 # Skip specific tests by setting EXCEPT.
5 #
6 # e.g. ONLY="22 23" or ONLY="`seq 32 39`" or EXCEPT="31"
7 set -e
8
9 ONLY=${ONLY:-"$*"}
10
11 # Check Grants after these tests
12 GRANT_CHECK_LIST="$GRANT_CHECK_LIST 42a 42b 42c 42d 42e 63a 63b 64a 64b 64c 64d"
13
14 OSC=${OSC:-"osc"}
15
16 CC=${CC:-cc}
17 CREATETEST=${CREATETEST:-createtest}
18 LVERIFY=${LVERIFY:-ll_dirstripe_verify}
19 OPENFILE=${OPENFILE:-openfile}
20 OPENUNLINK=${OPENUNLINK:-openunlink}
21 READS=${READS:-"reads"}
22 MUNLINK=${MUNLINK:-munlink}
23 SOCKETSERVER=${SOCKETSERVER:-socketserver}
24 SOCKETCLIENT=${SOCKETCLIENT:-socketclient}
25 MEMHOG=${MEMHOG:-memhog}
26 DIRECTIO=${DIRECTIO:-directio}
27 ACCEPTOR_PORT=${ACCEPTOR_PORT:-988}
28 DEF_STRIPE_COUNT=-1
29 CHECK_GRANT=${CHECK_GRANT:-"yes"}
30 GRANT_CHECK_LIST=${GRANT_CHECK_LIST:-""}
31 export PARALLEL=${PARALLEL:-"no"}
32
33 TRACE=${TRACE:-""}
34 LUSTRE=${LUSTRE:-$(dirname $0)/..}
35 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
36 . $LUSTRE/tests/test-framework.sh
37 init_test_env $@
38
39 init_logging
40
41 ALWAYS_EXCEPT="$SANITY_EXCEPT "
42 # bug number for skipped test: LU-9693 LU-6493 LU-9693
43 ALWAYS_EXCEPT+="               42a     42b     42c "
44 # bug number:    LU-8411 LU-9054 LU-13314
45 ALWAYS_EXCEPT+=" 407     312    56ob"
46
47 if $SHARED_KEY; then
48         # bug number:    LU-9795 LU-9795 LU-9795 LU-9795
49         ALWAYS_EXCEPT+=" 17n     60a     133g    300f"
50 fi
51
52 selinux_status=$(getenforce)
53 if [ "$selinux_status" != "Disabled" ]; then
54         # bug number:
55         ALWAYS_EXCEPT+=""
56 fi
57
58 # skip the grant tests for ARM until they are fixed
59 if [[ $(uname -m) = aarch64 ]]; then
60         # bug number:    LU-11596
61         ALWAYS_EXCEPT+=" $GRANT_CHECK_LIST"
62         # bug number:    LU-11671 LU-11667
63         ALWAYS_EXCEPT+=" 45       317"
64 fi
65
66 # skip nfs tests on kernels >= 4.14.0 until they are fixed
67 if [ $LINUX_VERSION_CODE -ge $(version_code 4.14.0) ]; then
68         # bug number:   LU-12661
69         ALWAYS_EXCEPT+=" 817"
70 fi
71 # skip cgroup tests on RHEL8.1 kernels until they are fixed
72 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
73       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
74         # bug number:   LU-13063
75         ALWAYS_EXCEPT+=" 411"
76 fi
77
78 #                                  5          12     8   12  (min)"
79 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 64b 68 71 115 135 136 300o"
80
81 if [ "$mds1_FSTYPE" = "zfs" ]; then
82         # bug number for skipped test:
83         ALWAYS_EXCEPT="$ALWAYS_EXCEPT  "
84         #                                               13    (min)"
85         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
86 fi
87
88 # Get the SLES distro version
89 #
90 # Returns a version string that should only be used in comparing
91 # strings returned by version_code()
92 sles_version_code()
93 {
94         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
95
96         # All SuSE Linux versions have one decimal. version_code expects two
97         local sles_version=$version.0
98         version_code $sles_version
99 }
100
101 # Check if we are running on Ubuntu or SLES so we can make decisions on
102 # what tests to run
103 if [ -r /etc/SuSE-release ]; then
104         sles_version=$(sles_version_code)
105         [ $sles_version -lt $(version_code 11.4.0) ] &&
106                 # bug number for skipped test: LU-4341
107                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  170"
108         [ $sles_version -lt $(version_code 12.0.0) ] &&
109                 # bug number for skipped test: LU-3703
110                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  234"
111 elif [ -r /etc/os-release ]; then
112         if grep -qi ubuntu /etc/os-release; then
113                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
114                                                 -e 's/^VERSION=//p' \
115                                                 /etc/os-release |
116                                                 awk '{ print $1 }'))
117
118                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
119                         # bug number for skipped test:
120                         #                LU-10334 LU-10366
121                         ALWAYS_EXCEPT+=" 103a     410"
122                 fi
123         fi
124 fi
125
126 build_test_filter
127 FAIL_ON_ERROR=false
128
129 cleanup() {
130         echo -n "cln.."
131         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
132         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
133 }
134 setup() {
135         echo -n "mnt.."
136         load_modules
137         setupall || exit 10
138         echo "done"
139 }
140
141 check_swap_layouts_support()
142 {
143         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
144                 skip "Does not support layout lock."
145 }
146
147 check_and_setup_lustre
148 DIR=${DIR:-$MOUNT}
149 assert_DIR
150
151 MAXFREE=${MAXFREE:-$((200000 * $OSTCOUNT))}
152
153 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
154 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
155 rm -rf $DIR/[Rdfs][0-9]*
156
157 # $RUNAS_ID may get set incorrectly somewhere else
158 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
159         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
160
161 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
162
163 if [ "${ONLY}" = "MOUNT" ] ; then
164         echo "Lustre is up, please go on"
165         exit
166 fi
167
168 echo "preparing for tests involving mounts"
169 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
170 touch $EXT2_DEV
171 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
172 echo # add a newline after mke2fs.
173
174 umask 077
175
176 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
177 lctl set_param debug=-1 2> /dev/null || true
178 test_0a() {
179         touch $DIR/$tfile
180         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
181         rm $DIR/$tfile
182         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
183 }
184 run_test 0a "touch; rm ====================="
185
186 test_0b() {
187         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
188         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
189 }
190 run_test 0b "chmod 0755 $DIR ============================="
191
192 test_0c() {
193         $LCTL get_param mdc.*.import | grep "state: FULL" ||
194                 error "import not FULL"
195         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
196                 error "bad target"
197 }
198 run_test 0c "check import proc"
199
200 test_0d() { # LU-3397
201         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
202                 skip "proc exports not supported before 2.10.57"
203
204         local mgs_exp="mgs.MGS.exports"
205         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
206         local exp_client_nid
207         local exp_client_version
208         local exp_val
209         local imp_val
210         local temp_imp=$DIR/$tfile.import
211         local temp_exp=$DIR/$tfile.export
212
213         # save mgc import file to $temp_imp
214         $LCTL get_param mgc.*.import | tee $temp_imp
215         # Check if client uuid is found in MGS export
216         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
217                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
218                         $client_uuid ] &&
219                         break;
220         done
221         # save mgs export file to $temp_exp
222         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
223
224         # Compare the value of field "connect_flags"
225         imp_val=$(grep "connect_flags" $temp_imp)
226         exp_val=$(grep "connect_flags" $temp_exp)
227         [ "$exp_val" == "$imp_val" ] ||
228                 error "export flags '$exp_val' != import flags '$imp_val'"
229
230         # Compare the value of client version
231         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
232         exp_val=$(version_code $exp_client_version)
233         imp_val=$CLIENT_VERSION
234         [ "$exp_val" == "$imp_val" ] ||
235                 error "export client version '$exp_val' != '$imp_val'"
236 }
237 run_test 0d "check export proc ============================="
238
239 test_1() {
240         test_mkdir $DIR/$tdir
241         test_mkdir $DIR/$tdir/d2
242         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
243         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
244         rmdir $DIR/$tdir/d2
245         rmdir $DIR/$tdir
246         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
247 }
248 run_test 1 "mkdir; remkdir; rmdir"
249
250 test_2() {
251         test_mkdir $DIR/$tdir
252         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
253         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
254         rm -r $DIR/$tdir
255         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
256 }
257 run_test 2 "mkdir; touch; rmdir; check file"
258
259 test_3() {
260         test_mkdir $DIR/$tdir
261         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
262         touch $DIR/$tdir/$tfile
263         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
264         rm -r $DIR/$tdir
265         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
266 }
267 run_test 3 "mkdir; touch; rmdir; check dir"
268
269 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
270 test_4() {
271         test_mkdir -i 1 $DIR/$tdir
272
273         touch $DIR/$tdir/$tfile ||
274                 error "Create file under remote directory failed"
275
276         rmdir $DIR/$tdir &&
277                 error "Expect error removing in-use dir $DIR/$tdir"
278
279         test -d $DIR/$tdir || error "Remote directory disappeared"
280
281         rm -rf $DIR/$tdir || error "remove remote dir error"
282 }
283 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
284
285 test_5() {
286         test_mkdir $DIR/$tdir
287         test_mkdir $DIR/$tdir/d2
288         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
289         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
290         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
291 }
292 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
293
294 test_6a() {
295         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
296         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
297         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
298                 error "$tfile does not have perm 0666 or UID $UID"
299         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
300         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
301                 error "$tfile should be 0666 and owned by UID $UID"
302 }
303 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
304
305 test_6c() {
306         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
307
308         touch $DIR/$tfile
309         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
310         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
311                 error "$tfile should be owned by UID $RUNAS_ID"
312         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
313         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
314                 error "$tfile should be owned by UID $RUNAS_ID"
315 }
316 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
317
318 test_6e() {
319         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
320
321         touch $DIR/$tfile
322         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
323         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
324                 error "$tfile should be owned by GID $UID"
325         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
326         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
327                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
328 }
329 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
330
331 test_6g() {
332         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
333
334         test_mkdir $DIR/$tdir
335         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
336         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
337         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
338         test_mkdir $DIR/$tdir/d/subdir
339         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
340                 error "$tdir/d/subdir should be GID $RUNAS_GID"
341         if [[ $MDSCOUNT -gt 1 ]]; then
342                 # check remote dir sgid inherite
343                 $LFS mkdir -i 0 $DIR/$tdir.local ||
344                         error "mkdir $tdir.local failed"
345                 chmod g+s $DIR/$tdir.local ||
346                         error "chmod $tdir.local failed"
347                 chgrp $RUNAS_GID $DIR/$tdir.local ||
348                         error "chgrp $tdir.local failed"
349                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
350                         error "mkdir $tdir.remote failed"
351                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
352                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
353                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
354                         error "$tdir.remote should be mode 02755"
355         fi
356 }
357 run_test 6g "verify new dir in sgid dir inherits group"
358
359 test_6h() { # bug 7331
360         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
361
362         touch $DIR/$tfile || error "touch failed"
363         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
364         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
365                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
366         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
367                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
368 }
369 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
370
371 test_7a() {
372         test_mkdir $DIR/$tdir
373         $MCREATE $DIR/$tdir/$tfile
374         chmod 0666 $DIR/$tdir/$tfile
375         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
376                 error "$tdir/$tfile should be mode 0666"
377 }
378 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
379
380 test_7b() {
381         if [ ! -d $DIR/$tdir ]; then
382                 test_mkdir $DIR/$tdir
383         fi
384         $MCREATE $DIR/$tdir/$tfile
385         echo -n foo > $DIR/$tdir/$tfile
386         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
387         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
388 }
389 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
390
391 test_8() {
392         test_mkdir $DIR/$tdir
393         touch $DIR/$tdir/$tfile
394         chmod 0666 $DIR/$tdir/$tfile
395         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
396                 error "$tfile mode not 0666"
397 }
398 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
399
400 test_9() {
401         test_mkdir $DIR/$tdir
402         test_mkdir $DIR/$tdir/d2
403         test_mkdir $DIR/$tdir/d2/d3
404         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
405 }
406 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
407
408 test_10() {
409         test_mkdir $DIR/$tdir
410         test_mkdir $DIR/$tdir/d2
411         touch $DIR/$tdir/d2/$tfile
412         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
413                 error "$tdir/d2/$tfile not a file"
414 }
415 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
416
417 test_11() {
418         test_mkdir $DIR/$tdir
419         test_mkdir $DIR/$tdir/d2
420         chmod 0666 $DIR/$tdir/d2
421         chmod 0705 $DIR/$tdir/d2
422         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
423                 error "$tdir/d2 mode not 0705"
424 }
425 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
426
427 test_12() {
428         test_mkdir $DIR/$tdir
429         touch $DIR/$tdir/$tfile
430         chmod 0666 $DIR/$tdir/$tfile
431         chmod 0654 $DIR/$tdir/$tfile
432         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
433                 error "$tdir/d2 mode not 0654"
434 }
435 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
436
437 test_13() {
438         test_mkdir $DIR/$tdir
439         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
440         >  $DIR/$tdir/$tfile
441         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
442                 error "$tdir/$tfile size not 0 after truncate"
443 }
444 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
445
446 test_14() {
447         test_mkdir $DIR/$tdir
448         touch $DIR/$tdir/$tfile
449         rm $DIR/$tdir/$tfile
450         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
451 }
452 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
453
454 test_15() {
455         test_mkdir $DIR/$tdir
456         touch $DIR/$tdir/$tfile
457         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
458         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
459                 error "$tdir/${tfile_2} not a file after rename"
460         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
461 }
462 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
463
464 test_16() {
465         test_mkdir $DIR/$tdir
466         touch $DIR/$tdir/$tfile
467         rm -rf $DIR/$tdir/$tfile
468         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
469 }
470 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
471
472 test_17a() {
473         test_mkdir $DIR/$tdir
474         touch $DIR/$tdir/$tfile
475         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
476         ls -l $DIR/$tdir
477         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
478                 error "$tdir/l-exist not a symlink"
479         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
480                 error "$tdir/l-exist not referencing a file"
481         rm -f $DIR/$tdir/l-exist
482         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
483 }
484 run_test 17a "symlinks: create, remove (real)"
485
486 test_17b() {
487         test_mkdir $DIR/$tdir
488         ln -s no-such-file $DIR/$tdir/l-dangle
489         ls -l $DIR/$tdir
490         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
491                 error "$tdir/l-dangle not referencing no-such-file"
492         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
493                 error "$tdir/l-dangle not referencing non-existent file"
494         rm -f $DIR/$tdir/l-dangle
495         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
496 }
497 run_test 17b "symlinks: create, remove (dangling)"
498
499 test_17c() { # bug 3440 - don't save failed open RPC for replay
500         test_mkdir $DIR/$tdir
501         ln -s foo $DIR/$tdir/$tfile
502         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
503 }
504 run_test 17c "symlinks: open dangling (should return error)"
505
506 test_17d() {
507         test_mkdir $DIR/$tdir
508         ln -s foo $DIR/$tdir/$tfile
509         touch $DIR/$tdir/$tfile || error "creating to new symlink"
510 }
511 run_test 17d "symlinks: create dangling"
512
513 test_17e() {
514         test_mkdir $DIR/$tdir
515         local foo=$DIR/$tdir/$tfile
516         ln -s $foo $foo || error "create symlink failed"
517         ls -l $foo || error "ls -l failed"
518         ls $foo && error "ls not failed" || true
519 }
520 run_test 17e "symlinks: create recursive symlink (should return error)"
521
522 test_17f() {
523         test_mkdir $DIR/$tdir
524         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
525         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
526         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
527         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
528         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
529         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890/aaaaaaaaaa/bbbbbbbbbb/cccccccccc/dddddddddd/eeeeeeeeee/ffffffffff/ $DIR/$tdir/666
530         ls -l  $DIR/$tdir
531 }
532 run_test 17f "symlinks: long and very long symlink name"
533
534 # str_repeat(S, N) generate a string that is string S repeated N times
535 str_repeat() {
536         local s=$1
537         local n=$2
538         local ret=''
539         while [ $((n -= 1)) -ge 0 ]; do
540                 ret=$ret$s
541         done
542         echo $ret
543 }
544
545 # Long symlinks and LU-2241
546 test_17g() {
547         test_mkdir $DIR/$tdir
548         local TESTS="59 60 61 4094 4095"
549
550         # Fix for inode size boundary in 2.1.4
551         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
552                 TESTS="4094 4095"
553
554         # Patch not applied to 2.2 or 2.3 branches
555         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
556         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
557                 TESTS="4094 4095"
558
559         for i in $TESTS; do
560                 local SYMNAME=$(str_repeat 'x' $i)
561                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
562                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
563         done
564 }
565 run_test 17g "symlinks: really long symlink name and inode boundaries"
566
567 test_17h() { #bug 17378
568         [ $PARALLEL == "yes" ] && skip "skip parallel run"
569         remote_mds_nodsh && skip "remote MDS with nodsh"
570
571         local mdt_idx
572
573         test_mkdir $DIR/$tdir
574         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
575         $LFS setstripe -c -1 $DIR/$tdir
576         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
577         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
578         touch $DIR/$tdir/$tfile || true
579 }
580 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
581
582 test_17i() { #bug 20018
583         [ $PARALLEL == "yes" ] && skip "skip parallel run"
584         remote_mds_nodsh && skip "remote MDS with nodsh"
585
586         local foo=$DIR/$tdir/$tfile
587         local mdt_idx
588
589         test_mkdir -c1 $DIR/$tdir
590         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
591         ln -s $foo $foo || error "create symlink failed"
592 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
593         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
594         ls -l $foo && error "error not detected"
595         return 0
596 }
597 run_test 17i "don't panic on short symlink (should return error)"
598
599 test_17k() { #bug 22301
600         [ $PARALLEL == "yes" ] && skip "skip parallel run"
601         [[ -z "$(which rsync 2>/dev/null)" ]] &&
602                 skip "no rsync command"
603         rsync --help | grep -q xattr ||
604                 skip_env "$(rsync --version | head -n1) does not support xattrs"
605         test_mkdir $DIR/$tdir
606         test_mkdir $DIR/$tdir.new
607         touch $DIR/$tdir/$tfile
608         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
609         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
610                 error "rsync failed with xattrs enabled"
611 }
612 run_test 17k "symlinks: rsync with xattrs enabled"
613
614 test_17l() { # LU-279
615         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
616                 skip "no getfattr command"
617
618         test_mkdir $DIR/$tdir
619         touch $DIR/$tdir/$tfile
620         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
621         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
622                 # -h to not follow symlinks. -m '' to list all the xattrs.
623                 # grep to remove first line: '# file: $path'.
624                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
625                 do
626                         lgetxattr_size_check $path $xattr ||
627                                 error "lgetxattr_size_check $path $xattr failed"
628                 done
629         done
630 }
631 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
632
633 # LU-1540
634 test_17m() {
635         [ $PARALLEL == "yes" ] && skip "skip parallel run"
636         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
637         remote_mds_nodsh && skip "remote MDS with nodsh"
638         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
639         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
640                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
641
642         local short_sym="0123456789"
643         local wdir=$DIR/$tdir
644         local i
645
646         test_mkdir $wdir
647         long_sym=$short_sym
648         # create a long symlink file
649         for ((i = 0; i < 4; ++i)); do
650                 long_sym=${long_sym}${long_sym}
651         done
652
653         echo "create 512 short and long symlink files under $wdir"
654         for ((i = 0; i < 256; ++i)); do
655                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
656                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
657         done
658
659         echo "erase them"
660         rm -f $wdir/*
661         sync
662         wait_delete_completed
663
664         echo "recreate the 512 symlink files with a shorter string"
665         for ((i = 0; i < 512; ++i)); do
666                 # rewrite the symlink file with a shorter string
667                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
668                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
669         done
670
671         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
672         local devname=$(mdsdevname $mds_index)
673
674         echo "stop and checking mds${mds_index}:"
675         # e2fsck should not return error
676         stop mds${mds_index}
677         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
678         rc=$?
679
680         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
681                 error "start mds${mds_index} failed"
682         df $MOUNT > /dev/null 2>&1
683         [ $rc -eq 0 ] ||
684                 error "e2fsck detected error for short/long symlink: rc=$rc"
685         rm -f $wdir/*
686 }
687 run_test 17m "run e2fsck against MDT which contains short/long symlink"
688
689 check_fs_consistency_17n() {
690         local mdt_index
691         local rc=0
692
693         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
694         # so it only check MDT1/MDT2 instead of all of MDTs.
695         for mdt_index in 1 2; do
696                 local devname=$(mdsdevname $mdt_index)
697                 # e2fsck should not return error
698                 stop mds${mdt_index}
699                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
700                         rc=$((rc + $?))
701
702                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
703                         error "mount mds$mdt_index failed"
704                 df $MOUNT > /dev/null 2>&1
705         done
706         return $rc
707 }
708
709 test_17n() {
710         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
711         [ $PARALLEL == "yes" ] && skip "skip parallel run"
712         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
713         remote_mds_nodsh && skip "remote MDS with nodsh"
714         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
715         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
716                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
717
718         local i
719
720         test_mkdir $DIR/$tdir
721         for ((i=0; i<10; i++)); do
722                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
723                         error "create remote dir error $i"
724                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
725                         error "create files under remote dir failed $i"
726         done
727
728         check_fs_consistency_17n ||
729                 error "e2fsck report error after create files under remote dir"
730
731         for ((i = 0; i < 10; i++)); do
732                 rm -rf $DIR/$tdir/remote_dir_${i} ||
733                         error "destroy remote dir error $i"
734         done
735
736         check_fs_consistency_17n ||
737                 error "e2fsck report error after unlink files under remote dir"
738
739         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
740                 skip "lustre < 2.4.50 does not support migrate mv"
741
742         for ((i = 0; i < 10; i++)); do
743                 mkdir -p $DIR/$tdir/remote_dir_${i}
744                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
745                         error "create files under remote dir failed $i"
746                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
747                         error "migrate remote dir error $i"
748         done
749         check_fs_consistency_17n || error "e2fsck report error after migration"
750
751         for ((i = 0; i < 10; i++)); do
752                 rm -rf $DIR/$tdir/remote_dir_${i} ||
753                         error "destroy remote dir error $i"
754         done
755
756         check_fs_consistency_17n || error "e2fsck report error after unlink"
757 }
758 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
759
760 test_17o() {
761         remote_mds_nodsh && skip "remote MDS with nodsh"
762         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
763                 skip "Need MDS version at least 2.3.64"
764
765         local wdir=$DIR/${tdir}o
766         local mdt_index
767         local rc=0
768
769         test_mkdir $wdir
770         touch $wdir/$tfile
771         mdt_index=$($LFS getstripe -m $wdir/$tfile)
772         mdt_index=$((mdt_index + 1))
773
774         cancel_lru_locks mdc
775         #fail mds will wait the failover finish then set
776         #following fail_loc to avoid interfer the recovery process.
777         fail mds${mdt_index}
778
779         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
780         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
781         ls -l $wdir/$tfile && rc=1
782         do_facet mds${mdt_index} lctl set_param fail_loc=0
783         [[ $rc -eq 0 ]] || error "stat file should fail"
784 }
785 run_test 17o "stat file with incompat LMA feature"
786
787 test_18() {
788         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
789         ls $DIR || error "Failed to ls $DIR: $?"
790 }
791 run_test 18 "touch .../f ; ls ... =============================="
792
793 test_19a() {
794         touch $DIR/$tfile
795         ls -l $DIR
796         rm $DIR/$tfile
797         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
798 }
799 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
800
801 test_19b() {
802         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
803 }
804 run_test 19b "ls -l .../f19 (should return error) =============="
805
806 test_19c() {
807         [ $RUNAS_ID -eq $UID ] &&
808                 skip_env "RUNAS_ID = UID = $UID -- skipping"
809
810         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
811 }
812 run_test 19c "$RUNAS touch .../f19 (should return error) =="
813
814 test_19d() {
815         cat $DIR/f19 && error || true
816 }
817 run_test 19d "cat .../f19 (should return error) =============="
818
819 test_20() {
820         touch $DIR/$tfile
821         rm $DIR/$tfile
822         touch $DIR/$tfile
823         rm $DIR/$tfile
824         touch $DIR/$tfile
825         rm $DIR/$tfile
826         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
827 }
828 run_test 20 "touch .../f ; ls -l ..."
829
830 test_21() {
831         test_mkdir $DIR/$tdir
832         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
833         ln -s dangle $DIR/$tdir/link
834         echo foo >> $DIR/$tdir/link
835         cat $DIR/$tdir/dangle
836         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
837         $CHECKSTAT -f -t file $DIR/$tdir/link ||
838                 error "$tdir/link not linked to a file"
839 }
840 run_test 21 "write to dangling link"
841
842 test_22() {
843         local wdir=$DIR/$tdir
844         test_mkdir $wdir
845         chown $RUNAS_ID:$RUNAS_GID $wdir
846         (cd $wdir || error "cd $wdir failed";
847                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
848                 $RUNAS tar xf -)
849         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
850         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
851         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
852                 error "checkstat -u failed"
853 }
854 run_test 22 "unpack tar archive as non-root user"
855
856 # was test_23
857 test_23a() {
858         test_mkdir $DIR/$tdir
859         local file=$DIR/$tdir/$tfile
860
861         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
862         openfile -f O_CREAT:O_EXCL $file &&
863                 error "$file recreate succeeded" || true
864 }
865 run_test 23a "O_CREAT|O_EXCL in subdir"
866
867 test_23b() { # bug 18988
868         test_mkdir $DIR/$tdir
869         local file=$DIR/$tdir/$tfile
870
871         rm -f $file
872         echo foo > $file || error "write filed"
873         echo bar >> $file || error "append filed"
874         $CHECKSTAT -s 8 $file || error "wrong size"
875         rm $file
876 }
877 run_test 23b "O_APPEND check"
878
879 # LU-9409, size with O_APPEND and tiny writes
880 test_23c() {
881         local file=$DIR/$tfile
882
883         # single dd
884         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
885         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
886         rm -f $file
887
888         # racing tiny writes
889         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
890         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
891         wait
892         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
893         rm -f $file
894
895         #racing tiny & normal writes
896         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
897         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
898         wait
899         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
900         rm -f $file
901
902         #racing tiny & normal writes 2, ugly numbers
903         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
904         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
905         wait
906         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
907         rm -f $file
908 }
909 run_test 23c "O_APPEND size checks for tiny writes"
910
911 # LU-11069 file offset is correct after appending writes
912 test_23d() {
913         local file=$DIR/$tfile
914         local offset
915
916         echo CentaurHauls > $file
917         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
918         if ((offset != 26)); then
919                 error "wrong offset, expected 26, got '$offset'"
920         fi
921 }
922 run_test 23d "file offset is correct after appending writes"
923
924 # rename sanity
925 test_24a() {
926         echo '-- same directory rename'
927         test_mkdir $DIR/$tdir
928         touch $DIR/$tdir/$tfile.1
929         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
930         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
931 }
932 run_test 24a "rename file to non-existent target"
933
934 test_24b() {
935         test_mkdir $DIR/$tdir
936         touch $DIR/$tdir/$tfile.{1,2}
937         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
938         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
939         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
940 }
941 run_test 24b "rename file to existing target"
942
943 test_24c() {
944         test_mkdir $DIR/$tdir
945         test_mkdir $DIR/$tdir/d$testnum.1
946         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
947         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
948         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
949 }
950 run_test 24c "rename directory to non-existent target"
951
952 test_24d() {
953         test_mkdir -c1 $DIR/$tdir
954         test_mkdir -c1 $DIR/$tdir/d$testnum.1
955         test_mkdir -c1 $DIR/$tdir/d$testnum.2
956         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
957         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
958         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
959 }
960 run_test 24d "rename directory to existing target"
961
962 test_24e() {
963         echo '-- cross directory renames --'
964         test_mkdir $DIR/R5a
965         test_mkdir $DIR/R5b
966         touch $DIR/R5a/f
967         mv $DIR/R5a/f $DIR/R5b/g
968         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
969         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
970 }
971 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
972
973 test_24f() {
974         test_mkdir $DIR/R6a
975         test_mkdir $DIR/R6b
976         touch $DIR/R6a/f $DIR/R6b/g
977         mv $DIR/R6a/f $DIR/R6b/g
978         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
979         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
980 }
981 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
982
983 test_24g() {
984         test_mkdir $DIR/R7a
985         test_mkdir $DIR/R7b
986         test_mkdir $DIR/R7a/d
987         mv $DIR/R7a/d $DIR/R7b/e
988         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
989         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
990 }
991 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
992
993 test_24h() {
994         test_mkdir -c1 $DIR/R8a
995         test_mkdir -c1 $DIR/R8b
996         test_mkdir -c1 $DIR/R8a/d
997         test_mkdir -c1 $DIR/R8b/e
998         mrename $DIR/R8a/d $DIR/R8b/e
999         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1000         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1001 }
1002 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1003
1004 test_24i() {
1005         echo "-- rename error cases"
1006         test_mkdir $DIR/R9
1007         test_mkdir $DIR/R9/a
1008         touch $DIR/R9/f
1009         mrename $DIR/R9/f $DIR/R9/a
1010         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1011         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1012         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1013 }
1014 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1015
1016 test_24j() {
1017         test_mkdir $DIR/R10
1018         mrename $DIR/R10/f $DIR/R10/g
1019         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1020         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1021         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1022 }
1023 run_test 24j "source does not exist ============================"
1024
1025 test_24k() {
1026         test_mkdir $DIR/R11a
1027         test_mkdir $DIR/R11a/d
1028         touch $DIR/R11a/f
1029         mv $DIR/R11a/f $DIR/R11a/d
1030         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1031         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1032 }
1033 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1034
1035 # bug 2429 - rename foo foo foo creates invalid file
1036 test_24l() {
1037         f="$DIR/f24l"
1038         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1039 }
1040 run_test 24l "Renaming a file to itself ========================"
1041
1042 test_24m() {
1043         f="$DIR/f24m"
1044         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1045         # on ext3 this does not remove either the source or target files
1046         # though the "expected" operation would be to remove the source
1047         $CHECKSTAT -t file ${f} || error "${f} missing"
1048         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1049 }
1050 run_test 24m "Renaming a file to a hard link to itself ========="
1051
1052 test_24n() {
1053     f="$DIR/f24n"
1054     # this stats the old file after it was renamed, so it should fail
1055     touch ${f}
1056     $CHECKSTAT ${f} || error "${f} missing"
1057     mv ${f} ${f}.rename
1058     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1059     $CHECKSTAT -a ${f} || error "${f} exists"
1060 }
1061 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1062
1063 test_24o() {
1064         test_mkdir $DIR/$tdir
1065         rename_many -s random -v -n 10 $DIR/$tdir
1066 }
1067 run_test 24o "rename of files during htree split"
1068
1069 test_24p() {
1070         test_mkdir $DIR/R12a
1071         test_mkdir $DIR/R12b
1072         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1073         mrename $DIR/R12a $DIR/R12b
1074         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1075         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1076         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1077         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1078 }
1079 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1080
1081 cleanup_multiop_pause() {
1082         trap 0
1083         kill -USR1 $MULTIPID
1084 }
1085
1086 test_24q() {
1087         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1088
1089         test_mkdir $DIR/R13a
1090         test_mkdir $DIR/R13b
1091         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1092         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1093         MULTIPID=$!
1094
1095         trap cleanup_multiop_pause EXIT
1096         mrename $DIR/R13a $DIR/R13b
1097         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1098         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1099         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1100         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1101         cleanup_multiop_pause
1102         wait $MULTIPID || error "multiop close failed"
1103 }
1104 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1105
1106 test_24r() { #bug 3789
1107         test_mkdir $DIR/R14a
1108         test_mkdir $DIR/R14a/b
1109         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1110         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1111         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1112 }
1113 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1114
1115 test_24s() {
1116         test_mkdir $DIR/R15a
1117         test_mkdir $DIR/R15a/b
1118         test_mkdir $DIR/R15a/b/c
1119         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1120         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1121         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1122 }
1123 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1124 test_24t() {
1125         test_mkdir $DIR/R16a
1126         test_mkdir $DIR/R16a/b
1127         test_mkdir $DIR/R16a/b/c
1128         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1129         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1130         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1131 }
1132 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1133
1134 test_24u() { # bug12192
1135         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1136         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1137 }
1138 run_test 24u "create stripe file"
1139
1140 simple_cleanup_common() {
1141         local rc=0
1142         trap 0
1143         [ -z "$DIR" ] || [ -z "$tdir" ] && return 0
1144
1145         local start=$SECONDS
1146         rm -rf $DIR/$tdir
1147         rc=$?
1148         wait_delete_completed
1149         echo "cleanup time $((SECONDS - start))"
1150         return $rc
1151 }
1152
1153 max_pages_per_rpc() {
1154         local mdtname="$(printf "MDT%04x" ${1:-0})"
1155         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1156 }
1157
1158 test_24v() {
1159         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1160
1161         local nrfiles=${COUNT:-100000}
1162         local fname="$DIR/$tdir/$tfile"
1163
1164         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1165         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1166
1167         test_mkdir "$(dirname $fname)"
1168         # assume MDT0000 has the fewest inodes
1169         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1170         local free_inodes=$(($(mdt_free_inodes 0) * stripes))
1171         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1172
1173         trap simple_cleanup_common EXIT
1174
1175         createmany -m "$fname" $nrfiles
1176
1177         cancel_lru_locks mdc
1178         lctl set_param mdc.*.stats clear
1179
1180         # was previously test_24D: LU-6101
1181         # readdir() returns correct number of entries after cursor reload
1182         local num_ls=$(ls $DIR/$tdir | wc -l)
1183         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1184         local num_all=$(ls -a $DIR/$tdir | wc -l)
1185         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1186                 [ $num_all -ne $((nrfiles + 2)) ]; then
1187                         error "Expected $nrfiles files, got $num_ls " \
1188                                 "($num_uniq unique $num_all .&..)"
1189         fi
1190         # LU-5 large readdir
1191         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1192         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1193         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1194         # take into account of overhead in lu_dirpage header and end mark in
1195         # each page, plus one in rpc_num calculation.
1196         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1197         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1198         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1199         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1200         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1201         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1202         echo "readpages: $mds_readpage rpc_max: $rpc_max"
1203         (( $mds_readpage < $rpc_max - 2 || $mds_readpage > $rpc_max + 1)) &&
1204                 error "large readdir doesn't take effect: " \
1205                       "$mds_readpage should be about $rpc_max"
1206
1207         simple_cleanup_common
1208 }
1209 run_test 24v "list large directory (test hash collision, b=17560)"
1210
1211 test_24w() { # bug21506
1212         SZ1=234852
1213         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1214         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1215         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1216         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1217         [[ "$SZ1" -eq "$SZ2" ]] ||
1218                 error "Error reading at the end of the file $tfile"
1219 }
1220 run_test 24w "Reading a file larger than 4Gb"
1221
1222 test_24x() {
1223         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1224         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1225         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1226                 skip "Need MDS version at least 2.7.56"
1227
1228         local MDTIDX=1
1229         local remote_dir=$DIR/$tdir/remote_dir
1230
1231         test_mkdir $DIR/$tdir
1232         $LFS mkdir -i $MDTIDX $remote_dir ||
1233                 error "create remote directory failed"
1234
1235         test_mkdir $DIR/$tdir/src_dir
1236         touch $DIR/$tdir/src_file
1237         test_mkdir $remote_dir/tgt_dir
1238         touch $remote_dir/tgt_file
1239
1240         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1241                 error "rename dir cross MDT failed!"
1242
1243         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1244                 error "rename file cross MDT failed!"
1245
1246         touch $DIR/$tdir/ln_file
1247         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1248                 error "ln file cross MDT failed"
1249
1250         rm -rf $DIR/$tdir || error "Can not delete directories"
1251 }
1252 run_test 24x "cross MDT rename/link"
1253
1254 test_24y() {
1255         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1256         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1257
1258         local remote_dir=$DIR/$tdir/remote_dir
1259         local mdtidx=1
1260
1261         test_mkdir $DIR/$tdir
1262         $LFS mkdir -i $mdtidx $remote_dir ||
1263                 error "create remote directory failed"
1264
1265         test_mkdir $remote_dir/src_dir
1266         touch $remote_dir/src_file
1267         test_mkdir $remote_dir/tgt_dir
1268         touch $remote_dir/tgt_file
1269
1270         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1271                 error "rename subdir in the same remote dir failed!"
1272
1273         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1274                 error "rename files in the same remote dir failed!"
1275
1276         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1277                 error "link files in the same remote dir failed!"
1278
1279         rm -rf $DIR/$tdir || error "Can not delete directories"
1280 }
1281 run_test 24y "rename/link on the same dir should succeed"
1282
1283 test_24z() {
1284         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1285         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1286                 skip "Need MDS version at least 2.12.51"
1287
1288         local index
1289
1290         for index in 0 1; do
1291                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1292                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1293         done
1294
1295         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1296
1297         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1298         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1299
1300         local mdts=$(comma_list $(mdts_nodes))
1301
1302         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1303         stack_trap "do_nodes $mdts $LCTL \
1304                 set_param mdt.*.enable_remote_rename=1" EXIT
1305
1306         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1307
1308         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1309         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1310 }
1311 run_test 24z "cross-MDT rename is done as cp"
1312
1313 test_24A() { # LU-3182
1314         local NFILES=5000
1315
1316         rm -rf $DIR/$tdir
1317         test_mkdir $DIR/$tdir
1318         trap simple_cleanup_common EXIT
1319         createmany -m $DIR/$tdir/$tfile $NFILES
1320         local t=$(ls $DIR/$tdir | wc -l)
1321         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1322         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1323         if [ $t -ne $NFILES ] || [ $u -ne $NFILES ] ||
1324            [ $v -ne $((NFILES + 2)) ] ; then
1325                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1326         fi
1327
1328         simple_cleanup_common || error "Can not delete directories"
1329 }
1330 run_test 24A "readdir() returns correct number of entries."
1331
1332 test_24B() { # LU-4805
1333         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1334
1335         local count
1336
1337         test_mkdir $DIR/$tdir
1338         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1339                 error "create striped dir failed"
1340
1341         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1342         [ $count -eq 2 ] || error "Expected 2, got $count"
1343
1344         touch $DIR/$tdir/striped_dir/a
1345
1346         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1347         [ $count -eq 3 ] || error "Expected 3, got $count"
1348
1349         touch $DIR/$tdir/striped_dir/.f
1350
1351         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1352         [ $count -eq 4 ] || error "Expected 4, got $count"
1353
1354         rm -rf $DIR/$tdir || error "Can not delete directories"
1355 }
1356 run_test 24B "readdir for striped dir return correct number of entries"
1357
1358 test_24C() {
1359         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1360
1361         mkdir $DIR/$tdir
1362         mkdir $DIR/$tdir/d0
1363         mkdir $DIR/$tdir/d1
1364
1365         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1366                 error "create striped dir failed"
1367
1368         cd $DIR/$tdir/d0/striped_dir
1369
1370         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1371         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1372         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1373
1374         [ "$d0_ino" = "$parent_ino" ] ||
1375                 error ".. wrong, expect $d0_ino, get $parent_ino"
1376
1377         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1378                 error "mv striped dir failed"
1379
1380         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1381
1382         [ "$d1_ino" = "$parent_ino" ] ||
1383                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1384 }
1385 run_test 24C "check .. in striped dir"
1386
1387 test_24E() {
1388         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1389         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1390
1391         mkdir -p $DIR/$tdir
1392         mkdir $DIR/$tdir/src_dir
1393         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1394                 error "create remote source failed"
1395
1396         touch $DIR/$tdir/src_dir/src_child/a
1397
1398         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1399                 error "create remote target dir failed"
1400
1401         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1402                 error "create remote target child failed"
1403
1404         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1405                 error "rename dir cross MDT failed!"
1406
1407         find $DIR/$tdir
1408
1409         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1410                 error "src_child still exists after rename"
1411
1412         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1413                 error "missing file(a) after rename"
1414
1415         rm -rf $DIR/$tdir || error "Can not delete directories"
1416 }
1417 run_test 24E "cross MDT rename/link"
1418
1419 test_24F () {
1420         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1421
1422         local repeats=1000
1423         [ "$SLOW" = "no" ] && repeats=100
1424
1425         mkdir -p $DIR/$tdir
1426
1427         echo "$repeats repeats"
1428         for ((i = 0; i < repeats; i++)); do
1429                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1430                 touch $DIR/$tdir/test/a || error "touch fails"
1431                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1432                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1433         done
1434
1435         true
1436 }
1437 run_test 24F "hash order vs readdir (LU-11330)"
1438
1439 test_25a() {
1440         echo '== symlink sanity ============================================='
1441
1442         test_mkdir $DIR/d25
1443         ln -s d25 $DIR/s25
1444         touch $DIR/s25/foo ||
1445                 error "File creation in symlinked directory failed"
1446 }
1447 run_test 25a "create file in symlinked directory ==============="
1448
1449 test_25b() {
1450         [ ! -d $DIR/d25 ] && test_25a
1451         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1452 }
1453 run_test 25b "lookup file in symlinked directory ==============="
1454
1455 test_26a() {
1456         test_mkdir $DIR/d26
1457         test_mkdir $DIR/d26/d26-2
1458         ln -s d26/d26-2 $DIR/s26
1459         touch $DIR/s26/foo || error "File creation failed"
1460 }
1461 run_test 26a "multiple component symlink ======================="
1462
1463 test_26b() {
1464         test_mkdir -p $DIR/$tdir/d26-2
1465         ln -s $tdir/d26-2/foo $DIR/s26-2
1466         touch $DIR/s26-2 || error "File creation failed"
1467 }
1468 run_test 26b "multiple component symlink at end of lookup ======"
1469
1470 test_26c() {
1471         test_mkdir $DIR/d26.2
1472         touch $DIR/d26.2/foo
1473         ln -s d26.2 $DIR/s26.2-1
1474         ln -s s26.2-1 $DIR/s26.2-2
1475         ln -s s26.2-2 $DIR/s26.2-3
1476         chmod 0666 $DIR/s26.2-3/foo
1477 }
1478 run_test 26c "chain of symlinks"
1479
1480 # recursive symlinks (bug 439)
1481 test_26d() {
1482         ln -s d26-3/foo $DIR/d26-3
1483 }
1484 run_test 26d "create multiple component recursive symlink"
1485
1486 test_26e() {
1487         [ ! -h $DIR/d26-3 ] && test_26d
1488         rm $DIR/d26-3
1489 }
1490 run_test 26e "unlink multiple component recursive symlink"
1491
1492 # recursive symlinks (bug 7022)
1493 test_26f() {
1494         test_mkdir $DIR/$tdir
1495         test_mkdir $DIR/$tdir/$tfile
1496         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1497         test_mkdir -p lndir/bar1
1498         test_mkdir $DIR/$tdir/$tfile/$tfile
1499         cd $tfile                || error "cd $tfile failed"
1500         ln -s .. dotdot          || error "ln dotdot failed"
1501         ln -s dotdot/lndir lndir || error "ln lndir failed"
1502         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1503         output=`ls $tfile/$tfile/lndir/bar1`
1504         [ "$output" = bar1 ] && error "unexpected output"
1505         rm -r $tfile             || error "rm $tfile failed"
1506         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1507 }
1508 run_test 26f "rm -r of a directory which has recursive symlink"
1509
1510 test_27a() {
1511         test_mkdir $DIR/$tdir
1512         $LFS getstripe $DIR/$tdir
1513         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1514         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1515         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1516 }
1517 run_test 27a "one stripe file"
1518
1519 test_27b() {
1520         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1521
1522         test_mkdir $DIR/$tdir
1523         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1524         $LFS getstripe -c $DIR/$tdir/$tfile
1525         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1526                 error "two-stripe file doesn't have two stripes"
1527
1528         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1529 }
1530 run_test 27b "create and write to two stripe file"
1531
1532 # 27c family tests specific striping, setstripe -o
1533 test_27ca() {
1534         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1535         test_mkdir -p $DIR/$tdir
1536         local osts="1"
1537
1538         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1539         $LFS getstripe -i $DIR/$tdir/$tfile
1540         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1541                 error "stripe not on specified OST"
1542
1543         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1544 }
1545 run_test 27ca "one stripe on specified OST"
1546
1547 test_27cb() {
1548         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1549         test_mkdir -p $DIR/$tdir
1550         local osts="1,0"
1551         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1552         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1553         echo "$getstripe"
1554
1555         # Strip getstripe output to a space separated list of OSTs
1556         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1557                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1558         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1559                 error "stripes not on specified OSTs"
1560
1561         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1562 }
1563 run_test 27cb "two stripes on specified OSTs"
1564
1565 test_27cc() {
1566         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1567         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1568                 skip "server does not support overstriping"
1569
1570         test_mkdir -p $DIR/$tdir
1571         local osts="0,0"
1572         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1573         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1574         echo "$getstripe"
1575
1576         # Strip getstripe output to a space separated list of OSTs
1577         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1578                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1579         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1580                 error "stripes not on specified OSTs"
1581
1582         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1583 }
1584 run_test 27cc "two stripes on the same OST"
1585
1586 test_27cd() {
1587         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1588         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1589                 skip "server does not support overstriping"
1590         test_mkdir -p $DIR/$tdir
1591         local osts="0,1,1,0"
1592         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1593         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1594         echo "$getstripe"
1595
1596         # Strip getstripe output to a space separated list of OSTs
1597         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1598                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1599         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1600                 error "stripes not on specified OSTs"
1601
1602         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1603 }
1604 run_test 27cd "four stripes on two OSTs"
1605
1606 test_27ce() {
1607         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1608                 skip_env "too many osts, skipping"
1609         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1610                 skip "server does not support overstriping"
1611         # We do one more stripe than we have OSTs
1612         [ $OSTCOUNT -ge 159 ] || large_xattr_enabled ||
1613                 skip_env "ea_inode feature disabled"
1614
1615         test_mkdir -p $DIR/$tdir
1616         local osts=""
1617         for i in $(seq 0 $OSTCOUNT);
1618         do
1619                 osts=$osts"0"
1620                 if [ $i -ne $OSTCOUNT ]; then
1621                         osts=$osts","
1622                 fi
1623         done
1624         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1625         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1626         echo "$getstripe"
1627
1628         # Strip getstripe output to a space separated list of OSTs
1629         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1630                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1631         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1632                 error "stripes not on specified OSTs"
1633
1634         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1635 }
1636 run_test 27ce "more stripes than OSTs with -o"
1637
1638 test_27d() {
1639         test_mkdir $DIR/$tdir
1640         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1641                 error "setstripe failed"
1642         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1643         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1644 }
1645 run_test 27d "create file with default settings"
1646
1647 test_27e() {
1648         # LU-5839 adds check for existed layout before setting it
1649         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1650                 skip "Need MDS version at least 2.7.56"
1651
1652         test_mkdir $DIR/$tdir
1653         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1654         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1655         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1656 }
1657 run_test 27e "setstripe existing file (should return error)"
1658
1659 test_27f() {
1660         test_mkdir $DIR/$tdir
1661         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1662                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1663         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1664                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1665         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1666         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1667 }
1668 run_test 27f "setstripe with bad stripe size (should return error)"
1669
1670 test_27g() {
1671         test_mkdir $DIR/$tdir
1672         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1673         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1674                 error "$DIR/$tdir/$tfile has object"
1675 }
1676 run_test 27g "$LFS getstripe with no objects"
1677
1678 test_27ga() {
1679         test_mkdir $DIR/$tdir
1680         touch $DIR/$tdir/$tfile || error "touch failed"
1681         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1682         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1683         local rc=$?
1684         (( rc == 2 )) || error "getstripe did not return ENOENT"
1685 }
1686 run_test 27ga "$LFS getstripe with missing file (should return error)"
1687
1688 test_27i() {
1689         test_mkdir $DIR/$tdir
1690         touch $DIR/$tdir/$tfile || error "touch failed"
1691         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1692                 error "missing objects"
1693 }
1694 run_test 27i "$LFS getstripe with some objects"
1695
1696 test_27j() {
1697         test_mkdir $DIR/$tdir
1698         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1699                 error "setstripe failed" || true
1700 }
1701 run_test 27j "setstripe with bad stripe offset (should return error)"
1702
1703 test_27k() { # bug 2844
1704         test_mkdir $DIR/$tdir
1705         local file=$DIR/$tdir/$tfile
1706         local ll_max_blksize=$((4 * 1024 * 1024))
1707         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1708         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1709         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1710         dd if=/dev/zero of=$file bs=4k count=1
1711         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1712         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1713 }
1714 run_test 27k "limit i_blksize for broken user apps"
1715
1716 test_27l() {
1717         mcreate $DIR/$tfile || error "creating file"
1718         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1719                 error "setstripe should have failed" || true
1720 }
1721 run_test 27l "check setstripe permissions (should return error)"
1722
1723 test_27m() {
1724         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1725
1726         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1727                 skip_env "multiple clients -- skipping"
1728
1729         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1730                    head -n1)
1731         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1732                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1733         fi
1734         trap simple_cleanup_common EXIT
1735         test_mkdir $DIR/$tdir
1736         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1737         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1738                 error "dd should fill OST0"
1739         i=2
1740         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1741                 i=$((i + 1))
1742                 [ $i -gt 256 ] && break
1743         done
1744         i=$((i + 1))
1745         touch $DIR/$tdir/$tfile.$i
1746         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1747             awk '{print $1}'| grep -w "0") ] &&
1748                 error "OST0 was full but new created file still use it"
1749         i=$((i + 1))
1750         touch $DIR/$tdir/$tfile.$i
1751         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1752             awk '{print $1}'| grep -w "0") ] &&
1753                 error "OST0 was full but new created file still use it"
1754         simple_cleanup_common
1755 }
1756 run_test 27m "create file while OST0 was full"
1757
1758 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1759 # if the OST isn't full anymore.
1760 reset_enospc() {
1761         local OSTIDX=${1:-""}
1762
1763         local list=$(comma_list $(osts_nodes))
1764         [ "$OSTIDX" ] && list=$(facet_host ost$((OSTIDX + 1)))
1765
1766         do_nodes $list lctl set_param fail_loc=0
1767         sync    # initiate all OST_DESTROYs from MDS to OST
1768         sleep_maxage
1769 }
1770
1771 exhaust_precreations() {
1772         local OSTIDX=$1
1773         local FAILLOC=$2
1774         local FAILIDX=${3:-$OSTIDX}
1775         local ofacet=ost$((OSTIDX + 1))
1776
1777         test_mkdir -p -c1 $DIR/$tdir
1778         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
1779         local mfacet=mds$((mdtidx + 1))
1780         echo OSTIDX=$OSTIDX MDTIDX=$mdtidx
1781
1782         local OST=$(ostname_from_index $OSTIDX)
1783
1784         # on the mdt's osc
1785         local mdtosc_proc1=$(get_mdtosc_proc_path $mfacet $OST)
1786         local last_id=$(do_facet $mfacet lctl get_param -n \
1787                         osp.$mdtosc_proc1.prealloc_last_id)
1788         local next_id=$(do_facet $mfacet lctl get_param -n \
1789                         osp.$mdtosc_proc1.prealloc_next_id)
1790
1791         local mdtosc_proc2=$(get_mdtosc_proc_path $mfacet)
1792         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1793
1794         test_mkdir -p $DIR/$tdir/${OST}
1795         $LFS setstripe -i $OSTIDX -c 1 $DIR/$tdir/${OST}
1796 #define OBD_FAIL_OST_ENOSPC              0x215
1797         do_facet $ofacet lctl set_param fail_val=$FAILIDX fail_loc=0x215
1798         echo "Creating to objid $last_id on ost $OST..."
1799         createmany -o $DIR/$tdir/${OST}/f $next_id $((last_id - next_id + 2))
1800         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1801         do_facet $ofacet lctl set_param fail_loc=$FAILLOC
1802         sleep_maxage
1803 }
1804
1805 exhaust_all_precreations() {
1806         local i
1807         for (( i=0; i < OSTCOUNT; i++ )) ; do
1808                 exhaust_precreations $i $1 -1
1809         done
1810 }
1811
1812 test_27n() {
1813         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1814         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1815         remote_mds_nodsh && skip "remote MDS with nodsh"
1816         remote_ost_nodsh && skip "remote OST with nodsh"
1817
1818         reset_enospc
1819         rm -f $DIR/$tdir/$tfile
1820         exhaust_precreations 0 0x80000215
1821         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1822         touch $DIR/$tdir/$tfile || error "touch failed"
1823         $LFS getstripe $DIR/$tdir/$tfile
1824         reset_enospc
1825 }
1826 run_test 27n "create file with some full OSTs"
1827
1828 test_27o() {
1829         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1830         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1831         remote_mds_nodsh && skip "remote MDS with nodsh"
1832         remote_ost_nodsh && skip "remote OST with nodsh"
1833
1834         reset_enospc
1835         rm -f $DIR/$tdir/$tfile
1836         exhaust_all_precreations 0x215
1837
1838         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1839
1840         reset_enospc
1841         rm -rf $DIR/$tdir/*
1842 }
1843 run_test 27o "create file with all full OSTs (should error)"
1844
1845 test_27p() {
1846         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1847         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1848         remote_mds_nodsh && skip "remote MDS with nodsh"
1849         remote_ost_nodsh && skip "remote OST with nodsh"
1850
1851         reset_enospc
1852         rm -f $DIR/$tdir/$tfile
1853         test_mkdir $DIR/$tdir
1854
1855         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1856         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1857         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1858
1859         exhaust_precreations 0 0x80000215
1860         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1861         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1862         $LFS getstripe $DIR/$tdir/$tfile
1863
1864         reset_enospc
1865 }
1866 run_test 27p "append to a truncated file with some full OSTs"
1867
1868 test_27q() {
1869         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1870         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1871         remote_mds_nodsh && skip "remote MDS with nodsh"
1872         remote_ost_nodsh && skip "remote OST with nodsh"
1873
1874         reset_enospc
1875         rm -f $DIR/$tdir/$tfile
1876
1877         test_mkdir $DIR/$tdir
1878         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1879         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1880                 error "truncate $DIR/$tdir/$tfile failed"
1881         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1882
1883         exhaust_all_precreations 0x215
1884
1885         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1886         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1887
1888         reset_enospc
1889 }
1890 run_test 27q "append to truncated file with all OSTs full (should error)"
1891
1892 test_27r() {
1893         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1894         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1895         remote_mds_nodsh && skip "remote MDS with nodsh"
1896         remote_ost_nodsh && skip "remote OST with nodsh"
1897
1898         reset_enospc
1899         rm -f $DIR/$tdir/$tfile
1900         exhaust_precreations 0 0x80000215
1901
1902         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1903
1904         reset_enospc
1905 }
1906 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
1907
1908 test_27s() { # bug 10725
1909         test_mkdir $DIR/$tdir
1910         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
1911         local stripe_count=0
1912         [ $OSTCOUNT -eq 1 ] || stripe_count=2
1913         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
1914                 error "stripe width >= 2^32 succeeded" || true
1915
1916 }
1917 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
1918
1919 test_27t() { # bug 10864
1920         WDIR=$(pwd)
1921         WLFS=$(which lfs)
1922         cd $DIR
1923         touch $tfile
1924         $WLFS getstripe $tfile
1925         cd $WDIR
1926 }
1927 run_test 27t "check that utils parse path correctly"
1928
1929 test_27u() { # bug 4900
1930         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1931         remote_mds_nodsh && skip "remote MDS with nodsh"
1932
1933         local index
1934         local list=$(comma_list $(mdts_nodes))
1935
1936 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
1937         do_nodes $list $LCTL set_param fail_loc=0x139
1938         test_mkdir -p $DIR/$tdir
1939         trap simple_cleanup_common EXIT
1940         createmany -o $DIR/$tdir/t- 1000
1941         do_nodes $list $LCTL set_param fail_loc=0
1942
1943         TLOG=$TMP/$tfile.getstripe
1944         $LFS getstripe $DIR/$tdir > $TLOG
1945         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
1946         unlinkmany $DIR/$tdir/t- 1000
1947         trap 0
1948         [[ $OBJS -gt 0 ]] &&
1949                 error "$OBJS objects created on OST-0. See $TLOG" ||
1950                 rm -f $TLOG
1951 }
1952 run_test 27u "skip object creation on OSC w/o objects"
1953
1954 test_27v() { # bug 4900
1955         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1956         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1957         remote_mds_nodsh && skip "remote MDS with nodsh"
1958         remote_ost_nodsh && skip "remote OST with nodsh"
1959
1960         exhaust_all_precreations 0x215
1961         reset_enospc
1962
1963         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
1964
1965         touch $DIR/$tdir/$tfile
1966         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
1967         # all except ost1
1968         for (( i=1; i < OSTCOUNT; i++ )); do
1969                 do_facet ost$i lctl set_param fail_loc=0x705
1970         done
1971         local START=`date +%s`
1972         createmany -o $DIR/$tdir/$tfile 32
1973
1974         local FINISH=`date +%s`
1975         local TIMEOUT=`lctl get_param -n timeout`
1976         local PROCESS=$((FINISH - START))
1977         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
1978                error "$FINISH - $START >= $TIMEOUT / 2"
1979         sleep $((TIMEOUT / 2 - PROCESS))
1980         reset_enospc
1981 }
1982 run_test 27v "skip object creation on slow OST"
1983
1984 test_27w() { # bug 10997
1985         test_mkdir $DIR/$tdir
1986         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
1987         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
1988                 error "stripe size $size != 65536" || true
1989         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
1990                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
1991 }
1992 run_test 27w "check $LFS setstripe -S and getstrip -d options"
1993
1994 test_27wa() {
1995         [[ $OSTCOUNT -lt 2 ]] &&
1996                 skip_env "skipping multiple stripe count/offset test"
1997
1998         test_mkdir $DIR/$tdir
1999         for i in $(seq 1 $OSTCOUNT); do
2000                 offset=$((i - 1))
2001                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2002                         error "setstripe -c $i -i $offset failed"
2003                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2004                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2005                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2006                 [ $index -ne $offset ] &&
2007                         error "stripe offset $index != $offset" || true
2008         done
2009 }
2010 run_test 27wa "check $LFS setstripe -c -i options"
2011
2012 test_27x() {
2013         remote_ost_nodsh && skip "remote OST with nodsh"
2014         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2015         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2016
2017         OFFSET=$(($OSTCOUNT - 1))
2018         OSTIDX=0
2019         local OST=$(ostname_from_index $OSTIDX)
2020
2021         test_mkdir $DIR/$tdir
2022         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2023         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2024         sleep_maxage
2025         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2026         for i in $(seq 0 $OFFSET); do
2027                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2028                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2029                 error "OST0 was degraded but new created file still use it"
2030         done
2031         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2032 }
2033 run_test 27x "create files while OST0 is degraded"
2034
2035 test_27y() {
2036         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2037         remote_mds_nodsh && skip "remote MDS with nodsh"
2038         remote_ost_nodsh && skip "remote OST with nodsh"
2039         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2040
2041         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2042         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2043                 osp.$mdtosc.prealloc_last_id)
2044         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2045                 osp.$mdtosc.prealloc_next_id)
2046         local fcount=$((last_id - next_id))
2047         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2048         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2049
2050         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2051                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2052         local OST_DEACTIVE_IDX=-1
2053         local OSC
2054         local OSTIDX
2055         local OST
2056
2057         for OSC in $MDS_OSCS; do
2058                 OST=$(osc_to_ost $OSC)
2059                 OSTIDX=$(index_from_ostuuid $OST)
2060                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2061                         OST_DEACTIVE_IDX=$OSTIDX
2062                 fi
2063                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2064                         echo $OSC "is Deactivated:"
2065                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2066                 fi
2067         done
2068
2069         OSTIDX=$(index_from_ostuuid $OST)
2070         test_mkdir $DIR/$tdir
2071         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2072
2073         for OSC in $MDS_OSCS; do
2074                 OST=$(osc_to_ost $OSC)
2075                 OSTIDX=$(index_from_ostuuid $OST)
2076                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2077                         echo $OST "is degraded:"
2078                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2079                                                 obdfilter.$OST.degraded=1
2080                 fi
2081         done
2082
2083         sleep_maxage
2084         createmany -o $DIR/$tdir/$tfile $fcount
2085
2086         for OSC in $MDS_OSCS; do
2087                 OST=$(osc_to_ost $OSC)
2088                 OSTIDX=$(index_from_ostuuid $OST)
2089                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2090                         echo $OST "is recovered from degraded:"
2091                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2092                                                 obdfilter.$OST.degraded=0
2093                 else
2094                         do_facet $SINGLEMDS lctl --device %$OSC activate
2095                 fi
2096         done
2097
2098         # all osp devices get activated, hence -1 stripe count restored
2099         local stripe_count=0
2100
2101         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2102         # devices get activated.
2103         sleep_maxage
2104         $LFS setstripe -c -1 $DIR/$tfile
2105         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2106         rm -f $DIR/$tfile
2107         [ $stripe_count -ne $OSTCOUNT ] &&
2108                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2109         return 0
2110 }
2111 run_test 27y "create files while OST0 is degraded and the rest inactive"
2112
2113 check_seq_oid()
2114 {
2115         log "check file $1"
2116
2117         lmm_count=$($LFS getstripe -c $1)
2118         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2119         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2120
2121         local old_ifs="$IFS"
2122         IFS=$'[:]'
2123         fid=($($LFS path2fid $1))
2124         IFS="$old_ifs"
2125
2126         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2127         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2128
2129         # compare lmm_seq and lu_fid->f_seq
2130         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2131         # compare lmm_object_id and lu_fid->oid
2132         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2133
2134         # check the trusted.fid attribute of the OST objects of the file
2135         local have_obdidx=false
2136         local stripe_nr=0
2137         $LFS getstripe $1 | while read obdidx oid hex seq; do
2138                 # skip lines up to and including "obdidx"
2139                 [ -z "$obdidx" ] && break
2140                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2141                 $have_obdidx || continue
2142
2143                 local ost=$((obdidx + 1))
2144                 local dev=$(ostdevname $ost)
2145                 local oid_hex
2146
2147                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2148
2149                 seq=$(echo $seq | sed -e "s/^0x//g")
2150                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2151                         oid_hex=$(echo $oid)
2152                 else
2153                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2154                 fi
2155                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2156
2157                 local ff=""
2158                 #
2159                 # Don't unmount/remount the OSTs if we don't need to do that.
2160                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2161                 # update too, until that use mount/ll_decode_filter_fid/mount.
2162                 # Re-enable when debugfs will understand new filter_fid.
2163                 #
2164                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2165                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2166                                 $dev 2>/dev/null" | grep "parent=")
2167                 fi
2168                 if [ -z "$ff" ]; then
2169                         stop ost$ost
2170                         mount_fstype ost$ost
2171                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2172                                 $(facet_mntpt ost$ost)/$obj_file)
2173                         unmount_fstype ost$ost
2174                         start ost$ost $dev $OST_MOUNT_OPTS
2175                         clients_up
2176                 fi
2177
2178                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2179
2180                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2181
2182                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2183                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2184                 #
2185                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2186                 #       stripe_size=1048576 component_id=1 component_start=0 \
2187                 #       component_end=33554432
2188                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2189                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2190                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2191                 local ff_pstripe
2192                 if grep -q 'stripe=' <<<$ff; then
2193                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2194                 else
2195                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2196                         # into f_ver in this case.  See comment on ff_parent.
2197                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2198                 fi
2199
2200                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2201                 [ $ff_pseq = $lmm_seq ] ||
2202                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2203                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2204                 [ $ff_poid = $lmm_oid ] ||
2205                         error "FF parent OID $ff_poid != $lmm_oid"
2206                 (($ff_pstripe == $stripe_nr)) ||
2207                         error "FF stripe $ff_pstripe != $stripe_nr"
2208
2209                 stripe_nr=$((stripe_nr + 1))
2210                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2211                         continue
2212                 if grep -q 'stripe_count=' <<<$ff; then
2213                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2214                                             -e 's/ .*//' <<<$ff)
2215                         [ $lmm_count = $ff_scnt ] ||
2216                                 error "FF stripe count $lmm_count != $ff_scnt"
2217                 fi
2218         done
2219 }
2220
2221 test_27z() {
2222         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2223         remote_ost_nodsh && skip "remote OST with nodsh"
2224
2225         test_mkdir $DIR/$tdir
2226         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2227                 { error "setstripe -c -1 failed"; return 1; }
2228         # We need to send a write to every object to get parent FID info set.
2229         # This _should_ also work for setattr, but does not currently.
2230         # touch $DIR/$tdir/$tfile-1 ||
2231         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2232                 { error "dd $tfile-1 failed"; return 2; }
2233         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2234                 { error "setstripe -c -1 failed"; return 3; }
2235         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2236                 { error "dd $tfile-2 failed"; return 4; }
2237
2238         # make sure write RPCs have been sent to OSTs
2239         sync; sleep 5; sync
2240
2241         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2242         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2243 }
2244 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2245
2246 test_27A() { # b=19102
2247         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2248
2249         save_layout_restore_at_exit $MOUNT
2250         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2251         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2252                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2253         local default_size=$($LFS getstripe -S $MOUNT)
2254         local default_offset=$($LFS getstripe -i $MOUNT)
2255         local dsize=$(do_facet $SINGLEMDS \
2256                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2257         [ $default_size -eq $dsize ] ||
2258                 error "stripe size $default_size != $dsize"
2259         [ $default_offset -eq -1 ] ||
2260                 error "stripe offset $default_offset != -1"
2261 }
2262 run_test 27A "check filesystem-wide default LOV EA values"
2263
2264 test_27B() { # LU-2523
2265         test_mkdir $DIR/$tdir
2266         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2267         touch $DIR/$tdir/f0
2268         # open f1 with O_LOV_DELAY_CREATE
2269         # rename f0 onto f1
2270         # call setstripe ioctl on open file descriptor for f1
2271         # close
2272         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2273                 $DIR/$tdir/f0
2274
2275         rm -f $DIR/$tdir/f1
2276         # open f1 with O_LOV_DELAY_CREATE
2277         # unlink f1
2278         # call setstripe ioctl on open file descriptor for f1
2279         # close
2280         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2281
2282         # Allow multiop to fail in imitation of NFS's busted semantics.
2283         true
2284 }
2285 run_test 27B "call setstripe on open unlinked file/rename victim"
2286
2287 # 27C family tests full striping and overstriping
2288 test_27Ca() { #LU-2871
2289         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2290
2291         declare -a ost_idx
2292         local index
2293         local found
2294         local i
2295         local j
2296
2297         test_mkdir $DIR/$tdir
2298         cd $DIR/$tdir
2299         for i in $(seq 0 $((OSTCOUNT - 1))); do
2300                 # set stripe across all OSTs starting from OST$i
2301                 $LFS setstripe -i $i -c -1 $tfile$i
2302                 # get striping information
2303                 ost_idx=($($LFS getstripe $tfile$i |
2304                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2305                 echo ${ost_idx[@]}
2306
2307                 # check the layout
2308                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2309                         error "${#ost_idx[@]} != $OSTCOUNT"
2310
2311                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2312                         found=0
2313                         for j in $(echo ${ost_idx[@]}); do
2314                                 if [ $index -eq $j ]; then
2315                                         found=1
2316                                         break
2317                                 fi
2318                         done
2319                         [ $found = 1 ] ||
2320                                 error "Can not find $index in ${ost_idx[@]}"
2321                 done
2322         done
2323 }
2324 run_test 27Ca "check full striping across all OSTs"
2325
2326 test_27Cb() {
2327         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2328                 skip "server does not support overstriping"
2329         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2330                 skip_env "too many osts, skipping"
2331
2332         test_mkdir -p $DIR/$tdir
2333         local setcount=$(($OSTCOUNT * 2))
2334         [ $setcount -ge 160 ] || large_xattr_enabled ||
2335                 skip_env "ea_inode feature disabled"
2336
2337         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2338                 error "setstripe failed"
2339
2340         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2341         [ $count -eq $setcount ] ||
2342                 error "stripe count $count, should be $setcount"
2343
2344         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2345                 error "overstriped should be set in pattern"
2346
2347         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2348                 error "dd failed"
2349 }
2350 run_test 27Cb "more stripes than OSTs with -C"
2351
2352 test_27Cc() {
2353         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2354                 skip "server does not support overstriping"
2355         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2356
2357         test_mkdir -p $DIR/$tdir
2358         local setcount=$(($OSTCOUNT - 1))
2359
2360         [ $setcount -ge 160 ] || large_xattr_enabled ||
2361                 skip_env "ea_inode feature disabled"
2362
2363         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2364                 error "setstripe failed"
2365
2366         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2367         [ $count -eq $setcount ] ||
2368                 error "stripe count $count, should be $setcount"
2369
2370         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2371                 error "overstriped should not be set in pattern"
2372
2373         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2374                 error "dd failed"
2375 }
2376 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2377
2378 test_27Cd() {
2379         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2380                 skip "server does not support overstriping"
2381         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2382         large_xattr_enabled || skip_env "ea_inode feature disabled"
2383
2384         test_mkdir -p $DIR/$tdir
2385         local setcount=$LOV_MAX_STRIPE_COUNT
2386
2387         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2388                 error "setstripe failed"
2389
2390         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2391         [ $count -eq $setcount ] ||
2392                 error "stripe count $count, should be $setcount"
2393
2394         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2395                 error "overstriped should be set in pattern"
2396
2397         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2398                 error "dd failed"
2399
2400         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2401 }
2402 run_test 27Cd "test maximum stripe count"
2403
2404 test_27Ce() {
2405         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2406                 skip "server does not support overstriping"
2407         test_mkdir -p $DIR/$tdir
2408
2409         pool_add $TESTNAME || error "Pool creation failed"
2410         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2411
2412         local setcount=8
2413
2414         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2415                 error "setstripe failed"
2416
2417         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2418         [ $count -eq $setcount ] ||
2419                 error "stripe count $count, should be $setcount"
2420
2421         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2422                 error "overstriped should be set in pattern"
2423
2424         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2425                 error "dd failed"
2426
2427         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2428 }
2429 run_test 27Ce "test pool with overstriping"
2430
2431 test_27Cf() {
2432         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2433                 skip "server does not support overstriping"
2434         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2435                 skip_env "too many osts, skipping"
2436
2437         test_mkdir -p $DIR/$tdir
2438
2439         local setcount=$(($OSTCOUNT * 2))
2440         [ $setcount -ge 160 ] || large_xattr_enabled ||
2441                 skip_env "ea_inode feature disabled"
2442
2443         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2444                 error "setstripe failed"
2445
2446         echo 1 > $DIR/$tdir/$tfile
2447
2448         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2449         [ $count -eq $setcount ] ||
2450                 error "stripe count $count, should be $setcount"
2451
2452         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2453                 error "overstriped should be set in pattern"
2454
2455         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2456                 error "dd failed"
2457
2458         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2459 }
2460 run_test 27Cf "test default inheritance with overstriping"
2461
2462 test_27D() {
2463         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2464         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2465         remote_mds_nodsh && skip "remote MDS with nodsh"
2466
2467         local POOL=${POOL:-testpool}
2468         local first_ost=0
2469         local last_ost=$(($OSTCOUNT - 1))
2470         local ost_step=1
2471         local ost_list=$(seq $first_ost $ost_step $last_ost)
2472         local ost_range="$first_ost $last_ost $ost_step"
2473
2474         test_mkdir $DIR/$tdir
2475         pool_add $POOL || error "pool_add failed"
2476         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2477
2478         local skip27D
2479         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2480                 skip27D+="-s 29"
2481         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2482                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2483                         skip27D+=" -s 30,31"
2484         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2485           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2486                 skip27D+=" -s 32,33"
2487         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2488                 skip27D+=" -s 34"
2489         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2490                 error "llapi_layout_test failed"
2491
2492         destroy_test_pools || error "destroy test pools failed"
2493 }
2494 run_test 27D "validate llapi_layout API"
2495
2496 # Verify that default_easize is increased from its initial value after
2497 # accessing a widely striped file.
2498 test_27E() {
2499         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2500         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2501                 skip "client does not have LU-3338 fix"
2502
2503         # 72 bytes is the minimum space required to store striping
2504         # information for a file striped across one OST:
2505         # (sizeof(struct lov_user_md_v3) +
2506         #  sizeof(struct lov_user_ost_data_v1))
2507         local min_easize=72
2508         $LCTL set_param -n llite.*.default_easize $min_easize ||
2509                 error "lctl set_param failed"
2510         local easize=$($LCTL get_param -n llite.*.default_easize)
2511
2512         [ $easize -eq $min_easize ] ||
2513                 error "failed to set default_easize"
2514
2515         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2516                 error "setstripe failed"
2517         # In order to ensure stat() call actually talks to MDS we need to
2518         # do something drastic to this file to shake off all lock, e.g.
2519         # rename it (kills lookup lock forcing cache cleaning)
2520         mv $DIR/$tfile $DIR/${tfile}-1
2521         ls -l $DIR/${tfile}-1
2522         rm $DIR/${tfile}-1
2523
2524         easize=$($LCTL get_param -n llite.*.default_easize)
2525
2526         [ $easize -gt $min_easize ] ||
2527                 error "default_easize not updated"
2528 }
2529 run_test 27E "check that default extended attribute size properly increases"
2530
2531 test_27F() { # LU-5346/LU-7975
2532         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2533         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2534         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2535                 skip "Need MDS version at least 2.8.51"
2536         remote_ost_nodsh && skip "remote OST with nodsh"
2537
2538         test_mkdir $DIR/$tdir
2539         rm -f $DIR/$tdir/f0
2540         $LFS setstripe -c 2 $DIR/$tdir
2541
2542         # stop all OSTs to reproduce situation for LU-7975 ticket
2543         for num in $(seq $OSTCOUNT); do
2544                 stop ost$num
2545         done
2546
2547         # open/create f0 with O_LOV_DELAY_CREATE
2548         # truncate f0 to a non-0 size
2549         # close
2550         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2551
2552         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2553         # open/write it again to force delayed layout creation
2554         cat /etc/hosts > $DIR/$tdir/f0 &
2555         catpid=$!
2556
2557         # restart OSTs
2558         for num in $(seq $OSTCOUNT); do
2559                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2560                         error "ost$num failed to start"
2561         done
2562
2563         wait $catpid || error "cat failed"
2564
2565         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2566         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2567                 error "wrong stripecount"
2568
2569 }
2570 run_test 27F "Client resend delayed layout creation with non-zero size"
2571
2572 test_27G() { #LU-10629
2573         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2574                 skip "Need MDS version at least 2.11.51"
2575         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2576         remote_mds_nodsh && skip "remote MDS with nodsh"
2577         local POOL=${POOL:-testpool}
2578         local ostrange="0 0 1"
2579
2580         test_mkdir $DIR/$tdir
2581         pool_add $POOL || error "pool_add failed"
2582         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2583         $LFS setstripe -p $POOL $DIR/$tdir
2584
2585         local pool=$($LFS getstripe -p $DIR/$tdir)
2586
2587         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2588
2589         $LFS setstripe -d $DIR/$tdir
2590
2591         pool=$($LFS getstripe -p $DIR/$tdir)
2592
2593         rmdir $DIR/$tdir
2594
2595         [ -z "$pool" ] || error "'$pool' is not empty"
2596 }
2597 run_test 27G "Clear OST pool from stripe"
2598
2599 test_27H() {
2600         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2601                 skip "Need MDS version newer than 2.11.54"
2602         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2603         test_mkdir $DIR/$tdir
2604         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2605         touch $DIR/$tdir/$tfile
2606         $LFS getstripe -c $DIR/$tdir/$tfile
2607         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2608                 error "two-stripe file doesn't have two stripes"
2609
2610         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2611         $LFS getstripe -y $DIR/$tdir/$tfile
2612         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2613              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2614                 error "expected l_ost_idx: [02]$ not matched"
2615
2616         # make sure ost list has been cleared
2617         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2618         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2619                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2620         touch $DIR/$tdir/f3
2621         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2622 }
2623 run_test 27H "Set specific OSTs stripe"
2624
2625 test_27I() {
2626         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2627         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2628         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2629                 skip "Need MDS version newer than 2.12.52"
2630         local pool=$TESTNAME
2631         local ostrange="1 1 1"
2632
2633         save_layout_restore_at_exit $MOUNT
2634         $LFS setstripe -c 2 -i 0 $MOUNT
2635         pool_add $pool || error "pool_add failed"
2636         pool_add_targets $pool $ostrange || "pool_add_targets failed"
2637         test_mkdir $DIR/$tdir
2638         $LFS setstripe -p $pool $DIR/$tdir
2639         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2640         $LFS getstripe $DIR/$tdir/$tfile
2641 }
2642 run_test 27I "check that root dir striping does not break parent dir one"
2643
2644 test_27J() {
2645         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2646                 skip "Need MDS version newer than 2.12.51"
2647
2648         test_mkdir $DIR/$tdir
2649         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2650         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2651
2652         # create foreign file (raw way)
2653         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2654                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2655
2656         # verify foreign file (raw way)
2657         parse_foreign_file -f $DIR/$tdir/$tfile |
2658                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2659                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2660         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2661                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2662         parse_foreign_file -f $DIR/$tdir/$tfile |
2663                 grep "lov_foreign_size: 73" ||
2664                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2665         parse_foreign_file -f $DIR/$tdir/$tfile |
2666                 grep "lov_foreign_type: 1" ||
2667                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2668         parse_foreign_file -f $DIR/$tdir/$tfile |
2669                 grep "lov_foreign_flags: 0x0000DA08" ||
2670                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2671         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2672                 grep "lov_foreign_value: 0x" |
2673                 sed -e 's/lov_foreign_value: 0x//')
2674         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2675         [[ $lov = ${lov2// /} ]] ||
2676                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2677
2678         # create foreign file (lfs + API)
2679         $LFS setstripe --foreign=daos --flags 0xda08 \
2680                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2681                 error "$DIR/$tdir/${tfile}2: create failed"
2682
2683         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2684                 grep "lfm_magic:.*0x0BD70BD0" ||
2685                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2686         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2687         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2688                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2689         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*daos" ||
2690                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2691         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2692                 grep "lfm_flags:.*0x0000DA08" ||
2693                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2694         $LFS getstripe $DIR/$tdir/${tfile}2 |
2695                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2696                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2697
2698         # modify striping should fail
2699         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2700                 error "$DIR/$tdir/$tfile: setstripe should fail"
2701         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2702                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2703
2704         # R/W should fail
2705         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2706         cat $DIR/$tdir/${tfile}2 &&
2707                 error "$DIR/$tdir/${tfile}2: read should fail"
2708         cat /etc/passwd > $DIR/$tdir/$tfile &&
2709                 error "$DIR/$tdir/$tfile: write should fail"
2710         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2711                 error "$DIR/$tdir/${tfile}2: write should fail"
2712
2713         # chmod should work
2714         chmod 222 $DIR/$tdir/$tfile ||
2715                 error "$DIR/$tdir/$tfile: chmod failed"
2716         chmod 222 $DIR/$tdir/${tfile}2 ||
2717                 error "$DIR/$tdir/${tfile}2: chmod failed"
2718
2719         # chown should work
2720         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2721                 error "$DIR/$tdir/$tfile: chown failed"
2722         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2723                 error "$DIR/$tdir/${tfile}2: chown failed"
2724
2725         # rename should work
2726         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2727                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2728         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2729                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2730
2731         #remove foreign file
2732         rm $DIR/$tdir/${tfile}.new ||
2733                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2734         rm $DIR/$tdir/${tfile}2.new ||
2735                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2736 }
2737 run_test 27J "basic ops on file with foreign LOV"
2738
2739 test_27K() {
2740         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2741                 skip "Need MDS version newer than 2.12.49"
2742
2743         test_mkdir $DIR/$tdir
2744         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2745         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2746
2747         # create foreign dir (raw way)
2748         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2749                 error "create_foreign_dir FAILED"
2750
2751         # verify foreign dir (raw way)
2752         parse_foreign_dir -d $DIR/$tdir/$tdir |
2753                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2754                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2755         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2756                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2757         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2758                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2759         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_flags: 0$" ||
2760                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2761         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2762                 grep "lmv_foreign_value: 0x" |
2763                 sed 's/lmv_foreign_value: 0x//')
2764         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2765                 sed 's/ //g')
2766         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2767
2768         # create foreign dir (lfs + API)
2769         $LFS mkdir --foreign=daos --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2770                 $DIR/$tdir/${tdir}2 ||
2771                 error "$DIR/$tdir/${tdir}2: create failed"
2772
2773         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2774                 grep "lfm_magic:.*0x0CD50CD0" ||
2775                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2776         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2777         # - sizeof(lfm_type) - sizeof(lfm_flags)
2778         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2779                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2780         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*daos" ||
2781                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2782         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2783                 grep "lfm_flags:.*0x0000DA05" ||
2784                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2785         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2786                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2787                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2788
2789         # file create in dir should fail
2790         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
2791         touch $DIR/$tdir/${tdir}2/$tfile &&
2792                 "$DIR/${tdir}2: file create should fail"
2793
2794         # chmod should work
2795         chmod 777 $DIR/$tdir/$tdir ||
2796                 error "$DIR/$tdir: chmod failed"
2797         chmod 777 $DIR/$tdir/${tdir}2 ||
2798                 error "$DIR/${tdir}2: chmod failed"
2799
2800         # chown should work
2801         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2802                 error "$DIR/$tdir: chown failed"
2803         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2804                 error "$DIR/${tdir}2: chown failed"
2805
2806         # rename should work
2807         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2808                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2809         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2810                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2811
2812         #remove foreign dir
2813         rmdir $DIR/$tdir/${tdir}.new ||
2814                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2815         rmdir $DIR/$tdir/${tdir}2.new ||
2816                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2817 }
2818 run_test 27K "basic ops on dir with foreign LMV"
2819
2820 test_27L() {
2821         remote_mds_nodsh && skip "remote MDS with nodsh"
2822
2823         local POOL=${POOL:-$TESTNAME}
2824
2825         pool_add $POOL || error "pool_add failed"
2826
2827         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2828                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2829                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2830 }
2831 run_test 27L "lfs pool_list gives correct pool name"
2832
2833 test_27M() {
2834         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2835                 skip "Need MDS version >= than 2.12.57"
2836         remote_mds_nodsh && skip "remote MDS with nodsh"
2837         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2838
2839         test_mkdir $DIR/$tdir
2840
2841         # Set default striping on directory
2842         $LFS setstripe -C 4 $DIR/$tdir
2843
2844         echo 1 > $DIR/$tdir/${tfile}.1
2845         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2846         local setcount=4
2847         [ $count -eq $setcount ] ||
2848                 error "(1) stripe count $count, should be $setcount"
2849
2850         # Capture existing append_stripe_count setting for restore
2851         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2852         local mdts=$(comma_list $(mdts_nodes))
2853         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$orig_count" EXIT
2854
2855         local appendcount=$orig_count
2856         echo 1 >> $DIR/$tdir/${tfile}.2_append
2857         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
2858         [ $count -eq $appendcount ] ||
2859                 error "(2)stripe count $count, should be $appendcount for append"
2860
2861         # Disable O_APPEND striping, verify it works
2862         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
2863
2864         # Should now get the default striping, which is 4
2865         setcount=4
2866         echo 1 >> $DIR/$tdir/${tfile}.3_append
2867         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
2868         [ $count -eq $setcount ] ||
2869                 error "(3) stripe count $count, should be $setcount"
2870
2871         # Try changing the stripe count for append files
2872         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
2873
2874         # Append striping is now 2 (directory default is still 4)
2875         appendcount=2
2876         echo 1 >> $DIR/$tdir/${tfile}.4_append
2877         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
2878         [ $count -eq $appendcount ] ||
2879                 error "(4) stripe count $count, should be $appendcount for append"
2880
2881         # Test append stripe count of -1
2882         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
2883         appendcount=$OSTCOUNT
2884         echo 1 >> $DIR/$tdir/${tfile}.5
2885         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
2886         [ $count -eq $appendcount ] ||
2887                 error "(5) stripe count $count, should be $appendcount for append"
2888
2889         # Set append striping back to default of 1
2890         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
2891
2892         # Try a new default striping, PFL + DOM
2893         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
2894
2895         # Create normal DOM file, DOM returns stripe count == 0
2896         setcount=0
2897         touch $DIR/$tdir/${tfile}.6
2898         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
2899         [ $count -eq $setcount ] ||
2900                 error "(6) stripe count $count, should be $setcount"
2901
2902         # Show
2903         appendcount=1
2904         echo 1 >> $DIR/$tdir/${tfile}.7_append
2905         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
2906         [ $count -eq $appendcount ] ||
2907                 error "(7) stripe count $count, should be $appendcount for append"
2908
2909         # Clean up DOM layout
2910         $LFS setstripe -d $DIR/$tdir
2911
2912         # Now test that append striping works when layout is from root
2913         $LFS setstripe -c 2 $MOUNT
2914         # Make a special directory for this
2915         mkdir $DIR/${tdir}/${tdir}.2
2916         stack_trap "$LFS setstripe -d $MOUNT" EXIT
2917
2918         # Verify for normal file
2919         setcount=2
2920         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
2921         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
2922         [ $count -eq $setcount ] ||
2923                 error "(8) stripe count $count, should be $setcount"
2924
2925         appendcount=1
2926         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
2927         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
2928         [ $count -eq $appendcount ] ||
2929                 error "(9) stripe count $count, should be $appendcount for append"
2930
2931         # Now test O_APPEND striping with pools
2932         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
2933         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'" EXIT
2934
2935         # Create the pool
2936         pool_add $TESTNAME || error "pool creation failed"
2937         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
2938
2939         echo 1 >> $DIR/$tdir/${tfile}.10_append
2940
2941         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
2942         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
2943
2944         # Check that count is still correct
2945         appendcount=1
2946         echo 1 >> $DIR/$tdir/${tfile}.11_append
2947         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
2948         [ $count -eq $appendcount ] ||
2949                 error "(11) stripe count $count, should be $appendcount for append"
2950
2951         # Disable O_APPEND stripe count, verify pool works separately
2952         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
2953
2954         echo 1 >> $DIR/$tdir/${tfile}.12_append
2955
2956         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
2957         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
2958
2959         # Remove pool setting, verify it's not applied
2960         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
2961
2962         echo 1 >> $DIR/$tdir/${tfile}.13_append
2963
2964         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
2965         [ "$pool" = "" ] || error "(13) pool found: $pool"
2966 }
2967 run_test 27M "test O_APPEND striping"
2968
2969 test_27N() {
2970         combined_mgs_mds && skip "needs separate MGS/MDT"
2971
2972         pool_add $TESTNAME || error "pool_add failed"
2973         do_facet mgs "$LCTL pool_list $FSNAME" |
2974                 grep -Fx "${FSNAME}.${TESTNAME}" ||
2975                 error "lctl pool_list on MGS failed"
2976 }
2977 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
2978
2979 # createtest also checks that device nodes are created and
2980 # then visible correctly (#2091)
2981 test_28() { # bug 2091
2982         test_mkdir $DIR/d28
2983         $CREATETEST $DIR/d28/ct || error "createtest failed"
2984 }
2985 run_test 28 "create/mknod/mkdir with bad file types ============"
2986
2987 test_29() {
2988         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2989
2990         sync; sleep 1; sync # flush out any dirty pages from previous tests
2991         cancel_lru_locks
2992         test_mkdir $DIR/d29
2993         touch $DIR/d29/foo
2994         log 'first d29'
2995         ls -l $DIR/d29
2996
2997         declare -i LOCKCOUNTORIG=0
2998         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
2999                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3000         done
3001         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3002
3003         declare -i LOCKUNUSEDCOUNTORIG=0
3004         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3005                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3006         done
3007
3008         log 'second d29'
3009         ls -l $DIR/d29
3010         log 'done'
3011
3012         declare -i LOCKCOUNTCURRENT=0
3013         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3014                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3015         done
3016
3017         declare -i LOCKUNUSEDCOUNTCURRENT=0
3018         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3019                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3020         done
3021
3022         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3023                 $LCTL set_param -n ldlm.dump_namespaces ""
3024                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3025                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3026                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3027                 return 2
3028         fi
3029         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3030                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3031                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3032                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3033                 return 3
3034         fi
3035 }
3036 run_test 29 "IT_GETATTR regression  ============================"
3037
3038 test_30a() { # was test_30
3039         cp $(which ls) $DIR || cp /bin/ls $DIR
3040         $DIR/ls / || error "Can't execute binary from lustre"
3041         rm $DIR/ls
3042 }
3043 run_test 30a "execute binary from Lustre (execve) =============="
3044
3045 test_30b() {
3046         cp `which ls` $DIR || cp /bin/ls $DIR
3047         chmod go+rx $DIR/ls
3048         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3049         rm $DIR/ls
3050 }
3051 run_test 30b "execute binary from Lustre as non-root ==========="
3052
3053 test_30c() { # b=22376
3054         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3055
3056         cp `which ls` $DIR || cp /bin/ls $DIR
3057         chmod a-rw $DIR/ls
3058         cancel_lru_locks mdc
3059         cancel_lru_locks osc
3060         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3061         rm -f $DIR/ls
3062 }
3063 run_test 30c "execute binary from Lustre without read perms ===="
3064
3065 test_31a() {
3066         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3067         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3068 }
3069 run_test 31a "open-unlink file =================================="
3070
3071 test_31b() {
3072         touch $DIR/f31 || error "touch $DIR/f31 failed"
3073         ln $DIR/f31 $DIR/f31b || error "ln failed"
3074         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3075         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3076 }
3077 run_test 31b "unlink file with multiple links while open ======="
3078
3079 test_31c() {
3080         touch $DIR/f31 || error "touch $DIR/f31 failed"
3081         ln $DIR/f31 $DIR/f31c || error "ln failed"
3082         multiop_bg_pause $DIR/f31 O_uc ||
3083                 error "multiop_bg_pause for $DIR/f31 failed"
3084         MULTIPID=$!
3085         $MULTIOP $DIR/f31c Ouc
3086         kill -USR1 $MULTIPID
3087         wait $MULTIPID
3088 }
3089 run_test 31c "open-unlink file with multiple links ============="
3090
3091 test_31d() {
3092         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3093         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3094 }
3095 run_test 31d "remove of open directory ========================="
3096
3097 test_31e() { # bug 2904
3098         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3099 }
3100 run_test 31e "remove of open non-empty directory ==============="
3101
3102 test_31f() { # bug 4554
3103         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3104
3105         set -vx
3106         test_mkdir $DIR/d31f
3107         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3108         cp /etc/hosts $DIR/d31f
3109         ls -l $DIR/d31f
3110         $LFS getstripe $DIR/d31f/hosts
3111         multiop_bg_pause $DIR/d31f D_c || return 1
3112         MULTIPID=$!
3113
3114         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3115         test_mkdir $DIR/d31f
3116         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3117         cp /etc/hosts $DIR/d31f
3118         ls -l $DIR/d31f
3119         $LFS getstripe $DIR/d31f/hosts
3120         multiop_bg_pause $DIR/d31f D_c || return 1
3121         MULTIPID2=$!
3122
3123         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3124         wait $MULTIPID || error "first opendir $MULTIPID failed"
3125
3126         sleep 6
3127
3128         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3129         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3130         set +vx
3131 }
3132 run_test 31f "remove of open directory with open-unlink file ==="
3133
3134 test_31g() {
3135         echo "-- cross directory link --"
3136         test_mkdir -c1 $DIR/${tdir}ga
3137         test_mkdir -c1 $DIR/${tdir}gb
3138         touch $DIR/${tdir}ga/f
3139         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3140         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3141         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3142         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3143         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3144 }
3145 run_test 31g "cross directory link==============="
3146
3147 test_31h() {
3148         echo "-- cross directory link --"
3149         test_mkdir -c1 $DIR/${tdir}
3150         test_mkdir -c1 $DIR/${tdir}/dir
3151         touch $DIR/${tdir}/f
3152         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3153         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3154         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3155         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3156         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3157 }
3158 run_test 31h "cross directory link under child==============="
3159
3160 test_31i() {
3161         echo "-- cross directory link --"
3162         test_mkdir -c1 $DIR/$tdir
3163         test_mkdir -c1 $DIR/$tdir/dir
3164         touch $DIR/$tdir/dir/f
3165         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3166         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3167         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3168         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3169         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3170 }
3171 run_test 31i "cross directory link under parent==============="
3172
3173 test_31j() {
3174         test_mkdir -c1 -p $DIR/$tdir
3175         test_mkdir -c1 -p $DIR/$tdir/dir1
3176         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3177         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3178         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3179         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3180         return 0
3181 }
3182 run_test 31j "link for directory==============="
3183
3184 test_31k() {
3185         test_mkdir -c1 -p $DIR/$tdir
3186         touch $DIR/$tdir/s
3187         touch $DIR/$tdir/exist
3188         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3189         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3190         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3191         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3192         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3193         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3194         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3195         return 0
3196 }
3197 run_test 31k "link to file: the same, non-existing, dir==============="
3198
3199 test_31m() {
3200         mkdir $DIR/d31m
3201         touch $DIR/d31m/s
3202         mkdir $DIR/d31m2
3203         touch $DIR/d31m2/exist
3204         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3205         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3206         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3207         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3208         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3209         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3210         return 0
3211 }
3212 run_test 31m "link to file: the same, non-existing, dir==============="
3213
3214 test_31n() {
3215         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3216         nlink=$(stat --format=%h $DIR/$tfile)
3217         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3218         local fd=$(free_fd)
3219         local cmd="exec $fd<$DIR/$tfile"
3220         eval $cmd
3221         cmd="exec $fd<&-"
3222         trap "eval $cmd" EXIT
3223         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3224         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3225         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3226         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3227         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3228         eval $cmd
3229 }
3230 run_test 31n "check link count of unlinked file"
3231
3232 link_one() {
3233         local tempfile=$(mktemp $1_XXXXXX)
3234         mlink $tempfile $1 2> /dev/null &&
3235                 echo "$BASHPID: link $tempfile to $1 succeeded"
3236         munlink $tempfile
3237 }
3238
3239 test_31o() { # LU-2901
3240         test_mkdir $DIR/$tdir
3241         for LOOP in $(seq 100); do
3242                 rm -f $DIR/$tdir/$tfile*
3243                 for THREAD in $(seq 8); do
3244                         link_one $DIR/$tdir/$tfile.$LOOP &
3245                 done
3246                 wait
3247                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3248                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3249                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3250                         break || true
3251         done
3252 }
3253 run_test 31o "duplicate hard links with same filename"
3254
3255 test_31p() {
3256         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3257
3258         test_mkdir $DIR/$tdir
3259         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3260         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3261
3262         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3263                 error "open unlink test1 failed"
3264         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3265                 error "open unlink test2 failed"
3266
3267         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3268                 error "test1 still exists"
3269         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3270                 error "test2 still exists"
3271 }
3272 run_test 31p "remove of open striped directory"
3273
3274 cleanup_test32_mount() {
3275         local rc=0
3276         trap 0
3277         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3278         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3279         losetup -d $loopdev || true
3280         rm -rf $DIR/$tdir
3281         return $rc
3282 }
3283
3284 test_32a() {
3285         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3286
3287         echo "== more mountpoints and symlinks ================="
3288         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3289         trap cleanup_test32_mount EXIT
3290         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3291         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3292                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3293         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3294                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3295         cleanup_test32_mount
3296 }
3297 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3298
3299 test_32b() {
3300         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3301
3302         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3303         trap cleanup_test32_mount EXIT
3304         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3305         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3306                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3307         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3308                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3309         cleanup_test32_mount
3310 }
3311 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3312
3313 test_32c() {
3314         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3315
3316         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3317         trap cleanup_test32_mount EXIT
3318         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3319         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3320                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3321         test_mkdir -p $DIR/$tdir/d2/test_dir
3322         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3323                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3324         cleanup_test32_mount
3325 }
3326 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3327
3328 test_32d() {
3329         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3330
3331         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3332         trap cleanup_test32_mount EXIT
3333         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3334         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3335                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3336         test_mkdir -p $DIR/$tdir/d2/test_dir
3337         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3338                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3339         cleanup_test32_mount
3340 }
3341 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3342
3343 test_32e() {
3344         rm -fr $DIR/$tdir
3345         test_mkdir -p $DIR/$tdir/tmp
3346         local tmp_dir=$DIR/$tdir/tmp
3347         ln -s $DIR/$tdir $tmp_dir/symlink11
3348         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3349         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3350         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3351 }
3352 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3353
3354 test_32f() {
3355         rm -fr $DIR/$tdir
3356         test_mkdir -p $DIR/$tdir/tmp
3357         local tmp_dir=$DIR/$tdir/tmp
3358         ln -s $DIR/$tdir $tmp_dir/symlink11
3359         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3360         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3361         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3362 }
3363 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3364
3365 test_32g() {
3366         local tmp_dir=$DIR/$tdir/tmp
3367         test_mkdir -p $tmp_dir
3368         test_mkdir $DIR/${tdir}2
3369         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3370         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3371         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3372         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3373         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3374         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3375 }
3376 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3377
3378 test_32h() {
3379         rm -fr $DIR/$tdir $DIR/${tdir}2
3380         tmp_dir=$DIR/$tdir/tmp
3381         test_mkdir -p $tmp_dir
3382         test_mkdir $DIR/${tdir}2
3383         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3384         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3385         ls $tmp_dir/symlink12 || error "listing symlink12"
3386         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3387 }
3388 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3389
3390 test_32i() {
3391         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3392
3393         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3394         trap cleanup_test32_mount EXIT
3395         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3396         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3397                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3398         touch $DIR/$tdir/test_file
3399         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3400                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3401         cleanup_test32_mount
3402 }
3403 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3404
3405 test_32j() {
3406         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3407
3408         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3409         trap cleanup_test32_mount EXIT
3410         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3411         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3412                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3413         touch $DIR/$tdir/test_file
3414         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3415                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3416         cleanup_test32_mount
3417 }
3418 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3419
3420 test_32k() {
3421         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3422
3423         rm -fr $DIR/$tdir
3424         trap cleanup_test32_mount EXIT
3425         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3426         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3427                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3428         test_mkdir -p $DIR/$tdir/d2
3429         touch $DIR/$tdir/d2/test_file || error "touch failed"
3430         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3431                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3432         cleanup_test32_mount
3433 }
3434 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3435
3436 test_32l() {
3437         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3438
3439         rm -fr $DIR/$tdir
3440         trap cleanup_test32_mount EXIT
3441         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3442         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3443                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3444         test_mkdir -p $DIR/$tdir/d2
3445         touch $DIR/$tdir/d2/test_file || error "touch failed"
3446         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3447                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3448         cleanup_test32_mount
3449 }
3450 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3451
3452 test_32m() {
3453         rm -fr $DIR/d32m
3454         test_mkdir -p $DIR/d32m/tmp
3455         TMP_DIR=$DIR/d32m/tmp
3456         ln -s $DIR $TMP_DIR/symlink11
3457         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3458         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3459                 error "symlink11 not a link"
3460         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3461                 error "symlink01 not a link"
3462 }
3463 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3464
3465 test_32n() {
3466         rm -fr $DIR/d32n
3467         test_mkdir -p $DIR/d32n/tmp
3468         TMP_DIR=$DIR/d32n/tmp
3469         ln -s $DIR $TMP_DIR/symlink11
3470         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3471         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3472         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3473 }
3474 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3475
3476 test_32o() {
3477         touch $DIR/$tfile
3478         test_mkdir -p $DIR/d32o/tmp
3479         TMP_DIR=$DIR/d32o/tmp
3480         ln -s $DIR/$tfile $TMP_DIR/symlink12
3481         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3482         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3483                 error "symlink12 not a link"
3484         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3485         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3486                 error "$DIR/d32o/tmp/symlink12 not file type"
3487         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3488                 error "$DIR/d32o/symlink02 not file type"
3489 }
3490 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3491
3492 test_32p() {
3493         log 32p_1
3494         rm -fr $DIR/d32p
3495         log 32p_2
3496         rm -f $DIR/$tfile
3497         log 32p_3
3498         touch $DIR/$tfile
3499         log 32p_4
3500         test_mkdir -p $DIR/d32p/tmp
3501         log 32p_5
3502         TMP_DIR=$DIR/d32p/tmp
3503         log 32p_6
3504         ln -s $DIR/$tfile $TMP_DIR/symlink12
3505         log 32p_7
3506         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3507         log 32p_8
3508         cat $DIR/d32p/tmp/symlink12 ||
3509                 error "Can't open $DIR/d32p/tmp/symlink12"
3510         log 32p_9
3511         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3512         log 32p_10
3513 }
3514 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3515
3516 test_32q() {
3517         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3518
3519         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3520         trap cleanup_test32_mount EXIT
3521         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3522         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3523         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3524                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3525         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3526         cleanup_test32_mount
3527 }
3528 run_test 32q "stat follows mountpoints in Lustre (should return error)"
3529
3530 test_32r() {
3531         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3532
3533         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3534         trap cleanup_test32_mount EXIT
3535         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3536         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3537         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3538                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3539         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
3540         cleanup_test32_mount
3541 }
3542 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
3543
3544 test_33aa() {
3545         rm -f $DIR/$tfile
3546         touch $DIR/$tfile
3547         chmod 444 $DIR/$tfile
3548         chown $RUNAS_ID $DIR/$tfile
3549         log 33_1
3550         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3551         log 33_2
3552 }
3553 run_test 33aa "write file with mode 444 (should return error)"
3554
3555 test_33a() {
3556         rm -fr $DIR/$tdir
3557         test_mkdir $DIR/$tdir
3558         chown $RUNAS_ID $DIR/$tdir
3559         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
3560                 error "$RUNAS create $tdir/$tfile failed"
3561         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
3562                 error "open RDWR" || true
3563 }
3564 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
3565
3566 test_33b() {
3567         rm -fr $DIR/$tdir
3568         test_mkdir $DIR/$tdir
3569         chown $RUNAS_ID $DIR/$tdir
3570         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
3571 }
3572 run_test 33b "test open file with malformed flags (No panic)"
3573
3574 test_33c() {
3575         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3576         remote_ost_nodsh && skip "remote OST with nodsh"
3577
3578         local ostnum
3579         local ostname
3580         local write_bytes
3581         local all_zeros
3582
3583         all_zeros=:
3584         rm -fr $DIR/$tdir
3585         test_mkdir $DIR/$tdir
3586         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
3587
3588         sync
3589         for ostnum in $(seq $OSTCOUNT); do
3590                 # test-framework's OST numbering is one-based, while Lustre's
3591                 # is zero-based
3592                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3593                 # Parsing llobdstat's output sucks; we could grep the /proc
3594                 # path, but that's likely to not be as portable as using the
3595                 # llobdstat utility.  So we parse lctl output instead.
3596                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3597                         obdfilter/$ostname/stats |
3598                         awk '/^write_bytes/ {print $7}' )
3599                 echo "baseline_write_bytes@$OSTnum/$ostname=$write_bytes"
3600                 if (( ${write_bytes:-0} > 0 ))
3601                 then
3602                         all_zeros=false
3603                         break;
3604                 fi
3605         done
3606
3607         $all_zeros || return 0
3608
3609         # Write four bytes
3610         echo foo > $DIR/$tdir/bar
3611         # Really write them
3612         sync
3613
3614         # Total up write_bytes after writing.  We'd better find non-zeros.
3615         for ostnum in $(seq $OSTCOUNT); do
3616                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3617                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3618                         obdfilter/$ostname/stats |
3619                         awk '/^write_bytes/ {print $7}' )
3620                 echo "write_bytes@$OSTnum/$ostname=$write_bytes"
3621                 if (( ${write_bytes:-0} > 0 ))
3622                 then
3623                         all_zeros=false
3624                         break;
3625                 fi
3626         done
3627
3628         if $all_zeros
3629         then
3630                 for ostnum in $(seq $OSTCOUNT); do
3631                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3632                         echo "Check that write_bytes is present in obdfilter/*/stats:"
3633                         do_facet ost$ostnum lctl get_param -n \
3634                                 obdfilter/$ostname/stats
3635                 done
3636                 error "OST not keeping write_bytes stats (b22312)"
3637         fi
3638 }
3639 run_test 33c "test llobdstat and write_bytes"
3640
3641 test_33d() {
3642         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
3643         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3644
3645         local MDTIDX=1
3646         local remote_dir=$DIR/$tdir/remote_dir
3647
3648         test_mkdir $DIR/$tdir
3649         $LFS mkdir -i $MDTIDX $remote_dir ||
3650                 error "create remote directory failed"
3651
3652         touch $remote_dir/$tfile
3653         chmod 444 $remote_dir/$tfile
3654         chown $RUNAS_ID $remote_dir/$tfile
3655
3656         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3657
3658         chown $RUNAS_ID $remote_dir
3659         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
3660                                         error "create" || true
3661         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
3662                                     error "open RDWR" || true
3663         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
3664 }
3665 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
3666
3667 test_33e() {
3668         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3669
3670         mkdir $DIR/$tdir
3671
3672         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3673         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3674         mkdir $DIR/$tdir/local_dir
3675
3676         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3677         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3678         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3679
3680         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3681                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
3682
3683         rmdir $DIR/$tdir/* || error "rmdir failed"
3684
3685         umask 777
3686         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3687         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3688         mkdir $DIR/$tdir/local_dir
3689
3690         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3691         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3692         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3693
3694         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3695                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
3696
3697         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
3698
3699         umask 000
3700         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3701         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3702         mkdir $DIR/$tdir/local_dir
3703
3704         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3705         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3706         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3707
3708         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3709                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
3710 }
3711 run_test 33e "mkdir and striped directory should have same mode"
3712
3713 cleanup_33f() {
3714         trap 0
3715         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
3716 }
3717
3718 test_33f() {
3719         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3720         remote_mds_nodsh && skip "remote MDS with nodsh"
3721
3722         mkdir $DIR/$tdir
3723         chmod go+rwx $DIR/$tdir
3724         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
3725         trap cleanup_33f EXIT
3726
3727         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
3728                 error "cannot create striped directory"
3729
3730         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
3731                 error "cannot create files in striped directory"
3732
3733         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
3734                 error "cannot remove files in striped directory"
3735
3736         $RUNAS rmdir $DIR/$tdir/striped_dir ||
3737                 error "cannot remove striped directory"
3738
3739         cleanup_33f
3740 }
3741 run_test 33f "nonroot user can create, access, and remove a striped directory"
3742
3743 test_33g() {
3744         mkdir -p $DIR/$tdir/dir2
3745
3746         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
3747         echo $err
3748         [[ $err =~ "exists" ]] || error "Not exists error"
3749 }
3750 run_test 33g "nonroot user create already existing root created file"
3751
3752 test_33h() {
3753         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3754         [ $MDS1_VERSION -lt $(version_code 2.13.50) ] &&
3755                 skip "Need MDS version at least 2.13.50"
3756
3757         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir ||
3758                 error "mkdir $tdir failed"
3759         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
3760
3761         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
3762         local index2
3763
3764         for fname in $DIR/$tdir/$tfile.bak \
3765                      $DIR/$tdir/$tfile.SAV \
3766                      $DIR/$tdir/$tfile.orig \
3767                      $DIR/$tdir/$tfile~; do
3768                 touch $fname  || error "touch $fname failed"
3769                 index2=$($LFS getstripe -m $fname)
3770                 [ $index -eq $index2 ] ||
3771                         error "$fname MDT index mismatch $index != $index2"
3772         done
3773
3774         local failed=0
3775         for i in {1..50}; do
3776                 for fname in $(mktemp -u $DIR/$tdir/.$tfile.XXXXXX) \
3777                              $(mktemp $DIR/$tdir/$tfile.XXXXXXXX); do
3778                         touch $fname  || error "touch $fname failed"
3779                         index2=$($LFS getstripe -m $fname)
3780                         if [[ $index != $index2 ]]; then
3781                                 failed=$((failed + 1))
3782                                 echo "$fname MDT index mismatch $index != $index2"
3783                         fi
3784                 done
3785         done
3786         echo "$failed MDT index mismatches"
3787         (( failed < 4 )) || error "MDT index mismatch $failed times"
3788
3789 }
3790 run_test 33h "temp file is located on the same MDT as target"
3791
3792 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
3793 test_34a() {
3794         rm -f $DIR/f34
3795         $MCREATE $DIR/f34 || error "mcreate failed"
3796         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3797                 error "getstripe failed"
3798         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
3799         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3800                 error "getstripe failed"
3801         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3802                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3803 }
3804 run_test 34a "truncate file that has not been opened ==========="
3805
3806 test_34b() {
3807         [ ! -f $DIR/f34 ] && test_34a
3808         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3809                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3810         $OPENFILE -f O_RDONLY $DIR/f34
3811         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3812                 error "getstripe failed"
3813         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3814                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3815 }
3816 run_test 34b "O_RDONLY opening file doesn't create objects ====="
3817
3818 test_34c() {
3819         [ ! -f $DIR/f34 ] && test_34a
3820         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3821                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3822         $OPENFILE -f O_RDWR $DIR/f34
3823         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
3824                 error "$LFS getstripe failed"
3825         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3826                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3827 }
3828 run_test 34c "O_RDWR opening file-with-size works =============="
3829
3830 test_34d() {
3831         [ ! -f $DIR/f34 ] && test_34a
3832         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
3833                 error "dd failed"
3834         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3835                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3836         rm $DIR/f34
3837 }
3838 run_test 34d "write to sparse file ============================="
3839
3840 test_34e() {
3841         rm -f $DIR/f34e
3842         $MCREATE $DIR/f34e || error "mcreate failed"
3843         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
3844         $CHECKSTAT -s 1000 $DIR/f34e ||
3845                 error "Size of $DIR/f34e not equal to 1000 bytes"
3846         $OPENFILE -f O_RDWR $DIR/f34e
3847         $CHECKSTAT -s 1000 $DIR/f34e ||
3848                 error "Size of $DIR/f34e not equal to 1000 bytes"
3849 }
3850 run_test 34e "create objects, some with size and some without =="
3851
3852 test_34f() { # bug 6242, 6243
3853         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3854
3855         SIZE34F=48000
3856         rm -f $DIR/f34f
3857         $MCREATE $DIR/f34f || error "mcreate failed"
3858         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
3859         dd if=$DIR/f34f of=$TMP/f34f
3860         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
3861         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
3862         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
3863         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
3864         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
3865 }
3866 run_test 34f "read from a file with no objects until EOF ======="
3867
3868 test_34g() {
3869         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3870
3871         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
3872                 error "dd failed"
3873         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
3874         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3875                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
3876         cancel_lru_locks osc
3877         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3878                 error "wrong size after lock cancel"
3879
3880         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
3881         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3882                 error "expanding truncate failed"
3883         cancel_lru_locks osc
3884         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3885                 error "wrong expanded size after lock cancel"
3886 }
3887 run_test 34g "truncate long file ==============================="
3888
3889 test_34h() {
3890         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3891
3892         local gid=10
3893         local sz=1000
3894
3895         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
3896         sync # Flush the cache so that multiop below does not block on cache
3897              # flush when getting the group lock
3898         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
3899         MULTIPID=$!
3900
3901         # Since just timed wait is not good enough, let's do a sync write
3902         # that way we are sure enough time for a roundtrip + processing
3903         # passed + 2 seconds of extra margin.
3904         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
3905         rm $DIR/${tfile}-1
3906         sleep 2
3907
3908         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
3909                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
3910                 kill -9 $MULTIPID
3911         fi
3912         wait $MULTIPID
3913         local nsz=`stat -c %s $DIR/$tfile`
3914         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
3915 }
3916 run_test 34h "ftruncate file under grouplock should not block"
3917
3918 test_35a() {
3919         cp /bin/sh $DIR/f35a
3920         chmod 444 $DIR/f35a
3921         chown $RUNAS_ID $DIR/f35a
3922         $RUNAS $DIR/f35a && error || true
3923         rm $DIR/f35a
3924 }
3925 run_test 35a "exec file with mode 444 (should return and not leak)"
3926
3927 test_36a() {
3928         rm -f $DIR/f36
3929         utime $DIR/f36 || error "utime failed for MDS"
3930 }
3931 run_test 36a "MDS utime check (mknod, utime)"
3932
3933 test_36b() {
3934         echo "" > $DIR/f36
3935         utime $DIR/f36 || error "utime failed for OST"
3936 }
3937 run_test 36b "OST utime check (open, utime)"
3938
3939 test_36c() {
3940         rm -f $DIR/d36/f36
3941         test_mkdir $DIR/d36
3942         chown $RUNAS_ID $DIR/d36
3943         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
3944 }
3945 run_test 36c "non-root MDS utime check (mknod, utime)"
3946
3947 test_36d() {
3948         [ ! -d $DIR/d36 ] && test_36c
3949         echo "" > $DIR/d36/f36
3950         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
3951 }
3952 run_test 36d "non-root OST utime check (open, utime)"
3953
3954 test_36e() {
3955         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
3956
3957         test_mkdir $DIR/$tdir
3958         touch $DIR/$tdir/$tfile
3959         $RUNAS utime $DIR/$tdir/$tfile &&
3960                 error "utime worked, expected failure" || true
3961 }
3962 run_test 36e "utime on non-owned file (should return error)"
3963
3964 subr_36fh() {
3965         local fl="$1"
3966         local LANG_SAVE=$LANG
3967         local LC_LANG_SAVE=$LC_LANG
3968         export LANG=C LC_LANG=C # for date language
3969
3970         DATESTR="Dec 20  2000"
3971         test_mkdir $DIR/$tdir
3972         lctl set_param fail_loc=$fl
3973         date; date +%s
3974         cp /etc/hosts $DIR/$tdir/$tfile
3975         sync & # write RPC generated with "current" inode timestamp, but delayed
3976         sleep 1
3977         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
3978         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
3979         cancel_lru_locks $OSC
3980         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
3981         date; date +%s
3982         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
3983                 echo "BEFORE: $LS_BEFORE" && \
3984                 echo "AFTER : $LS_AFTER" && \
3985                 echo "WANT  : $DATESTR" && \
3986                 error "$DIR/$tdir/$tfile timestamps changed" || true
3987
3988         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
3989 }
3990
3991 test_36f() {
3992         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3993
3994         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
3995         subr_36fh "0x80000214"
3996 }
3997 run_test 36f "utime on file racing with OST BRW write =========="
3998
3999 test_36g() {
4000         remote_ost_nodsh && skip "remote OST with nodsh"
4001         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4002         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4003                 skip "Need MDS version at least 2.12.51"
4004
4005         local fmd_max_age
4006         local fmd
4007         local facet="ost1"
4008         local tgt="obdfilter"
4009
4010         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4011
4012         test_mkdir $DIR/$tdir
4013         fmd_max_age=$(do_facet $facet \
4014                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4015                 head -n 1")
4016
4017         echo "FMD max age: ${fmd_max_age}s"
4018         touch $DIR/$tdir/$tfile
4019         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4020                 gawk '{cnt=cnt+$1}  END{print cnt}')
4021         echo "FMD before: $fmd"
4022         [[ $fmd == 0 ]] &&
4023                 error "FMD wasn't create by touch"
4024         sleep $((fmd_max_age + 12))
4025         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4026                 gawk '{cnt=cnt+$1}  END{print cnt}')
4027         echo "FMD after: $fmd"
4028         [[ $fmd == 0 ]] ||
4029                 error "FMD wasn't expired by ping"
4030 }
4031 run_test 36g "FMD cache expiry ====================="
4032
4033 test_36h() {
4034         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4035
4036         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4037         subr_36fh "0x80000227"
4038 }
4039 run_test 36h "utime on file racing with OST BRW write =========="
4040
4041 test_36i() {
4042         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4043
4044         test_mkdir $DIR/$tdir
4045         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4046
4047         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4048         local new_mtime=$((mtime + 200))
4049
4050         #change Modify time of striped dir
4051         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4052                         error "change mtime failed"
4053
4054         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4055
4056         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4057 }
4058 run_test 36i "change mtime on striped directory"
4059
4060 # test_37 - duplicate with tests 32q 32r
4061
4062 test_38() {
4063         local file=$DIR/$tfile
4064         touch $file
4065         openfile -f O_DIRECTORY $file
4066         local RC=$?
4067         local ENOTDIR=20
4068         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4069         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4070 }
4071 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4072
4073 test_39a() { # was test_39
4074         touch $DIR/$tfile
4075         touch $DIR/${tfile}2
4076 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4077 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4078 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4079         sleep 2
4080         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4081         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4082                 echo "mtime"
4083                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4084                 echo "atime"
4085                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4086                 echo "ctime"
4087                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4088                 error "O_TRUNC didn't change timestamps"
4089         fi
4090 }
4091 run_test 39a "mtime changed on create"
4092
4093 test_39b() {
4094         test_mkdir -c1 $DIR/$tdir
4095         cp -p /etc/passwd $DIR/$tdir/fopen
4096         cp -p /etc/passwd $DIR/$tdir/flink
4097         cp -p /etc/passwd $DIR/$tdir/funlink
4098         cp -p /etc/passwd $DIR/$tdir/frename
4099         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4100
4101         sleep 1
4102         echo "aaaaaa" >> $DIR/$tdir/fopen
4103         echo "aaaaaa" >> $DIR/$tdir/flink
4104         echo "aaaaaa" >> $DIR/$tdir/funlink
4105         echo "aaaaaa" >> $DIR/$tdir/frename
4106
4107         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4108         local link_new=`stat -c %Y $DIR/$tdir/flink`
4109         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4110         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4111
4112         cat $DIR/$tdir/fopen > /dev/null
4113         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4114         rm -f $DIR/$tdir/funlink2
4115         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4116
4117         for (( i=0; i < 2; i++ )) ; do
4118                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4119                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4120                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4121                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4122
4123                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4124                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4125                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4126                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4127
4128                 cancel_lru_locks $OSC
4129                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4130         done
4131 }
4132 run_test 39b "mtime change on open, link, unlink, rename  ======"
4133
4134 # this should be set to past
4135 TEST_39_MTIME=`date -d "1 year ago" +%s`
4136
4137 # bug 11063
4138 test_39c() {
4139         touch $DIR1/$tfile
4140         sleep 2
4141         local mtime0=`stat -c %Y $DIR1/$tfile`
4142
4143         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4144         local mtime1=`stat -c %Y $DIR1/$tfile`
4145         [ "$mtime1" = $TEST_39_MTIME ] || \
4146                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4147
4148         local d1=`date +%s`
4149         echo hello >> $DIR1/$tfile
4150         local d2=`date +%s`
4151         local mtime2=`stat -c %Y $DIR1/$tfile`
4152         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4153                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4154
4155         mv $DIR1/$tfile $DIR1/$tfile-1
4156
4157         for (( i=0; i < 2; i++ )) ; do
4158                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4159                 [ "$mtime2" = "$mtime3" ] || \
4160                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4161
4162                 cancel_lru_locks $OSC
4163                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4164         done
4165 }
4166 run_test 39c "mtime change on rename ==========================="
4167
4168 # bug 21114
4169 test_39d() {
4170         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4171
4172         touch $DIR1/$tfile
4173         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4174
4175         for (( i=0; i < 2; i++ )) ; do
4176                 local mtime=`stat -c %Y $DIR1/$tfile`
4177                 [ $mtime = $TEST_39_MTIME ] || \
4178                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4179
4180                 cancel_lru_locks $OSC
4181                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4182         done
4183 }
4184 run_test 39d "create, utime, stat =============================="
4185
4186 # bug 21114
4187 test_39e() {
4188         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4189
4190         touch $DIR1/$tfile
4191         local mtime1=`stat -c %Y $DIR1/$tfile`
4192
4193         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4194
4195         for (( i=0; i < 2; i++ )) ; do
4196                 local mtime2=`stat -c %Y $DIR1/$tfile`
4197                 [ $mtime2 = $TEST_39_MTIME ] || \
4198                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4199
4200                 cancel_lru_locks $OSC
4201                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4202         done
4203 }
4204 run_test 39e "create, stat, utime, stat ========================"
4205
4206 # bug 21114
4207 test_39f() {
4208         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4209
4210         touch $DIR1/$tfile
4211         mtime1=`stat -c %Y $DIR1/$tfile`
4212
4213         sleep 2
4214         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4215
4216         for (( i=0; i < 2; i++ )) ; do
4217                 local mtime2=`stat -c %Y $DIR1/$tfile`
4218                 [ $mtime2 = $TEST_39_MTIME ] || \
4219                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4220
4221                 cancel_lru_locks $OSC
4222                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4223         done
4224 }
4225 run_test 39f "create, stat, sleep, utime, stat ================="
4226
4227 # bug 11063
4228 test_39g() {
4229         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4230
4231         echo hello >> $DIR1/$tfile
4232         local mtime1=`stat -c %Y $DIR1/$tfile`
4233
4234         sleep 2
4235         chmod o+r $DIR1/$tfile
4236
4237         for (( i=0; i < 2; i++ )) ; do
4238                 local mtime2=`stat -c %Y $DIR1/$tfile`
4239                 [ "$mtime1" = "$mtime2" ] || \
4240                         error "lost mtime: $mtime2, should be $mtime1"
4241
4242                 cancel_lru_locks $OSC
4243                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4244         done
4245 }
4246 run_test 39g "write, chmod, stat ==============================="
4247
4248 # bug 11063
4249 test_39h() {
4250         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4251
4252         touch $DIR1/$tfile
4253         sleep 1
4254
4255         local d1=`date`
4256         echo hello >> $DIR1/$tfile
4257         local mtime1=`stat -c %Y $DIR1/$tfile`
4258
4259         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4260         local d2=`date`
4261         if [ "$d1" != "$d2" ]; then
4262                 echo "write and touch not within one second"
4263         else
4264                 for (( i=0; i < 2; i++ )) ; do
4265                         local mtime2=`stat -c %Y $DIR1/$tfile`
4266                         [ "$mtime2" = $TEST_39_MTIME ] || \
4267                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4268
4269                         cancel_lru_locks $OSC
4270                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4271                 done
4272         fi
4273 }
4274 run_test 39h "write, utime within one second, stat ============="
4275
4276 test_39i() {
4277         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4278
4279         touch $DIR1/$tfile
4280         sleep 1
4281
4282         echo hello >> $DIR1/$tfile
4283         local mtime1=`stat -c %Y $DIR1/$tfile`
4284
4285         mv $DIR1/$tfile $DIR1/$tfile-1
4286
4287         for (( i=0; i < 2; i++ )) ; do
4288                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4289
4290                 [ "$mtime1" = "$mtime2" ] || \
4291                         error "lost mtime: $mtime2, should be $mtime1"
4292
4293                 cancel_lru_locks $OSC
4294                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4295         done
4296 }
4297 run_test 39i "write, rename, stat =============================="
4298
4299 test_39j() {
4300         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4301
4302         start_full_debug_logging
4303         touch $DIR1/$tfile
4304         sleep 1
4305
4306         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4307         lctl set_param fail_loc=0x80000412
4308         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4309                 error "multiop failed"
4310         local multipid=$!
4311         local mtime1=`stat -c %Y $DIR1/$tfile`
4312
4313         mv $DIR1/$tfile $DIR1/$tfile-1
4314
4315         kill -USR1 $multipid
4316         wait $multipid || error "multiop close failed"
4317
4318         for (( i=0; i < 2; i++ )) ; do
4319                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4320                 [ "$mtime1" = "$mtime2" ] ||
4321                         error "mtime is lost on close: $mtime2, " \
4322                               "should be $mtime1"
4323
4324                 cancel_lru_locks
4325                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4326         done
4327         lctl set_param fail_loc=0
4328         stop_full_debug_logging
4329 }
4330 run_test 39j "write, rename, close, stat ======================="
4331
4332 test_39k() {
4333         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4334
4335         touch $DIR1/$tfile
4336         sleep 1
4337
4338         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4339         local multipid=$!
4340         local mtime1=`stat -c %Y $DIR1/$tfile`
4341
4342         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4343
4344         kill -USR1 $multipid
4345         wait $multipid || error "multiop close failed"
4346
4347         for (( i=0; i < 2; i++ )) ; do
4348                 local mtime2=`stat -c %Y $DIR1/$tfile`
4349
4350                 [ "$mtime2" = $TEST_39_MTIME ] || \
4351                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4352
4353                 cancel_lru_locks
4354                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4355         done
4356 }
4357 run_test 39k "write, utime, close, stat ========================"
4358
4359 # this should be set to future
4360 TEST_39_ATIME=`date -d "1 year" +%s`
4361
4362 test_39l() {
4363         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4364         remote_mds_nodsh && skip "remote MDS with nodsh"
4365
4366         local atime_diff=$(do_facet $SINGLEMDS \
4367                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4368         rm -rf $DIR/$tdir
4369         mkdir -p $DIR/$tdir
4370
4371         # test setting directory atime to future
4372         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4373         local atime=$(stat -c %X $DIR/$tdir)
4374         [ "$atime" = $TEST_39_ATIME ] ||
4375                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4376
4377         # test setting directory atime from future to now
4378         local now=$(date +%s)
4379         touch -a -d @$now $DIR/$tdir
4380
4381         atime=$(stat -c %X $DIR/$tdir)
4382         [ "$atime" -eq "$now"  ] ||
4383                 error "atime is not updated from future: $atime, $now"
4384
4385         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4386         sleep 3
4387
4388         # test setting directory atime when now > dir atime + atime_diff
4389         local d1=$(date +%s)
4390         ls $DIR/$tdir
4391         local d2=$(date +%s)
4392         cancel_lru_locks mdc
4393         atime=$(stat -c %X $DIR/$tdir)
4394         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4395                 error "atime is not updated  : $atime, should be $d2"
4396
4397         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4398         sleep 3
4399
4400         # test not setting directory atime when now < dir atime + atime_diff
4401         ls $DIR/$tdir
4402         cancel_lru_locks mdc
4403         atime=$(stat -c %X $DIR/$tdir)
4404         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4405                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4406
4407         do_facet $SINGLEMDS \
4408                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4409 }
4410 run_test 39l "directory atime update ==========================="
4411
4412 test_39m() {
4413         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4414
4415         touch $DIR1/$tfile
4416         sleep 2
4417         local far_past_mtime=$(date -d "May 29 1953" +%s)
4418         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4419
4420         touch -m -d @$far_past_mtime $DIR1/$tfile
4421         touch -a -d @$far_past_atime $DIR1/$tfile
4422
4423         for (( i=0; i < 2; i++ )) ; do
4424                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4425                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4426                         error "atime or mtime set incorrectly"
4427
4428                 cancel_lru_locks $OSC
4429                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4430         done
4431 }
4432 run_test 39m "test atime and mtime before 1970"
4433
4434 test_39n() { # LU-3832
4435         remote_mds_nodsh && skip "remote MDS with nodsh"
4436
4437         local atime_diff=$(do_facet $SINGLEMDS \
4438                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4439         local atime0
4440         local atime1
4441         local atime2
4442
4443         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4444
4445         rm -rf $DIR/$tfile
4446         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4447         atime0=$(stat -c %X $DIR/$tfile)
4448
4449         sleep 5
4450         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4451         atime1=$(stat -c %X $DIR/$tfile)
4452
4453         sleep 5
4454         cancel_lru_locks mdc
4455         cancel_lru_locks osc
4456         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4457         atime2=$(stat -c %X $DIR/$tfile)
4458
4459         do_facet $SINGLEMDS \
4460                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4461
4462         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4463         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4464 }
4465 run_test 39n "check that O_NOATIME is honored"
4466
4467 test_39o() {
4468         TESTDIR=$DIR/$tdir/$tfile
4469         [ -e $TESTDIR ] && rm -rf $TESTDIR
4470         mkdir -p $TESTDIR
4471         cd $TESTDIR
4472         links1=2
4473         ls
4474         mkdir a b
4475         ls
4476         links2=$(stat -c %h .)
4477         [ $(($links1 + 2)) != $links2 ] &&
4478                 error "wrong links count $(($links1 + 2)) != $links2"
4479         rmdir b
4480         links3=$(stat -c %h .)
4481         [ $(($links1 + 1)) != $links3 ] &&
4482                 error "wrong links count $links1 != $links3"
4483         return 0
4484 }
4485 run_test 39o "directory cached attributes updated after create"
4486
4487 test_39p() {
4488         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4489
4490         local MDTIDX=1
4491         TESTDIR=$DIR/$tdir/$tdir
4492         [ -e $TESTDIR ] && rm -rf $TESTDIR
4493         test_mkdir -p $TESTDIR
4494         cd $TESTDIR
4495         links1=2
4496         ls
4497         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4498         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4499         ls
4500         links2=$(stat -c %h .)
4501         [ $(($links1 + 2)) != $links2 ] &&
4502                 error "wrong links count $(($links1 + 2)) != $links2"
4503         rmdir remote_dir2
4504         links3=$(stat -c %h .)
4505         [ $(($links1 + 1)) != $links3 ] &&
4506                 error "wrong links count $links1 != $links3"
4507         return 0
4508 }
4509 run_test 39p "remote directory cached attributes updated after create ========"
4510
4511 test_39r() {
4512         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
4513                 skip "no atime update on old OST"
4514         if [ "$ost1_FSTYPE" != ldiskfs ]; then
4515                 skip_env "ldiskfs only test"
4516         fi
4517
4518         local saved_adiff
4519         saved_adiff=$(do_facet ost1 \
4520                 lctl get_param -n obdfilter.*OST0000.atime_diff)
4521         stack_trap "do_facet ost1 \
4522                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
4523
4524         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
4525
4526         $LFS setstripe -i 0 $DIR/$tfile
4527         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
4528                 error "can't write initial file"
4529         cancel_lru_locks osc
4530
4531         # exceed atime_diff and access file
4532         sleep 6
4533         dd if=$DIR/$tfile of=/dev/null || error "can't udpate atime"
4534
4535         local atime_cli=$(stat -c %X $DIR/$tfile)
4536         echo "client atime: $atime_cli"
4537         # allow atime update to be written to device
4538         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
4539         sleep 5
4540
4541         local ostdev=$(ostdevname 1)
4542         local fid=($(lfs getstripe -y $DIR/$tfile |
4543                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
4544         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
4545         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
4546
4547         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
4548         local atime_ost=$(do_facet ost1 "$cmd" |&
4549                           awk -F'[: ]' '/atime:/ { print $4 }')
4550         (( atime_cli == atime_ost )) ||
4551                 error "atime on client $atime_cli != ost $atime_ost"
4552 }
4553 run_test 39r "lazy atime update on OST"
4554
4555 test_39q() { # LU-8041
4556         local testdir=$DIR/$tdir
4557         mkdir -p $testdir
4558         multiop_bg_pause $testdir D_c || error "multiop failed"
4559         local multipid=$!
4560         cancel_lru_locks mdc
4561         kill -USR1 $multipid
4562         local atime=$(stat -c %X $testdir)
4563         [ "$atime" -ne 0 ] || error "atime is zero"
4564 }
4565 run_test 39q "close won't zero out atime"
4566
4567 test_40() {
4568         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
4569         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
4570                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
4571         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
4572                 error "$tfile is not 4096 bytes in size"
4573 }
4574 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
4575
4576 test_41() {
4577         # bug 1553
4578         small_write $DIR/f41 18
4579 }
4580 run_test 41 "test small file write + fstat ====================="
4581
4582 count_ost_writes() {
4583         lctl get_param -n ${OSC}.*.stats |
4584                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
4585                         END { printf("%0.0f", writes) }'
4586 }
4587
4588 # decent default
4589 WRITEBACK_SAVE=500
4590 DIRTY_RATIO_SAVE=40
4591 MAX_DIRTY_RATIO=50
4592 BG_DIRTY_RATIO_SAVE=10
4593 MAX_BG_DIRTY_RATIO=25
4594
4595 start_writeback() {
4596         trap 0
4597         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
4598         # dirty_ratio, dirty_background_ratio
4599         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4600                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
4601                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
4602                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
4603         else
4604                 # if file not here, we are a 2.4 kernel
4605                 kill -CONT `pidof kupdated`
4606         fi
4607 }
4608
4609 stop_writeback() {
4610         # setup the trap first, so someone cannot exit the test at the
4611         # exact wrong time and mess up a machine
4612         trap start_writeback EXIT
4613         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
4614         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4615                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
4616                 sysctl -w vm.dirty_writeback_centisecs=0
4617                 sysctl -w vm.dirty_writeback_centisecs=0
4618                 # save and increase /proc/sys/vm/dirty_ratio
4619                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
4620                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
4621                 # save and increase /proc/sys/vm/dirty_background_ratio
4622                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
4623                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
4624         else
4625                 # if file not here, we are a 2.4 kernel
4626                 kill -STOP `pidof kupdated`
4627         fi
4628 }
4629
4630 # ensure that all stripes have some grant before we test client-side cache
4631 setup_test42() {
4632         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
4633                 dd if=/dev/zero of=$i bs=4k count=1
4634                 rm $i
4635         done
4636 }
4637
4638 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
4639 # file truncation, and file removal.
4640 test_42a() {
4641         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4642
4643         setup_test42
4644         cancel_lru_locks $OSC
4645         stop_writeback
4646         sync; sleep 1; sync # just to be safe
4647         BEFOREWRITES=`count_ost_writes`
4648         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
4649         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
4650         AFTERWRITES=`count_ost_writes`
4651         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
4652                 error "$BEFOREWRITES < $AFTERWRITES"
4653         start_writeback
4654 }
4655 run_test 42a "ensure that we don't flush on close"
4656
4657 test_42b() {
4658         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4659
4660         setup_test42
4661         cancel_lru_locks $OSC
4662         stop_writeback
4663         sync
4664         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
4665         BEFOREWRITES=$(count_ost_writes)
4666         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
4667         AFTERWRITES=$(count_ost_writes)
4668         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4669                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
4670         fi
4671         BEFOREWRITES=$(count_ost_writes)
4672         sync || error "sync: $?"
4673         AFTERWRITES=$(count_ost_writes)
4674         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4675                 error "$BEFOREWRITES < $AFTERWRITES on sync"
4676         fi
4677         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
4678         start_writeback
4679         return 0
4680 }
4681 run_test 42b "test destroy of file with cached dirty data ======"
4682
4683 # if these tests just want to test the effect of truncation,
4684 # they have to be very careful.  consider:
4685 # - the first open gets a {0,EOF}PR lock
4686 # - the first write conflicts and gets a {0, count-1}PW
4687 # - the rest of the writes are under {count,EOF}PW
4688 # - the open for truncate tries to match a {0,EOF}PR
4689 #   for the filesize and cancels the PWs.
4690 # any number of fixes (don't get {0,EOF} on open, match
4691 # composite locks, do smarter file size management) fix
4692 # this, but for now we want these tests to verify that
4693 # the cancellation with truncate intent works, so we
4694 # start the file with a full-file pw lock to match against
4695 # until the truncate.
4696 trunc_test() {
4697         test=$1
4698         file=$DIR/$test
4699         offset=$2
4700         cancel_lru_locks $OSC
4701         stop_writeback
4702         # prime the file with 0,EOF PW to match
4703         touch $file
4704         $TRUNCATE $file 0
4705         sync; sync
4706         # now the real test..
4707         dd if=/dev/zero of=$file bs=1024 count=100
4708         BEFOREWRITES=`count_ost_writes`
4709         $TRUNCATE $file $offset
4710         cancel_lru_locks $OSC
4711         AFTERWRITES=`count_ost_writes`
4712         start_writeback
4713 }
4714
4715 test_42c() {
4716         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4717
4718         trunc_test 42c 1024
4719         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
4720                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
4721         rm $file
4722 }
4723 run_test 42c "test partial truncate of file with cached dirty data"
4724
4725 test_42d() {
4726         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4727
4728         trunc_test 42d 0
4729         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
4730                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
4731         rm $file
4732 }
4733 run_test 42d "test complete truncate of file with cached dirty data"
4734
4735 test_42e() { # bug22074
4736         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4737
4738         local TDIR=$DIR/${tdir}e
4739         local pages=16 # hardcoded 16 pages, don't change it.
4740         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
4741         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
4742         local max_dirty_mb
4743         local warmup_files
4744
4745         test_mkdir $DIR/${tdir}e
4746         $LFS setstripe -c 1 $TDIR
4747         createmany -o $TDIR/f $files
4748
4749         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
4750
4751         # we assume that with $OSTCOUNT files, at least one of them will
4752         # be allocated on OST0.
4753         warmup_files=$((OSTCOUNT * max_dirty_mb))
4754         createmany -o $TDIR/w $warmup_files
4755
4756         # write a large amount of data into one file and sync, to get good
4757         # avail_grant number from OST.
4758         for ((i=0; i<$warmup_files; i++)); do
4759                 idx=$($LFS getstripe -i $TDIR/w$i)
4760                 [ $idx -ne 0 ] && continue
4761                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
4762                 break
4763         done
4764         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
4765         sync
4766         $LCTL get_param $proc_osc0/cur_dirty_bytes
4767         $LCTL get_param $proc_osc0/cur_grant_bytes
4768
4769         # create as much dirty pages as we can while not to trigger the actual
4770         # RPCs directly. but depends on the env, VFS may trigger flush during this
4771         # period, hopefully we are good.
4772         for ((i=0; i<$warmup_files; i++)); do
4773                 idx=$($LFS getstripe -i $TDIR/w$i)
4774                 [ $idx -ne 0 ] && continue
4775                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
4776         done
4777         $LCTL get_param $proc_osc0/cur_dirty_bytes
4778         $LCTL get_param $proc_osc0/cur_grant_bytes
4779
4780         # perform the real test
4781         $LCTL set_param $proc_osc0/rpc_stats 0
4782         for ((;i<$files; i++)); do
4783                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
4784                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
4785         done
4786         sync
4787         $LCTL get_param $proc_osc0/rpc_stats
4788
4789         local percent=0
4790         local have_ppr=false
4791         $LCTL get_param $proc_osc0/rpc_stats |
4792                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
4793                         # skip lines until we are at the RPC histogram data
4794                         [ "$PPR" == "pages" ] && have_ppr=true && continue
4795                         $have_ppr || continue
4796
4797                         # we only want the percent stat for < 16 pages
4798                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
4799
4800                         percent=$((percent + WPCT))
4801                         if [[ $percent -gt 15 ]]; then
4802                                 error "less than 16-pages write RPCs" \
4803                                       "$percent% > 15%"
4804                                 break
4805                         fi
4806                 done
4807         rm -rf $TDIR
4808 }
4809 run_test 42e "verify sub-RPC writes are not done synchronously"
4810
4811 test_43A() { # was test_43
4812         test_mkdir $DIR/$tdir
4813         cp -p /bin/ls $DIR/$tdir/$tfile
4814         $MULTIOP $DIR/$tdir/$tfile Ow_c &
4815         pid=$!
4816         # give multiop a chance to open
4817         sleep 1
4818
4819         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
4820         kill -USR1 $pid
4821 }
4822 run_test 43A "execution of file opened for write should return -ETXTBSY"
4823
4824 test_43a() {
4825         test_mkdir $DIR/$tdir
4826         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4827         $DIR/$tdir/sleep 60 &
4828         SLEEP_PID=$!
4829         # Make sure exec of $tdir/sleep wins race with truncate
4830         sleep 1
4831         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
4832         kill $SLEEP_PID
4833 }
4834 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
4835
4836 test_43b() {
4837         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4838
4839         test_mkdir $DIR/$tdir
4840         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4841         $DIR/$tdir/sleep 60 &
4842         SLEEP_PID=$!
4843         # Make sure exec of $tdir/sleep wins race with truncate
4844         sleep 1
4845         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
4846         kill $SLEEP_PID
4847 }
4848 run_test 43b "truncate of file being executed should return -ETXTBSY"
4849
4850 test_43c() {
4851         local testdir="$DIR/$tdir"
4852         test_mkdir $testdir
4853         cp $SHELL $testdir/
4854         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
4855                 ( cd $testdir && md5sum -c )
4856 }
4857 run_test 43c "md5sum of copy into lustre"
4858
4859 test_44A() { # was test_44
4860         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4861
4862         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
4863         dd if=$DIR/f1 bs=4k count=1 > /dev/null
4864 }
4865 run_test 44A "zero length read from a sparse stripe"
4866
4867 test_44a() {
4868         local nstripe=$($LCTL lov_getconfig $DIR | grep default_stripe_count: |
4869                 awk '{ print $2 }')
4870         [ -z "$nstripe" ] && skip "can't get stripe info"
4871         [[ $nstripe -gt $OSTCOUNT ]] &&
4872                 skip "Wrong default_stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
4873
4874         local stride=$($LCTL lov_getconfig $DIR | grep default_stripe_size: |
4875                 awk '{ print $2 }')
4876         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
4877                 nstripe=$($LCTL lov_getconfig $DIR | grep obd_count: |
4878                         awk '{ print $2 }')
4879         fi
4880
4881         OFFSETS="0 $((stride/2)) $((stride-1))"
4882         for offset in $OFFSETS; do
4883                 for i in $(seq 0 $((nstripe-1))); do
4884                         local GLOBALOFFSETS=""
4885                         # size in Bytes
4886                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
4887                         local myfn=$DIR/d44a-$size
4888                         echo "--------writing $myfn at $size"
4889                         ll_sparseness_write $myfn $size ||
4890                                 error "ll_sparseness_write"
4891                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
4892                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4893                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4894
4895                         for j in $(seq 0 $((nstripe-1))); do
4896                                 # size in Bytes
4897                                 size=$((((j + $nstripe )*$stride + $offset)))
4898                                 ll_sparseness_write $myfn $size ||
4899                                         error "ll_sparseness_write"
4900                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
4901                         done
4902                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4903                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4904                         rm -f $myfn
4905                 done
4906         done
4907 }
4908 run_test 44a "test sparse pwrite ==============================="
4909
4910 dirty_osc_total() {
4911         tot=0
4912         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
4913                 tot=$(($tot + $d))
4914         done
4915         echo $tot
4916 }
4917 do_dirty_record() {
4918         before=`dirty_osc_total`
4919         echo executing "\"$*\""
4920         eval $*
4921         after=`dirty_osc_total`
4922         echo before $before, after $after
4923 }
4924 test_45() {
4925         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4926
4927         f="$DIR/f45"
4928         # Obtain grants from OST if it supports it
4929         echo blah > ${f}_grant
4930         stop_writeback
4931         sync
4932         do_dirty_record "echo blah > $f"
4933         [[ $before -eq $after ]] && error "write wasn't cached"
4934         do_dirty_record "> $f"
4935         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
4936         do_dirty_record "echo blah > $f"
4937         [[ $before -eq $after ]] && error "write wasn't cached"
4938         do_dirty_record "sync"
4939         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
4940         do_dirty_record "echo blah > $f"
4941         [[ $before -eq $after ]] && error "write wasn't cached"
4942         do_dirty_record "cancel_lru_locks osc"
4943         [[ $before -gt $after ]] ||
4944                 error "lock cancellation didn't lower dirty count"
4945         start_writeback
4946 }
4947 run_test 45 "osc io page accounting ============================"
4948
4949 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
4950 # test tickles a bug where re-dirtying a page was failing to be mapped to the
4951 # objects offset and an assert hit when an rpc was built with 1023's mapped
4952 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
4953 test_46() {
4954         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4955
4956         f="$DIR/f46"
4957         stop_writeback
4958         sync
4959         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
4960         sync
4961         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
4962         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
4963         sync
4964         start_writeback
4965 }
4966 run_test 46 "dirtying a previously written page ================"
4967
4968 # test_47 is removed "Device nodes check" is moved to test_28
4969
4970 test_48a() { # bug 2399
4971         [ "$mds1_FSTYPE" = "zfs" ] &&
4972         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
4973                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
4974
4975         test_mkdir $DIR/$tdir
4976         cd $DIR/$tdir
4977         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
4978         test_mkdir $DIR/$tdir
4979         touch foo || error "'touch foo' failed after recreating cwd"
4980         test_mkdir bar
4981         touch .foo || error "'touch .foo' failed after recreating cwd"
4982         test_mkdir .bar
4983         ls . > /dev/null || error "'ls .' failed after recreating cwd"
4984         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
4985         cd . || error "'cd .' failed after recreating cwd"
4986         mkdir . && error "'mkdir .' worked after recreating cwd"
4987         rmdir . && error "'rmdir .' worked after recreating cwd"
4988         ln -s . baz || error "'ln -s .' failed after recreating cwd"
4989         cd .. || error "'cd ..' failed after recreating cwd"
4990 }
4991 run_test 48a "Access renamed working dir (should return errors)="
4992
4993 test_48b() { # bug 2399
4994         rm -rf $DIR/$tdir
4995         test_mkdir $DIR/$tdir
4996         cd $DIR/$tdir
4997         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
4998         touch foo && error "'touch foo' worked after removing cwd"
4999         mkdir foo && error "'mkdir foo' worked after removing cwd"
5000         touch .foo && error "'touch .foo' worked after removing cwd"
5001         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5002         ls . > /dev/null && error "'ls .' worked after removing cwd"
5003         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5004         mkdir . && error "'mkdir .' worked after removing cwd"
5005         rmdir . && error "'rmdir .' worked after removing cwd"
5006         ln -s . foo && error "'ln -s .' worked after removing cwd"
5007         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5008 }
5009 run_test 48b "Access removed working dir (should return errors)="
5010
5011 test_48c() { # bug 2350
5012         #lctl set_param debug=-1
5013         #set -vx
5014         rm -rf $DIR/$tdir
5015         test_mkdir -p $DIR/$tdir/dir
5016         cd $DIR/$tdir/dir
5017         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5018         $TRACE touch foo && error "touch foo worked after removing cwd"
5019         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5020         touch .foo && error "touch .foo worked after removing cwd"
5021         mkdir .foo && error "mkdir .foo worked after removing cwd"
5022         $TRACE ls . && error "'ls .' worked after removing cwd"
5023         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5024         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5025         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5026         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5027         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5028 }
5029 run_test 48c "Access removed working subdir (should return errors)"
5030
5031 test_48d() { # bug 2350
5032         #lctl set_param debug=-1
5033         #set -vx
5034         rm -rf $DIR/$tdir
5035         test_mkdir -p $DIR/$tdir/dir
5036         cd $DIR/$tdir/dir
5037         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5038         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5039         $TRACE touch foo && error "'touch foo' worked after removing parent"
5040         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5041         touch .foo && error "'touch .foo' worked after removing parent"
5042         mkdir .foo && error "mkdir .foo worked after removing parent"
5043         $TRACE ls . && error "'ls .' worked after removing parent"
5044         $TRACE ls .. && error "'ls ..' worked after removing parent"
5045         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5046         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5047         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5048         true
5049 }
5050 run_test 48d "Access removed parent subdir (should return errors)"
5051
5052 test_48e() { # bug 4134
5053         #lctl set_param debug=-1
5054         #set -vx
5055         rm -rf $DIR/$tdir
5056         test_mkdir -p $DIR/$tdir/dir
5057         cd $DIR/$tdir/dir
5058         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5059         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5060         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5061         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5062         # On a buggy kernel addition of "touch foo" after cd .. will
5063         # produce kernel oops in lookup_hash_it
5064         touch ../foo && error "'cd ..' worked after recreate parent"
5065         cd $DIR
5066         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5067 }
5068 run_test 48e "Access to recreated parent subdir (should return errors)"
5069
5070 test_49() { # LU-1030
5071         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5072         remote_ost_nodsh && skip "remote OST with nodsh"
5073
5074         # get ost1 size - $FSNAME-OST0000
5075         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5076                 awk '{ print $4 }')
5077         # write 800M at maximum
5078         [[ $ost1_size -lt 2 ]] && ost1_size=2
5079         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5080
5081         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5082         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5083         local dd_pid=$!
5084
5085         # change max_pages_per_rpc while writing the file
5086         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5087         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5088         # loop until dd process exits
5089         while ps ax -opid | grep -wq $dd_pid; do
5090                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5091                 sleep $((RANDOM % 5 + 1))
5092         done
5093         # restore original max_pages_per_rpc
5094         $LCTL set_param $osc1_mppc=$orig_mppc
5095         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5096 }
5097 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5098
5099 test_50() {
5100         # bug 1485
5101         test_mkdir $DIR/$tdir
5102         cd $DIR/$tdir
5103         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5104 }
5105 run_test 50 "special situations: /proc symlinks  ==============="
5106
5107 test_51a() {    # was test_51
5108         # bug 1516 - create an empty entry right after ".." then split dir
5109         test_mkdir -c1 $DIR/$tdir
5110         touch $DIR/$tdir/foo
5111         $MCREATE $DIR/$tdir/bar
5112         rm $DIR/$tdir/foo
5113         createmany -m $DIR/$tdir/longfile 201
5114         FNUM=202
5115         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5116                 $MCREATE $DIR/$tdir/longfile$FNUM
5117                 FNUM=$(($FNUM + 1))
5118                 echo -n "+"
5119         done
5120         echo
5121         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5122 }
5123 run_test 51a "special situations: split htree with empty entry =="
5124
5125 cleanup_print_lfs_df () {
5126         trap 0
5127         $LFS df
5128         $LFS df -i
5129 }
5130
5131 test_51b() {
5132         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5133
5134         local dir=$DIR/$tdir
5135         local nrdirs=$((65536 + 100))
5136
5137         # cleanup the directory
5138         rm -fr $dir
5139
5140         test_mkdir -c1 $dir
5141
5142         $LFS df
5143         $LFS df -i
5144         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5145         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5146         [[ $numfree -lt $nrdirs ]] &&
5147                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5148
5149         # need to check free space for the directories as well
5150         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5151         numfree=$(( blkfree / $(fs_inode_ksize) ))
5152         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5153
5154         trap cleanup_print_lfs_df EXIT
5155
5156         # create files
5157         createmany -d $dir/d $nrdirs || {
5158                 unlinkmany $dir/d $nrdirs
5159                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5160         }
5161
5162         # really created :
5163         nrdirs=$(ls -U $dir | wc -l)
5164
5165         # unlink all but 100 subdirectories, then check it still works
5166         local left=100
5167         local delete=$((nrdirs - left))
5168
5169         $LFS df
5170         $LFS df -i
5171
5172         # for ldiskfs the nlink count should be 1, but this is OSD specific
5173         # and so this is listed for informational purposes only
5174         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5175         unlinkmany -d $dir/d $delete ||
5176                 error "unlink of first $delete subdirs failed"
5177
5178         echo "nlink between: $(stat -c %h $dir)"
5179         local found=$(ls -U $dir | wc -l)
5180         [ $found -ne $left ] &&
5181                 error "can't find subdirs: found only $found, expected $left"
5182
5183         unlinkmany -d $dir/d $delete $left ||
5184                 error "unlink of second $left subdirs failed"
5185         # regardless of whether the backing filesystem tracks nlink accurately
5186         # or not, the nlink count shouldn't be more than "." and ".." here
5187         local after=$(stat -c %h $dir)
5188         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5189                 echo "nlink after: $after"
5190
5191         cleanup_print_lfs_df
5192 }
5193 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5194
5195 test_51d() {
5196         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5197         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5198
5199         test_mkdir $DIR/$tdir
5200         createmany -o $DIR/$tdir/t- 1000
5201         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5202         for N in $(seq 0 $((OSTCOUNT - 1))); do
5203                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
5204                         END { printf("%0.0f", objs) }' $TMP/$tfile)
5205                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5206                         '($1 == '$N') { objs += 1 } \
5207                         END { printf("%0.0f", objs) }')
5208                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
5209         done
5210         unlinkmany $DIR/$tdir/t- 1000
5211
5212         NLAST=0
5213         for N in $(seq 1 $((OSTCOUNT - 1))); do
5214                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
5215                         error "OST $N has less objects vs OST $NLAST" \
5216                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5217                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
5218                         error "OST $N has less objects vs OST $NLAST" \
5219                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5220
5221                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
5222                         error "OST $N has less #0 objects vs OST $NLAST" \
5223                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5224                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
5225                         error "OST $N has less #0 objects vs OST $NLAST" \
5226                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5227                 NLAST=$N
5228         done
5229         rm -f $TMP/$tfile
5230 }
5231 run_test 51d "check object distribution"
5232
5233 test_51e() {
5234         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5235                 skip_env "ldiskfs only test"
5236         fi
5237
5238         test_mkdir -c1 $DIR/$tdir
5239         test_mkdir -c1 $DIR/$tdir/d0
5240
5241         touch $DIR/$tdir/d0/foo
5242         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5243                 error "file exceed 65000 nlink limit!"
5244         unlinkmany $DIR/$tdir/d0/f- 65001
5245         return 0
5246 }
5247 run_test 51e "check file nlink limit"
5248
5249 test_51f() {
5250         test_mkdir $DIR/$tdir
5251
5252         local max=100000
5253         local ulimit_old=$(ulimit -n)
5254         local spare=20 # number of spare fd's for scripts/libraries, etc.
5255         local mdt=$($LFS getstripe -m $DIR/$tdir)
5256         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5257
5258         echo "MDT$mdt numfree=$numfree, max=$max"
5259         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5260         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5261                 while ! ulimit -n $((numfree + spare)); do
5262                         numfree=$((numfree * 3 / 4))
5263                 done
5264                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5265         else
5266                 echo "left ulimit at $ulimit_old"
5267         fi
5268
5269         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5270                 unlinkmany $DIR/$tdir/f $numfree
5271                 error "create+open $numfree files in $DIR/$tdir failed"
5272         }
5273         ulimit -n $ulimit_old
5274
5275         # if createmany exits at 120s there will be fewer than $numfree files
5276         unlinkmany $DIR/$tdir/f $numfree || true
5277 }
5278 run_test 51f "check many open files limit"
5279
5280 test_52a() {
5281         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5282         test_mkdir $DIR/$tdir
5283         touch $DIR/$tdir/foo
5284         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5285         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5286         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5287         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5288         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5289                                         error "link worked"
5290         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5291         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5292         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5293                                                      error "lsattr"
5294         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5295         cp -r $DIR/$tdir $TMP/
5296         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5297 }
5298 run_test 52a "append-only flag test (should return errors)"
5299
5300 test_52b() {
5301         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5302         test_mkdir $DIR/$tdir
5303         touch $DIR/$tdir/foo
5304         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5305         cat test > $DIR/$tdir/foo && error "cat test worked"
5306         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5307         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5308         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5309                                         error "link worked"
5310         echo foo >> $DIR/$tdir/foo && error "echo worked"
5311         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5312         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5313         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5314         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5315                                                         error "lsattr"
5316         chattr -i $DIR/$tdir/foo || error "chattr failed"
5317
5318         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5319 }
5320 run_test 52b "immutable flag test (should return errors) ======="
5321
5322 test_53() {
5323         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5324         remote_mds_nodsh && skip "remote MDS with nodsh"
5325         remote_ost_nodsh && skip "remote OST with nodsh"
5326
5327         local param
5328         local param_seq
5329         local ostname
5330         local mds_last
5331         local mds_last_seq
5332         local ost_last
5333         local ost_last_seq
5334         local ost_last_id
5335         local ostnum
5336         local node
5337         local found=false
5338         local support_last_seq=true
5339
5340         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5341                 support_last_seq=false
5342
5343         # only test MDT0000
5344         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5345         local value
5346         for value in $(do_facet $SINGLEMDS \
5347                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5348                 param=$(echo ${value[0]} | cut -d "=" -f1)
5349                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5350
5351                 if $support_last_seq; then
5352                         param_seq=$(echo $param |
5353                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5354                         mds_last_seq=$(do_facet $SINGLEMDS \
5355                                        $LCTL get_param -n $param_seq)
5356                 fi
5357                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5358
5359                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5360                 node=$(facet_active_host ost$((ostnum+1)))
5361                 param="obdfilter.$ostname.last_id"
5362                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5363                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5364                         ost_last_id=$ost_last
5365
5366                         if $support_last_seq; then
5367                                 ost_last_id=$(echo $ost_last |
5368                                               awk -F':' '{print $2}' |
5369                                               sed -e "s/^0x//g")
5370                                 ost_last_seq=$(echo $ost_last |
5371                                                awk -F':' '{print $1}')
5372                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5373                         fi
5374
5375                         if [[ $ost_last_id != $mds_last ]]; then
5376                                 error "$ost_last_id != $mds_last"
5377                         else
5378                                 found=true
5379                                 break
5380                         fi
5381                 done
5382         done
5383         $found || error "can not match last_seq/last_id for $mdtosc"
5384         return 0
5385 }
5386 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5387
5388 test_54a() {
5389         perl -MSocket -e ';' || skip "no Socket perl module installed"
5390
5391         $SOCKETSERVER $DIR/socket ||
5392                 error "$SOCKETSERVER $DIR/socket failed: $?"
5393         $SOCKETCLIENT $DIR/socket ||
5394                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5395         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5396 }
5397 run_test 54a "unix domain socket test =========================="
5398
5399 test_54b() {
5400         f="$DIR/f54b"
5401         mknod $f c 1 3
5402         chmod 0666 $f
5403         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5404 }
5405 run_test 54b "char device works in lustre ======================"
5406
5407 find_loop_dev() {
5408         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5409         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5410         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5411
5412         for i in $(seq 3 7); do
5413                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5414                 LOOPDEV=$LOOPBASE$i
5415                 LOOPNUM=$i
5416                 break
5417         done
5418 }
5419
5420 cleanup_54c() {
5421         local rc=0
5422         loopdev="$DIR/loop54c"
5423
5424         trap 0
5425         $UMOUNT $DIR/$tdir || rc=$?
5426         losetup -d $loopdev || true
5427         losetup -d $LOOPDEV || true
5428         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5429         return $rc
5430 }
5431
5432 test_54c() {
5433         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5434
5435         loopdev="$DIR/loop54c"
5436
5437         find_loop_dev
5438         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5439         trap cleanup_54c EXIT
5440         mknod $loopdev b 7 $LOOPNUM
5441         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5442         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5443         losetup $loopdev $DIR/$tfile ||
5444                 error "can't set up $loopdev for $DIR/$tfile"
5445         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5446         test_mkdir $DIR/$tdir
5447         mount -t ext2 $loopdev $DIR/$tdir ||
5448                 error "error mounting $loopdev on $DIR/$tdir"
5449         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5450                 error "dd write"
5451         df $DIR/$tdir
5452         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5453                 error "dd read"
5454         cleanup_54c
5455 }
5456 run_test 54c "block device works in lustre ====================="
5457
5458 test_54d() {
5459         f="$DIR/f54d"
5460         string="aaaaaa"
5461         mknod $f p
5462         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5463 }
5464 run_test 54d "fifo device works in lustre ======================"
5465
5466 test_54e() {
5467         f="$DIR/f54e"
5468         string="aaaaaa"
5469         cp -aL /dev/console $f
5470         echo $string > $f || error "echo $string to $f failed"
5471 }
5472 run_test 54e "console/tty device works in lustre ======================"
5473
5474 test_56a() {
5475         local numfiles=3
5476         local dir=$DIR/$tdir
5477
5478         rm -rf $dir
5479         test_mkdir -p $dir/dir
5480         for i in $(seq $numfiles); do
5481                 touch $dir/file$i
5482                 touch $dir/dir/file$i
5483         done
5484
5485         local numcomp=$($LFS getstripe --component-count $dir)
5486
5487         [[ $numcomp == 0 ]] && numcomp=1
5488
5489         # test lfs getstripe with --recursive
5490         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5491
5492         [[ $filenum -eq $((numfiles * 2)) ]] ||
5493                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5494         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5495         [[ $filenum -eq $numfiles ]] ||
5496                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5497         echo "$LFS getstripe showed obdidx or l_ost_idx"
5498
5499         # test lfs getstripe with file instead of dir
5500         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5501         [[ $filenum -eq 1 ]] ||
5502                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5503         echo "$LFS getstripe file1 passed"
5504
5505         #test lfs getstripe with --verbose
5506         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5507         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5508                 error "$LFS getstripe --verbose $dir: "\
5509                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5510         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5511                 error "$LFS getstripe $dir: showed lmm_magic"
5512
5513         #test lfs getstripe with -v prints lmm_fid
5514         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5515         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5516                 error "$LFS getstripe -v $dir: "\
5517                       "got $filenum want $((numfiles * numcomp)) lmm_fid"
5518         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5519                 error "$LFS getstripe $dir: showed lmm_fid by default"
5520         echo "$LFS getstripe --verbose passed"
5521
5522         #check for FID information
5523         local fid1=$($LFS getstripe --fid $dir/file1)
5524         local fid2=$($LFS getstripe --verbose $dir/file1 |
5525                      awk '/lmm_fid: / { print $2; exit; }')
5526         local fid3=$($LFS path2fid $dir/file1)
5527
5528         [ "$fid1" != "$fid2" ] &&
5529                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5530         [ "$fid1" != "$fid3" ] &&
5531                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5532         echo "$LFS getstripe --fid passed"
5533
5534         #test lfs getstripe with --obd
5535         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
5536                 error "$LFS getstripe --obd wrong_uuid: should return error"
5537
5538         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5539
5540         local ostidx=1
5541         local obduuid=$(ostuuid_from_index $ostidx)
5542         local found=$($LFS getstripe -r --obd $obduuid $dir |
5543                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
5544
5545         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
5546         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
5547                 ((filenum--))
5548         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
5549                 ((filenum--))
5550
5551         [[ $found -eq $filenum ]] ||
5552                 error "$LFS getstripe --obd: found $found expect $filenum"
5553         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
5554                 sed '/^[         ]*'${ostidx}'[  ]/d' |
5555                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
5556                 error "$LFS getstripe --obd: should not show file on other obd"
5557         echo "$LFS getstripe --obd passed"
5558 }
5559 run_test 56a "check $LFS getstripe"
5560
5561 test_56b() {
5562         local dir=$DIR/$tdir
5563         local numdirs=3
5564
5565         test_mkdir $dir
5566         for i in $(seq $numdirs); do
5567                 test_mkdir $dir/dir$i
5568         done
5569
5570         # test lfs getdirstripe default mode is non-recursion, which is
5571         # different from lfs getstripe
5572         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
5573
5574         [[ $dircnt -eq 1 ]] ||
5575                 error "$LFS getdirstripe: found $dircnt, not 1"
5576         dircnt=$($LFS getdirstripe --recursive $dir |
5577                 grep -c lmv_stripe_count)
5578         [[ $dircnt -eq $((numdirs + 1)) ]] ||
5579                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
5580 }
5581 run_test 56b "check $LFS getdirstripe"
5582
5583 test_56c() {
5584         remote_ost_nodsh && skip "remote OST with nodsh"
5585
5586         local ost_idx=0
5587         local ost_name=$(ostname_from_index $ost_idx)
5588         local old_status=$(ost_dev_status $ost_idx)
5589
5590         [[ -z "$old_status" ]] ||
5591                 skip_env "OST $ost_name is in $old_status status"
5592
5593         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
5594         [[ $OST1_VERSION -ge $(version_code 2.12.55) ]] && do_facet ost1 \
5595                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
5596         sleep_maxage
5597
5598         local new_status=$(ost_dev_status $ost_idx)
5599
5600         [[ "$new_status" =~ "D" ]] ||
5601                 error "$ost_name status is '$new_status', missing 'D'"
5602         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
5603                 [[ "$new_status" =~ "N" ]] ||
5604                         error "$ost_name status is '$new_status', missing 'N'"
5605         fi
5606
5607         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
5608         [[ $OST1_VERSION -ge $(version_code 2.12.55) ]] && do_facet ost1 \
5609                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
5610         sleep_maxage
5611
5612         new_status=$(ost_dev_status $ost_idx)
5613         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
5614                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
5615 }
5616 run_test 56c "check 'lfs df' showing device status"
5617
5618 NUMFILES=3
5619 NUMDIRS=3
5620 setup_56() {
5621         local local_tdir="$1"
5622         local local_numfiles="$2"
5623         local local_numdirs="$3"
5624         local dir_params="$4"
5625         local dir_stripe_params="$5"
5626
5627         if [ ! -d "$local_tdir" ] ; then
5628                 test_mkdir -p $dir_stripe_params $local_tdir
5629                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
5630                 for i in $(seq $local_numfiles) ; do
5631                         touch $local_tdir/file$i
5632                 done
5633                 for i in $(seq $local_numdirs) ; do
5634                         test_mkdir $dir_stripe_params $local_tdir/dir$i
5635                         for j in $(seq $local_numfiles) ; do
5636                                 touch $local_tdir/dir$i/file$j
5637                         done
5638                 done
5639         fi
5640 }
5641
5642 setup_56_special() {
5643         local local_tdir=$1
5644         local local_numfiles=$2
5645         local local_numdirs=$3
5646
5647         setup_56 $local_tdir $local_numfiles $local_numdirs
5648
5649         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
5650                 for i in $(seq $local_numfiles) ; do
5651                         mknod $local_tdir/loop${i}b b 7 $i
5652                         mknod $local_tdir/null${i}c c 1 3
5653                         ln -s $local_tdir/file1 $local_tdir/link${i}
5654                 done
5655                 for i in $(seq $local_numdirs) ; do
5656                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
5657                         mknod $local_tdir/dir$i/null${i}c c 1 3
5658                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
5659                 done
5660         fi
5661 }
5662
5663 test_56g() {
5664         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5665         local expected=$(($NUMDIRS + 2))
5666
5667         setup_56 $dir $NUMFILES $NUMDIRS
5668
5669         # test lfs find with -name
5670         for i in $(seq $NUMFILES) ; do
5671                 local nums=$($LFS find -name "*$i" $dir | wc -l)
5672
5673                 [ $nums -eq $expected ] ||
5674                         error "lfs find -name '*$i' $dir wrong: "\
5675                               "found $nums, expected $expected"
5676         done
5677 }
5678 run_test 56g "check lfs find -name"
5679
5680 test_56h() {
5681         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5682         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
5683
5684         setup_56 $dir $NUMFILES $NUMDIRS
5685
5686         # test lfs find with ! -name
5687         for i in $(seq $NUMFILES) ; do
5688                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
5689
5690                 [ $nums -eq $expected ] ||
5691                         error "lfs find ! -name '*$i' $dir wrong: "\
5692                               "found $nums, expected $expected"
5693         done
5694 }
5695 run_test 56h "check lfs find ! -name"
5696
5697 test_56i() {
5698         local dir=$DIR/$tdir
5699
5700         test_mkdir $dir
5701
5702         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
5703         local out=$($cmd)
5704
5705         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
5706 }
5707 run_test 56i "check 'lfs find -ost UUID' skips directories"
5708
5709 test_56j() {
5710         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5711
5712         setup_56_special $dir $NUMFILES $NUMDIRS
5713
5714         local expected=$((NUMDIRS + 1))
5715         local cmd="$LFS find -type d $dir"
5716         local nums=$($cmd | wc -l)
5717
5718         [ $nums -eq $expected ] ||
5719                 error "'$cmd' wrong: found $nums, expected $expected"
5720 }
5721 run_test 56j "check lfs find -type d"
5722
5723 test_56k() {
5724         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5725
5726         setup_56_special $dir $NUMFILES $NUMDIRS
5727
5728         local expected=$(((NUMDIRS + 1) * NUMFILES))
5729         local cmd="$LFS find -type f $dir"
5730         local nums=$($cmd | wc -l)
5731
5732         [ $nums -eq $expected ] ||
5733                 error "'$cmd' wrong: found $nums, expected $expected"
5734 }
5735 run_test 56k "check lfs find -type f"
5736
5737 test_56l() {
5738         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5739
5740         setup_56_special $dir $NUMFILES $NUMDIRS
5741
5742         local expected=$((NUMDIRS + NUMFILES))
5743         local cmd="$LFS find -type b $dir"
5744         local nums=$($cmd | wc -l)
5745
5746         [ $nums -eq $expected ] ||
5747                 error "'$cmd' wrong: found $nums, expected $expected"
5748 }
5749 run_test 56l "check lfs find -type b"
5750
5751 test_56m() {
5752         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5753
5754         setup_56_special $dir $NUMFILES $NUMDIRS
5755
5756         local expected=$((NUMDIRS + NUMFILES))
5757         local cmd="$LFS find -type c $dir"
5758         local nums=$($cmd | wc -l)
5759         [ $nums -eq $expected ] ||
5760                 error "'$cmd' wrong: found $nums, expected $expected"
5761 }
5762 run_test 56m "check lfs find -type c"
5763
5764 test_56n() {
5765         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5766         setup_56_special $dir $NUMFILES $NUMDIRS
5767
5768         local expected=$((NUMDIRS + NUMFILES))
5769         local cmd="$LFS find -type l $dir"
5770         local nums=$($cmd | wc -l)
5771
5772         [ $nums -eq $expected ] ||
5773                 error "'$cmd' wrong: found $nums, expected $expected"
5774 }
5775 run_test 56n "check lfs find -type l"
5776
5777 test_56o() {
5778         local dir=$DIR/$tdir
5779
5780         setup_56 $dir $NUMFILES $NUMDIRS
5781         utime $dir/file1 > /dev/null || error "utime (1)"
5782         utime $dir/file2 > /dev/null || error "utime (2)"
5783         utime $dir/dir1 > /dev/null || error "utime (3)"
5784         utime $dir/dir2 > /dev/null || error "utime (4)"
5785         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
5786         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
5787
5788         local expected=4
5789         local nums=$($LFS find -mtime +0 $dir | wc -l)
5790
5791         [ $nums -eq $expected ] ||
5792                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
5793
5794         expected=12
5795         cmd="$LFS find -mtime 0 $dir"
5796         nums=$($cmd | wc -l)
5797         [ $nums -eq $expected ] ||
5798                 error "'$cmd' wrong: found $nums, expected $expected"
5799 }
5800 run_test 56o "check lfs find -mtime for old files"
5801
5802 test_56ob() {
5803         local dir=$DIR/$tdir
5804         local expected=1
5805         local count=0
5806
5807         # just to make sure there is something that won't be found
5808         test_mkdir $dir
5809         touch $dir/$tfile.now
5810
5811         for age in year week day hour min; do
5812                 count=$((count + 1))
5813
5814                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
5815                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
5816                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
5817
5818                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
5819                 local nums=$($cmd | wc -l)
5820                 [ $nums -eq $expected ] ||
5821                         error "'$cmd' wrong: found $nums, expected $expected"
5822
5823                 cmd="$LFS find $dir -atime $count${age:0:1}"
5824                 nums=$($cmd | wc -l)
5825                 [ $nums -eq $expected ] ||
5826                         error "'$cmd' wrong: found $nums, expected $expected"
5827         done
5828
5829         sleep 2
5830         cmd="$LFS find $dir -ctime +1s -type f"
5831         nums=$($cmd | wc -l)
5832         (( $nums == $count * 2 + 1)) ||
5833                 error "'$cmd' wrong: found $nums, expected $((expected*2+1))"
5834 }
5835 run_test 56ob "check lfs find -atime -mtime -ctime with units"
5836
5837 test_newerXY_base() {
5838         local x=$1
5839         local y=$2
5840         local dir=$DIR/$tdir
5841         local ref
5842         local negref
5843
5844         if [ $y == "t" ]; then
5845                 ref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
5846         else
5847                 ref=$DIR/$tfile.newer
5848                 touch $ref || error "touch $ref failed"
5849         fi
5850         sleep 2
5851         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
5852         sleep 2
5853         if [ $y == "t" ]; then
5854                 negref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
5855         else
5856                 negref=$DIR/$tfile.newerneg
5857                 touch $negref || error "touch $negref failed"
5858         fi
5859
5860         local cmd="$LFS find $dir -newer$x$y $ref"
5861         local nums=$(eval $cmd | wc -l)
5862         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
5863
5864         [ $nums -eq $expected ] ||
5865                 error "'$cmd' wrong: found $nums, expected $expected"
5866
5867         cmd="$LFS find $dir ! -newer$x$y $negref"
5868         nums=$(eval $cmd | wc -l)
5869         [ $nums -eq $expected ] ||
5870                 error "'$cmd' wrong: found $nums, expected $expected"
5871
5872         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
5873         nums=$(eval $cmd | wc -l)
5874         [ $nums -eq $expected ] ||
5875                 error "'$cmd' wrong: found $nums, expected $expected"
5876
5877         rm -rf $DIR/*
5878 }
5879
5880 test_56oc() {
5881         test_newerXY_base "a" "a"
5882         test_newerXY_base "a" "m"
5883         test_newerXY_base "a" "c"
5884         test_newerXY_base "m" "a"
5885         test_newerXY_base "m" "m"
5886         test_newerXY_base "m" "c"
5887         test_newerXY_base "c" "a"
5888         test_newerXY_base "c" "m"
5889         test_newerXY_base "c" "c"
5890         test_newerXY_base "a" "t"
5891         test_newerXY_base "m" "t"
5892         test_newerXY_base "c" "t"
5893 }
5894 run_test 56oc "check lfs find -newerXY work"
5895
5896 test_56p() {
5897         [ $RUNAS_ID -eq $UID ] &&
5898                 skip_env "RUNAS_ID = UID = $UID -- skipping"
5899
5900         local dir=$DIR/$tdir
5901
5902         setup_56 $dir $NUMFILES $NUMDIRS
5903         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
5904
5905         local expected=$NUMFILES
5906         local cmd="$LFS find -uid $RUNAS_ID $dir"
5907         local nums=$($cmd | wc -l)
5908
5909         [ $nums -eq $expected ] ||
5910                 error "'$cmd' wrong: found $nums, expected $expected"
5911
5912         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
5913         cmd="$LFS find ! -uid $RUNAS_ID $dir"
5914         nums=$($cmd | wc -l)
5915         [ $nums -eq $expected ] ||
5916                 error "'$cmd' wrong: found $nums, expected $expected"
5917 }
5918 run_test 56p "check lfs find -uid and ! -uid"
5919
5920 test_56q() {
5921         [ $RUNAS_ID -eq $UID ] &&
5922                 skip_env "RUNAS_ID = UID = $UID -- skipping"
5923
5924         local dir=$DIR/$tdir
5925
5926         setup_56 $dir $NUMFILES $NUMDIRS
5927         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
5928
5929         local expected=$NUMFILES
5930         local cmd="$LFS find -gid $RUNAS_GID $dir"
5931         local nums=$($cmd | wc -l)
5932
5933         [ $nums -eq $expected ] ||
5934                 error "'$cmd' wrong: found $nums, expected $expected"
5935
5936         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
5937         cmd="$LFS find ! -gid $RUNAS_GID $dir"
5938         nums=$($cmd | wc -l)
5939         [ $nums -eq $expected ] ||
5940                 error "'$cmd' wrong: found $nums, expected $expected"
5941 }
5942 run_test 56q "check lfs find -gid and ! -gid"
5943
5944 test_56r() {
5945         local dir=$DIR/$tdir
5946
5947         setup_56 $dir $NUMFILES $NUMDIRS
5948
5949         local expected=12
5950         local cmd="$LFS find -size 0 -type f -lazy $dir"
5951         local nums=$($cmd | wc -l)
5952
5953         [ $nums -eq $expected ] ||
5954                 error "'$cmd' wrong: found $nums, expected $expected"
5955         cmd="$LFS find -size 0 -type f $dir"
5956         nums=$($cmd | wc -l)
5957         [ $nums -eq $expected ] ||
5958                 error "'$cmd' wrong: found $nums, expected $expected"
5959
5960         expected=0
5961         cmd="$LFS find ! -size 0 -type f -lazy $dir"
5962         nums=$($cmd | wc -l)
5963         [ $nums -eq $expected ] ||
5964                 error "'$cmd' wrong: found $nums, expected $expected"
5965         cmd="$LFS find ! -size 0 -type f $dir"
5966         nums=$($cmd | wc -l)
5967         [ $nums -eq $expected ] ||
5968                 error "'$cmd' wrong: found $nums, expected $expected"
5969
5970         echo "test" > $dir/$tfile
5971         echo "test2" > $dir/$tfile.2 && sync
5972         expected=1
5973         cmd="$LFS find -size 5 -type f -lazy $dir"
5974         nums=$($cmd | wc -l)
5975         [ $nums -eq $expected ] ||
5976                 error "'$cmd' wrong: found $nums, expected $expected"
5977         cmd="$LFS find -size 5 -type f $dir"
5978         nums=$($cmd | wc -l)
5979         [ $nums -eq $expected ] ||
5980                 error "'$cmd' wrong: found $nums, expected $expected"
5981
5982         expected=1
5983         cmd="$LFS find -size +5 -type f -lazy $dir"
5984         nums=$($cmd | wc -l)
5985         [ $nums -eq $expected ] ||
5986                 error "'$cmd' wrong: found $nums, expected $expected"
5987         cmd="$LFS find -size +5 -type f $dir"
5988         nums=$($cmd | wc -l)
5989         [ $nums -eq $expected ] ||
5990                 error "'$cmd' wrong: found $nums, expected $expected"
5991
5992         expected=2
5993         cmd="$LFS find -size +0 -type f -lazy $dir"
5994         nums=$($cmd | wc -l)
5995         [ $nums -eq $expected ] ||
5996                 error "'$cmd' wrong: found $nums, expected $expected"
5997         cmd="$LFS find -size +0 -type f $dir"
5998         nums=$($cmd | wc -l)
5999         [ $nums -eq $expected ] ||
6000                 error "'$cmd' wrong: found $nums, expected $expected"
6001
6002         expected=2
6003         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6004         nums=$($cmd | wc -l)
6005         [ $nums -eq $expected ] ||
6006                 error "'$cmd' wrong: found $nums, expected $expected"
6007         cmd="$LFS find ! -size -5 -type f $dir"
6008         nums=$($cmd | wc -l)
6009         [ $nums -eq $expected ] ||
6010                 error "'$cmd' wrong: found $nums, expected $expected"
6011
6012         expected=12
6013         cmd="$LFS find -size -5 -type f -lazy $dir"
6014         nums=$($cmd | wc -l)
6015         [ $nums -eq $expected ] ||
6016                 error "'$cmd' wrong: found $nums, expected $expected"
6017         cmd="$LFS find -size -5 -type f $dir"
6018         nums=$($cmd | wc -l)
6019         [ $nums -eq $expected ] ||
6020                 error "'$cmd' wrong: found $nums, expected $expected"
6021 }
6022 run_test 56r "check lfs find -size works"
6023
6024 test_56ra() {
6025         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6026                 skip "MDS < 2.12.58 doesn't return LSOM data"
6027         local dir=$DIR/$tdir
6028
6029         [[ $OSC == "mdc" ]] && skip "DoM files" && return
6030
6031         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6032
6033         cancel_lru_locks $OSC
6034
6035         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6036         local expected=12
6037         local cmd="$LFS find -size 0 -type f -lazy $dir"
6038         local nums=$($cmd | wc -l)
6039
6040         [ $nums -eq $expected ] ||
6041                 error "'$cmd' wrong: found $nums, expected $expected"
6042
6043         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6044         [ $rpcs_before -eq $rpcs_after ] ||
6045                 error "'$cmd' should not send glimpse RPCs to OST"
6046         cmd="$LFS find -size 0 -type f $dir"
6047         nums=$($cmd | wc -l)
6048         [ $nums -eq $expected ] ||
6049                 error "'$cmd' wrong: found $nums, expected $expected"
6050         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6051         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6052         $LCTL get_param osc.*.stats
6053         [ $rpcs_after -eq $((rpcs_before + 12)) ] ||
6054                 error "'$cmd' should send 12 glimpse RPCs to OST"
6055
6056         cancel_lru_locks $OSC
6057         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6058         expected=0
6059         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6060         nums=$($cmd | wc -l)
6061         [ $nums -eq $expected ] ||
6062                 error "'$cmd' wrong: found $nums, expected $expected"
6063         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6064         $LCTL get_param mdc.*.stats
6065         [ $rpcs_before -eq $rpcs_after ] ||
6066                 error "'$cmd' should not send glimpse RPCs to OST"
6067         cmd="$LFS find ! -size 0 -type f $dir"
6068         nums=$($cmd | wc -l)
6069         [ $nums -eq $expected ] ||
6070                 error "'$cmd' wrong: found $nums, expected $expected"
6071         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6072         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6073         [ $rpcs_after -eq $((rpcs_before + 12)) ] ||
6074                 error "'$cmd' should send 12 glimpse RPCs to OST"
6075
6076         echo "test" > $dir/$tfile
6077         echo "test2" > $dir/$tfile.2 && sync
6078         cancel_lru_locks $OSC
6079         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6080         expected=1
6081         cmd="$LFS find -size 5 -type f -lazy $dir"
6082         nums=$($cmd | wc -l)
6083         [ $nums -eq $expected ] ||
6084                 error "'$cmd' wrong: found $nums, expected $expected"
6085         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6086         [ $rpcs_before -eq $rpcs_after ] ||
6087                 error "'$cmd' should not send glimpse RPCs to OST"
6088         cmd="$LFS find -size 5 -type f $dir"
6089         nums=$($cmd | wc -l)
6090         [ $nums -eq $expected ] ||
6091                 error "'$cmd' wrong: found $nums, expected $expected"
6092         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6093         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6094         [ $rpcs_after -eq $((rpcs_before + 14)) ] ||
6095                 error "'$cmd' should send 14 glimpse RPCs to OST"
6096
6097         cancel_lru_locks $OSC
6098         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6099         expected=1
6100         cmd="$LFS find -size +5 -type f -lazy $dir"
6101         nums=$($cmd | wc -l)
6102         [ $nums -eq $expected ] ||
6103                 error "'$cmd' wrong: found $nums, expected $expected"
6104         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6105         [ $rpcs_before -eq $rpcs_after ] ||
6106                 error "'$cmd' should not send glimpse RPCs to OST"
6107         cmd="$LFS find -size +5 -type f $dir"
6108         nums=$($cmd | wc -l)
6109         [ $nums -eq $expected ] ||
6110                 error "'$cmd' wrong: found $nums, expected $expected"
6111         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6112         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6113         [ $rpcs_after -eq $((rpcs_before + 14)) ] ||
6114                 error "'$cmd' should send 14 glimpse RPCs to OST"
6115
6116         cancel_lru_locks $OSC
6117         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6118         expected=2
6119         cmd="$LFS find -size +0 -type f -lazy $dir"
6120         nums=$($cmd | wc -l)
6121         [ $nums -eq $expected ] ||
6122                 error "'$cmd' wrong: found $nums, expected $expected"
6123         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6124         [ $rpcs_before -eq $rpcs_after ] ||
6125                 error "'$cmd' should not send glimpse RPCs to OST"
6126         cmd="$LFS find -size +0 -type f $dir"
6127         nums=$($cmd | wc -l)
6128         [ $nums -eq $expected ] ||
6129                 error "'$cmd' wrong: found $nums, expected $expected"
6130         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6131         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6132         [ $rpcs_after -eq $((rpcs_before + 14)) ] ||
6133                 error "'$cmd' should send 14 glimpse RPCs to OST"
6134
6135         cancel_lru_locks $OSC
6136         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6137         expected=2
6138         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6139         nums=$($cmd | wc -l)
6140         [ $nums -eq $expected ] ||
6141                 error "'$cmd' wrong: found $nums, expected $expected"
6142         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6143         [ $rpcs_before -eq $rpcs_after ] ||
6144                 error "'$cmd' should not send glimpse RPCs to OST"
6145         cmd="$LFS find ! -size -5 -type f $dir"
6146         nums=$($cmd | wc -l)
6147         [ $nums -eq $expected ] ||
6148                 error "'$cmd' wrong: found $nums, expected $expected"
6149         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6150         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6151         [ $rpcs_after -eq $((rpcs_before + 14)) ] ||
6152                 error "'$cmd' should send 14 glimpse RPCs to OST"
6153
6154         cancel_lru_locks $OSC
6155         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6156         expected=12
6157         cmd="$LFS find -size -5 -type f -lazy $dir"
6158         nums=$($cmd | wc -l)
6159         [ $nums -eq $expected ] ||
6160                 error "'$cmd' wrong: found $nums, expected $expected"
6161         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6162         [ $rpcs_before -eq $rpcs_after ] ||
6163                 error "'$cmd' should not send glimpse RPCs to OST"
6164         cmd="$LFS find -size -5 -type f $dir"
6165         nums=$($cmd | wc -l)
6166         [ $nums -eq $expected ] ||
6167                 error "'$cmd' wrong: found $nums, expected $expected"
6168         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6169         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6170         [ $rpcs_after -eq $((rpcs_before + 14)) ] ||
6171                 error "'$cmd' should send 14 glimpse RPCs to OST"
6172 }
6173 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6174
6175 test_56s() { # LU-611 #LU-9369
6176         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6177
6178         local dir=$DIR/$tdir
6179         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6180
6181         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6182         for i in $(seq $NUMDIRS); do
6183                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6184         done
6185
6186         local expected=$NUMDIRS
6187         local cmd="$LFS find -c $OSTCOUNT $dir"
6188         local nums=$($cmd | wc -l)
6189
6190         [ $nums -eq $expected ] || {
6191                 $LFS getstripe -R $dir
6192                 error "'$cmd' wrong: found $nums, expected $expected"
6193         }
6194
6195         expected=$((NUMDIRS + onestripe))
6196         cmd="$LFS find -stripe-count +0 -type f $dir"
6197         nums=$($cmd | wc -l)
6198         [ $nums -eq $expected ] || {
6199                 $LFS getstripe -R $dir
6200                 error "'$cmd' wrong: found $nums, expected $expected"
6201         }
6202
6203         expected=$onestripe
6204         cmd="$LFS find -stripe-count 1 -type f $dir"
6205         nums=$($cmd | wc -l)
6206         [ $nums -eq $expected ] || {
6207                 $LFS getstripe -R $dir
6208                 error "'$cmd' wrong: found $nums, expected $expected"
6209         }
6210
6211         cmd="$LFS find -stripe-count -2 -type f $dir"
6212         nums=$($cmd | wc -l)
6213         [ $nums -eq $expected ] || {
6214                 $LFS getstripe -R $dir
6215                 error "'$cmd' wrong: found $nums, expected $expected"
6216         }
6217
6218         expected=0
6219         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6220         nums=$($cmd | wc -l)
6221         [ $nums -eq $expected ] || {
6222                 $LFS getstripe -R $dir
6223                 error "'$cmd' wrong: found $nums, expected $expected"
6224         }
6225 }
6226 run_test 56s "check lfs find -stripe-count works"
6227
6228 test_56t() { # LU-611 #LU-9369
6229         local dir=$DIR/$tdir
6230
6231         setup_56 $dir 0 $NUMDIRS
6232         for i in $(seq $NUMDIRS); do
6233                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6234         done
6235
6236         local expected=$NUMDIRS
6237         local cmd="$LFS find -S 8M $dir"
6238         local nums=$($cmd | wc -l)
6239
6240         [ $nums -eq $expected ] || {
6241                 $LFS getstripe -R $dir
6242                 error "'$cmd' wrong: found $nums, expected $expected"
6243         }
6244         rm -rf $dir
6245
6246         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6247
6248         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6249
6250         expected=$(((NUMDIRS + 1) * NUMFILES))
6251         cmd="$LFS find -stripe-size 512k -type f $dir"
6252         nums=$($cmd | wc -l)
6253         [ $nums -eq $expected ] ||
6254                 error "'$cmd' wrong: found $nums, expected $expected"
6255
6256         cmd="$LFS find -stripe-size +320k -type f $dir"
6257         nums=$($cmd | wc -l)
6258         [ $nums -eq $expected ] ||
6259                 error "'$cmd' wrong: found $nums, expected $expected"
6260
6261         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6262         cmd="$LFS find -stripe-size +200k -type f $dir"
6263         nums=$($cmd | wc -l)
6264         [ $nums -eq $expected ] ||
6265                 error "'$cmd' wrong: found $nums, expected $expected"
6266
6267         cmd="$LFS find -stripe-size -640k -type f $dir"
6268         nums=$($cmd | wc -l)
6269         [ $nums -eq $expected ] ||
6270                 error "'$cmd' wrong: found $nums, expected $expected"
6271
6272         expected=4
6273         cmd="$LFS find -stripe-size 256k -type f $dir"
6274         nums=$($cmd | wc -l)
6275         [ $nums -eq $expected ] ||
6276                 error "'$cmd' wrong: found $nums, expected $expected"
6277
6278         cmd="$LFS find -stripe-size -320k -type f $dir"
6279         nums=$($cmd | wc -l)
6280         [ $nums -eq $expected ] ||
6281                 error "'$cmd' wrong: found $nums, expected $expected"
6282
6283         expected=0
6284         cmd="$LFS find -stripe-size 1024k -type f $dir"
6285         nums=$($cmd | wc -l)
6286         [ $nums -eq $expected ] ||
6287                 error "'$cmd' wrong: found $nums, expected $expected"
6288 }
6289 run_test 56t "check lfs find -stripe-size works"
6290
6291 test_56u() { # LU-611
6292         local dir=$DIR/$tdir
6293
6294         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6295
6296         if [[ $OSTCOUNT -gt 1 ]]; then
6297                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6298                 onestripe=4
6299         else
6300                 onestripe=0
6301         fi
6302
6303         local expected=$(((NUMDIRS + 1) * NUMFILES))
6304         local cmd="$LFS find -stripe-index 0 -type f $dir"
6305         local nums=$($cmd | wc -l)
6306
6307         [ $nums -eq $expected ] ||
6308                 error "'$cmd' wrong: found $nums, expected $expected"
6309
6310         expected=$onestripe
6311         cmd="$LFS find -stripe-index 1 -type f $dir"
6312         nums=$($cmd | wc -l)
6313         [ $nums -eq $expected ] ||
6314                 error "'$cmd' wrong: found $nums, expected $expected"
6315
6316         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6317         nums=$($cmd | wc -l)
6318         [ $nums -eq $expected ] ||
6319                 error "'$cmd' wrong: found $nums, expected $expected"
6320
6321         expected=0
6322         # This should produce an error and not return any files
6323         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
6324         nums=$($cmd 2>/dev/null | wc -l)
6325         [ $nums -eq $expected ] ||
6326                 error "'$cmd' wrong: found $nums, expected $expected"
6327
6328         if [[ $OSTCOUNT -gt 1 ]]; then
6329                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
6330                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
6331                 nums=$($cmd | wc -l)
6332                 [ $nums -eq $expected ] ||
6333                         error "'$cmd' wrong: found $nums, expected $expected"
6334         fi
6335 }
6336 run_test 56u "check lfs find -stripe-index works"
6337
6338 test_56v() {
6339         local mdt_idx=0
6340         local dir=$DIR/$tdir
6341
6342         setup_56 $dir $NUMFILES $NUMDIRS
6343
6344         UUID=$(mdtuuid_from_index $mdt_idx $dir)
6345         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
6346
6347         for file in $($LFS find -m $UUID $dir); do
6348                 file_midx=$($LFS getstripe -m $file)
6349                 [ $file_midx -eq $mdt_idx ] ||
6350                         error "lfs find -m $UUID != getstripe -m $file_midx"
6351         done
6352 }
6353 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
6354
6355 test_56w() {
6356         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6357         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6358
6359         local dir=$DIR/$tdir
6360
6361         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
6362
6363         local stripe_size=$($LFS getstripe -S -d $dir) ||
6364                 error "$LFS getstripe -S -d $dir failed"
6365         stripe_size=${stripe_size%% *}
6366
6367         local file_size=$((stripe_size * OSTCOUNT))
6368         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
6369         local required_space=$((file_num * file_size))
6370         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
6371                            head -n1)
6372         [[ $free_space -le $((required_space / 1024)) ]] &&
6373                 skip_env "need $required_space, have $free_space kbytes"
6374
6375         local dd_bs=65536
6376         local dd_count=$((file_size / dd_bs))
6377
6378         # write data into the files
6379         local i
6380         local j
6381         local file
6382
6383         for i in $(seq $NUMFILES); do
6384                 file=$dir/file$i
6385                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6386                         error "write data into $file failed"
6387         done
6388         for i in $(seq $NUMDIRS); do
6389                 for j in $(seq $NUMFILES); do
6390                         file=$dir/dir$i/file$j
6391                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6392                                 error "write data into $file failed"
6393                 done
6394         done
6395
6396         # $LFS_MIGRATE will fail if hard link migration is unsupported
6397         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
6398                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
6399                         error "creating links to $dir/dir1/file1 failed"
6400         fi
6401
6402         local expected=-1
6403
6404         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
6405
6406         # lfs_migrate file
6407         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
6408
6409         echo "$cmd"
6410         eval $cmd || error "$cmd failed"
6411
6412         check_stripe_count $dir/file1 $expected
6413
6414         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
6415         then
6416                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
6417                 # OST 1 if it is on OST 0. This file is small enough to
6418                 # be on only one stripe.
6419                 file=$dir/migr_1_ost
6420                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
6421                         error "write data into $file failed"
6422                 local obdidx=$($LFS getstripe -i $file)
6423                 local oldmd5=$(md5sum $file)
6424                 local newobdidx=0
6425
6426                 [[ $obdidx -eq 0 ]] && newobdidx=1
6427                 cmd="$LFS migrate -i $newobdidx $file"
6428                 echo $cmd
6429                 eval $cmd || error "$cmd failed"
6430
6431                 local realobdix=$($LFS getstripe -i $file)
6432                 local newmd5=$(md5sum $file)
6433
6434                 [[ $newobdidx -ne $realobdix ]] &&
6435                         error "new OST is different (was=$obdidx, "\
6436                               "wanted=$newobdidx, got=$realobdix)"
6437                 [[ "$oldmd5" != "$newmd5" ]] &&
6438                         error "md5sum differ: $oldmd5, $newmd5"
6439         fi
6440
6441         # lfs_migrate dir
6442         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
6443         echo "$cmd"
6444         eval $cmd || error "$cmd failed"
6445
6446         for j in $(seq $NUMFILES); do
6447                 check_stripe_count $dir/dir1/file$j $expected
6448         done
6449
6450         # lfs_migrate works with lfs find
6451         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
6452              $LFS_MIGRATE -y -c $expected"
6453         echo "$cmd"
6454         eval $cmd || error "$cmd failed"
6455
6456         for i in $(seq 2 $NUMFILES); do
6457                 check_stripe_count $dir/file$i $expected
6458         done
6459         for i in $(seq 2 $NUMDIRS); do
6460                 for j in $(seq $NUMFILES); do
6461                 check_stripe_count $dir/dir$i/file$j $expected
6462                 done
6463         done
6464 }
6465 run_test 56w "check lfs_migrate -c stripe_count works"
6466
6467 test_56wb() {
6468         local file1=$DIR/$tdir/file1
6469         local create_pool=false
6470         local initial_pool=$($LFS getstripe -p $DIR)
6471         local pool_list=()
6472         local pool=""
6473
6474         echo -n "Creating test dir..."
6475         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6476         echo "done."
6477
6478         echo -n "Creating test file..."
6479         touch $file1 || error "cannot create file"
6480         echo "done."
6481
6482         echo -n "Detecting existing pools..."
6483         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
6484
6485         if [ ${#pool_list[@]} -gt 0 ]; then
6486                 echo "${pool_list[@]}"
6487                 for thispool in "${pool_list[@]}"; do
6488                         if [[ -z "$initial_pool" ||
6489                               "$initial_pool" != "$thispool" ]]; then
6490                                 pool="$thispool"
6491                                 echo "Using existing pool '$pool'"
6492                                 break
6493                         fi
6494                 done
6495         else
6496                 echo "none detected."
6497         fi
6498         if [ -z "$pool" ]; then
6499                 pool=${POOL:-testpool}
6500                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
6501                 echo -n "Creating pool '$pool'..."
6502                 create_pool=true
6503                 pool_add $pool &> /dev/null ||
6504                         error "pool_add failed"
6505                 echo "done."
6506
6507                 echo -n "Adding target to pool..."
6508                 pool_add_targets $pool 0 0 1 &> /dev/null ||
6509                         error "pool_add_targets failed"
6510                 echo "done."
6511         fi
6512
6513         echo -n "Setting pool using -p option..."
6514         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
6515                 error "migrate failed rc = $?"
6516         echo "done."
6517
6518         echo -n "Verifying test file is in pool after migrating..."
6519         [ "$($LFS getstripe -p $file1)" = $pool ] ||
6520                 error "file was not migrated to pool $pool"
6521         echo "done."
6522
6523         echo -n "Removing test file from pool '$pool'..."
6524         # "lfs migrate $file" won't remove the file from the pool
6525         # until some striping information is changed.
6526         $LFS migrate -c 1 $file1 &> /dev/null ||
6527                 error "cannot remove from pool"
6528         [ "$($LFS getstripe -p $file1)" ] &&
6529                 error "pool still set"
6530         echo "done."
6531
6532         echo -n "Setting pool using --pool option..."
6533         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
6534                 error "migrate failed rc = $?"
6535         echo "done."
6536
6537         # Clean up
6538         rm -f $file1
6539         if $create_pool; then
6540                 destroy_test_pools 2> /dev/null ||
6541                         error "destroy test pools failed"
6542         fi
6543 }
6544 run_test 56wb "check lfs_migrate pool support"
6545
6546 test_56wc() {
6547         local file1="$DIR/$tdir/file1"
6548         local parent_ssize
6549         local parent_scount
6550         local cur_ssize
6551         local cur_scount
6552         local orig_ssize
6553
6554         echo -n "Creating test dir..."
6555         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6556         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
6557                 error "cannot set stripe by '-S 1M -c 1'"
6558         echo "done"
6559
6560         echo -n "Setting initial stripe for test file..."
6561         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
6562                 error "cannot set stripe"
6563         cur_ssize=$($LFS getstripe -S "$file1")
6564         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
6565         echo "done."
6566
6567         # File currently set to -S 512K -c 1
6568
6569         # Ensure -c and -S options are rejected when -R is set
6570         echo -n "Verifying incompatible options are detected..."
6571         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
6572                 error "incompatible -c and -R options not detected"
6573         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
6574                 error "incompatible -S and -R options not detected"
6575         echo "done."
6576
6577         # Ensure unrecognized options are passed through to 'lfs migrate'
6578         echo -n "Verifying -S option is passed through to lfs migrate..."
6579         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
6580                 error "migration failed"
6581         cur_ssize=$($LFS getstripe -S "$file1")
6582         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
6583         echo "done."
6584
6585         # File currently set to -S 1M -c 1
6586
6587         # Ensure long options are supported
6588         echo -n "Verifying long options supported..."
6589         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
6590                 error "long option without argument not supported"
6591         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
6592                 error "long option with argument not supported"
6593         cur_ssize=$($LFS getstripe -S "$file1")
6594         [ $cur_ssize -eq 524288 ] ||
6595                 error "migrate --stripe-size $cur_ssize != 524288"
6596         echo "done."
6597
6598         # File currently set to -S 512K -c 1
6599
6600         if [ "$OSTCOUNT" -gt 1 ]; then
6601                 echo -n "Verifying explicit stripe count can be set..."
6602                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
6603                         error "migrate failed"
6604                 cur_scount=$($LFS getstripe -c "$file1")
6605                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
6606                 echo "done."
6607         fi
6608
6609         # File currently set to -S 512K -c 1 or -S 512K -c 2
6610
6611         # Ensure parent striping is used if -R is set, and no stripe
6612         # count or size is specified
6613         echo -n "Setting stripe for parent directory..."
6614         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6615                 error "cannot set stripe '-S 2M -c 1'"
6616         echo "done."
6617
6618         echo -n "Verifying restripe option uses parent stripe settings..."
6619         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
6620         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
6621         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
6622                 error "migrate failed"
6623         cur_ssize=$($LFS getstripe -S "$file1")
6624         [ $cur_ssize -eq $parent_ssize ] ||
6625                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
6626         cur_scount=$($LFS getstripe -c "$file1")
6627         [ $cur_scount -eq $parent_scount ] ||
6628                 error "migrate -R stripe_count $cur_scount != $parent_scount"
6629         echo "done."
6630
6631         # File currently set to -S 1M -c 1
6632
6633         # Ensure striping is preserved if -R is not set, and no stripe
6634         # count or size is specified
6635         echo -n "Verifying striping size preserved when not specified..."
6636         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
6637         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6638                 error "cannot set stripe on parent directory"
6639         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6640                 error "migrate failed"
6641         cur_ssize=$($LFS getstripe -S "$file1")
6642         [ $cur_ssize -eq $orig_ssize ] ||
6643                 error "migrate by default $cur_ssize != $orig_ssize"
6644         echo "done."
6645
6646         # Ensure file name properly detected when final option has no argument
6647         echo -n "Verifying file name properly detected..."
6648         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6649                 error "file name interpreted as option argument"
6650         echo "done."
6651
6652         # Clean up
6653         rm -f "$file1"
6654 }
6655 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
6656
6657 test_56wd() {
6658         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6659
6660         local file1=$DIR/$tdir/file1
6661
6662         echo -n "Creating test dir..."
6663         test_mkdir $DIR/$tdir || error "cannot create dir"
6664         echo "done."
6665
6666         echo -n "Creating test file..."
6667         touch $file1
6668         echo "done."
6669
6670         # Ensure 'lfs migrate' will fail by using a non-existent option,
6671         # and make sure rsync is not called to recover
6672         echo -n "Make sure --no-rsync option works..."
6673         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
6674                 grep -q 'refusing to fall back to rsync' ||
6675                 error "rsync was called with --no-rsync set"
6676         echo "done."
6677
6678         # Ensure rsync is called without trying 'lfs migrate' first
6679         echo -n "Make sure --rsync option works..."
6680         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
6681                 grep -q 'falling back to rsync' &&
6682                 error "lfs migrate was called with --rsync set"
6683         echo "done."
6684
6685         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
6686         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
6687                 grep -q 'at the same time' ||
6688                 error "--rsync and --no-rsync accepted concurrently"
6689         echo "done."
6690
6691         # Clean up
6692         rm -f $file1
6693 }
6694 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
6695
6696 test_56x() {
6697         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6698         check_swap_layouts_support
6699
6700         local dir=$DIR/$tdir
6701         local ref1=/etc/passwd
6702         local file1=$dir/file1
6703
6704         test_mkdir $dir || error "creating dir $dir"
6705         $LFS setstripe -c 2 $file1
6706         cp $ref1 $file1
6707         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
6708         stripe=$($LFS getstripe -c $file1)
6709         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6710         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6711
6712         # clean up
6713         rm -f $file1
6714 }
6715 run_test 56x "lfs migration support"
6716
6717 test_56xa() {
6718         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6719         check_swap_layouts_support
6720
6721         local dir=$DIR/$tdir/$testnum
6722
6723         test_mkdir -p $dir
6724
6725         local ref1=/etc/passwd
6726         local file1=$dir/file1
6727
6728         $LFS setstripe -c 2 $file1
6729         cp $ref1 $file1
6730         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
6731
6732         local stripe=$($LFS getstripe -c $file1)
6733
6734         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6735         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6736
6737         # clean up
6738         rm -f $file1
6739 }
6740 run_test 56xa "lfs migration --block support"
6741
6742 check_migrate_links() {
6743         local dir="$1"
6744         local file1="$dir/file1"
6745         local begin="$2"
6746         local count="$3"
6747         local runas="$4"
6748         local total_count=$(($begin + $count - 1))
6749         local symlink_count=10
6750         local uniq_count=10
6751
6752         if [ ! -f "$file1" ]; then
6753                 echo -n "creating initial file..."
6754                 $LFS setstripe -c 1 -S "512k" "$file1" ||
6755                         error "cannot setstripe initial file"
6756                 echo "done"
6757
6758                 echo -n "creating symlinks..."
6759                 for s in $(seq 1 $symlink_count); do
6760                         ln -s "$file1" "$dir/slink$s" ||
6761                                 error "cannot create symlinks"
6762                 done
6763                 echo "done"
6764
6765                 echo -n "creating nonlinked files..."
6766                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
6767                         error "cannot create nonlinked files"
6768                 echo "done"
6769         fi
6770
6771         # create hard links
6772         if [ ! -f "$dir/file$total_count" ]; then
6773                 echo -n "creating hard links $begin:$total_count..."
6774                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
6775                         /dev/null || error "cannot create hard links"
6776                 echo "done"
6777         fi
6778
6779         echo -n "checking number of hard links listed in xattrs..."
6780         local fid=$($LFS getstripe -F "$file1")
6781         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
6782
6783         echo "${#paths[*]}"
6784         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
6785                         skip "hard link list has unexpected size, skipping test"
6786         fi
6787         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
6788                         error "link names should exceed xattrs size"
6789         fi
6790
6791         echo -n "migrating files..."
6792         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
6793         local rc=$?
6794         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
6795         echo "done"
6796
6797         # make sure all links have been properly migrated
6798         echo -n "verifying files..."
6799         fid=$($LFS getstripe -F "$file1") ||
6800                 error "cannot get fid for file $file1"
6801         for i in $(seq 2 $total_count); do
6802                 local fid2=$($LFS getstripe -F $dir/file$i)
6803
6804                 [ "$fid2" == "$fid" ] ||
6805                         error "migrated hard link has mismatched FID"
6806         done
6807
6808         # make sure hard links were properly detected, and migration was
6809         # performed only once for the entire link set; nonlinked files should
6810         # also be migrated
6811         local actual=$(grep -c 'done' <<< "$migrate_out")
6812         local expected=$(($uniq_count + 1))
6813
6814         [ "$actual" -eq  "$expected" ] ||
6815                 error "hard links individually migrated ($actual != $expected)"
6816
6817         # make sure the correct number of hard links are present
6818         local hardlinks=$(stat -c '%h' "$file1")
6819
6820         [ $hardlinks -eq $total_count ] ||
6821                 error "num hard links $hardlinks != $total_count"
6822         echo "done"
6823
6824         return 0
6825 }
6826
6827 test_56xb() {
6828         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
6829                 skip "Need MDS version at least 2.10.55"
6830
6831         local dir="$DIR/$tdir"
6832
6833         test_mkdir "$dir" || error "cannot create dir $dir"
6834
6835         echo "testing lfs migrate mode when all links fit within xattrs"
6836         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
6837
6838         echo "testing rsync mode when all links fit within xattrs"
6839         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
6840
6841         echo "testing lfs migrate mode when all links do not fit within xattrs"
6842         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
6843
6844         echo "testing rsync mode when all links do not fit within xattrs"
6845         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
6846
6847         chown -R $RUNAS_ID $dir
6848         echo "testing non-root lfs migrate mode when not all links are in xattr"
6849         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
6850
6851         # clean up
6852         rm -rf $dir
6853 }
6854 run_test 56xb "lfs migration hard link support"
6855
6856 test_56xc() {
6857         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6858
6859         local dir="$DIR/$tdir"
6860
6861         test_mkdir "$dir" || error "cannot create dir $dir"
6862
6863         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
6864         echo -n "Setting initial stripe for 20MB test file..."
6865         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
6866                 error "cannot setstripe 20MB file"
6867         echo "done"
6868         echo -n "Sizing 20MB test file..."
6869         truncate "$dir/20mb" 20971520 || error "cannot create 20MB test file"
6870         echo "done"
6871         echo -n "Verifying small file autostripe count is 1..."
6872         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
6873                 error "cannot migrate 20MB file"
6874         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
6875                 error "cannot get stripe for $dir/20mb"
6876         [ $stripe_count -eq 1 ] ||
6877                 error "unexpected stripe count $stripe_count for 20MB file"
6878         rm -f "$dir/20mb"
6879         echo "done"
6880
6881         # Test 2: File is small enough to fit within the available space on
6882         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
6883         # have at least an additional 1KB for each desired stripe for test 3
6884         echo -n "Setting stripe for 1GB test file..."
6885         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
6886         echo "done"
6887         echo -n "Sizing 1GB test file..."
6888         # File size is 1GB + 3KB
6889         truncate "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
6890         echo "done"
6891
6892         # need at least 512MB per OST for 1GB file to fit in 2 stripes
6893         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
6894         if (( avail > 524288 * OSTCOUNT )); then
6895                 echo -n "Migrating 1GB file..."
6896                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
6897                         error "cannot migrate 1GB file"
6898                 echo "done"
6899                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
6900                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
6901                         error "cannot getstripe for 1GB file"
6902                 [ $stripe_count -eq 2 ] ||
6903                         error "unexpected stripe count $stripe_count != 2"
6904                 echo "done"
6905         fi
6906
6907         # Test 3: File is too large to fit within the available space on
6908         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
6909         if [ $OSTCOUNT -ge 3 ]; then
6910                 # The required available space is calculated as
6911                 # file size (1GB + 3KB) / OST count (3).
6912                 local kb_per_ost=349526
6913
6914                 echo -n "Migrating 1GB file with limit..."
6915                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
6916                         error "cannot migrate 1GB file with limit"
6917                 echo "done"
6918
6919                 stripe_count=$($LFS getstripe -c "$dir/1gb")
6920                 echo -n "Verifying 1GB autostripe count with limited space..."
6921                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
6922                         error "unexpected stripe count $stripe_count (min 3)"
6923                 echo "done"
6924         fi
6925
6926         # clean up
6927         rm -rf $dir
6928 }
6929 run_test 56xc "lfs migration autostripe"
6930
6931 test_56xd() {
6932         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6933
6934         local dir=$DIR/$tdir
6935         local f_mgrt=$dir/$tfile.mgrt
6936         local f_yaml=$dir/$tfile.yaml
6937         local f_copy=$dir/$tfile.copy
6938         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
6939         local layout_copy="-c 2 -S 2M -i 1"
6940         local yamlfile=$dir/yamlfile
6941         local layout_before;
6942         local layout_after;
6943
6944         test_mkdir "$dir" || error "cannot create dir $dir"
6945         $LFS setstripe $layout_yaml $f_yaml ||
6946                 error "cannot setstripe $f_yaml with layout $layout_yaml"
6947         $LFS getstripe --yaml $f_yaml > $yamlfile
6948         $LFS setstripe $layout_copy $f_copy ||
6949                 error "cannot setstripe $f_copy with layout $layout_copy"
6950         touch $f_mgrt
6951         dd if=/dev/zero of=$f_mgrt bs=1M count=4
6952
6953         # 1. test option --yaml
6954         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
6955                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
6956         layout_before=$(get_layout_param $f_yaml)
6957         layout_after=$(get_layout_param $f_mgrt)
6958         [ "$layout_after" == "$layout_before" ] ||
6959                 error "lfs_migrate --yaml: $layout_after != $layout_before"
6960
6961         # 2. test option --copy
6962         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
6963                 error "cannot migrate $f_mgrt with --copy $f_copy"
6964         layout_before=$(get_layout_param $f_copy)
6965         layout_after=$(get_layout_param $f_mgrt)
6966         [ "$layout_after" == "$layout_before" ] ||
6967                 error "lfs_migrate --copy: $layout_after != $layout_before"
6968 }
6969 run_test 56xd "check lfs_migrate --yaml and --copy support"
6970
6971 test_56xe() {
6972         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6973
6974         local dir=$DIR/$tdir
6975         local f_comp=$dir/$tfile
6976         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
6977         local layout_before=""
6978         local layout_after=""
6979
6980         test_mkdir "$dir" || error "cannot create dir $dir"
6981         $LFS setstripe $layout $f_comp ||
6982                 error "cannot setstripe $f_comp with layout $layout"
6983         layout_before=$(get_layout_param $f_comp)
6984         dd if=/dev/zero of=$f_comp bs=1M count=4
6985
6986         # 1. migrate a comp layout file by lfs_migrate
6987         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
6988         layout_after=$(get_layout_param $f_comp)
6989         [ "$layout_before" == "$layout_after" ] ||
6990                 error "lfs_migrate: $layout_before != $layout_after"
6991
6992         # 2. migrate a comp layout file by lfs migrate
6993         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
6994         layout_after=$(get_layout_param $f_comp)
6995         [ "$layout_before" == "$layout_after" ] ||
6996                 error "lfs migrate: $layout_before != $layout_after"
6997 }
6998 run_test 56xe "migrate a composite layout file"
6999
7000 test_56y() {
7001         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7002                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7003
7004         local res=""
7005         local dir=$DIR/$tdir
7006         local f1=$dir/file1
7007         local f2=$dir/file2
7008
7009         test_mkdir -p $dir || error "creating dir $dir"
7010         touch $f1 || error "creating std file $f1"
7011         $MULTIOP $f2 H2c || error "creating released file $f2"
7012
7013         # a directory can be raid0, so ask only for files
7014         res=$($LFS find $dir -L raid0 -type f | wc -l)
7015         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7016
7017         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7018         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7019
7020         # only files can be released, so no need to force file search
7021         res=$($LFS find $dir -L released)
7022         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7023
7024         res=$($LFS find $dir -type f \! -L released)
7025         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7026 }
7027 run_test 56y "lfs find -L raid0|released"
7028
7029 test_56z() { # LU-4824
7030         # This checks to make sure 'lfs find' continues after errors
7031         # There are two classes of errors that should be caught:
7032         # - If multiple paths are provided, all should be searched even if one
7033         #   errors out
7034         # - If errors are encountered during the search, it should not terminate
7035         #   early
7036         local dir=$DIR/$tdir
7037         local i
7038
7039         test_mkdir $dir
7040         for i in d{0..9}; do
7041                 test_mkdir $dir/$i
7042                 touch $dir/$i/$tfile
7043         done
7044         $LFS find $DIR/non_existent_dir $dir &&
7045                 error "$LFS find did not return an error"
7046         # Make a directory unsearchable. This should NOT be the last entry in
7047         # directory order.  Arbitrarily pick the 6th entry
7048         chmod 700 $($LFS find $dir -type d | sed '6!d')
7049
7050         $RUNAS $LFS find $DIR/non_existent $dir
7051         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7052
7053         # The user should be able to see 10 directories and 9 files
7054         (( count == 19 )) ||
7055                 error "$LFS find found $count != 19 entries after error"
7056 }
7057 run_test 56z "lfs find should continue after an error"
7058
7059 test_56aa() { # LU-5937
7060         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7061
7062         local dir=$DIR/$tdir
7063
7064         mkdir $dir
7065         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7066
7067         createmany -o $dir/striped_dir/${tfile}- 1024
7068         local dirs=$($LFS find --size +8k $dir/)
7069
7070         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7071 }
7072 run_test 56aa "lfs find --size under striped dir"
7073
7074 test_56ab() { # LU-10705
7075         test_mkdir $DIR/$tdir
7076         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7077         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7078         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7079         # Flush writes to ensure valid blocks.  Need to be more thorough for
7080         # ZFS, since blocks are not allocated/returned to client immediately.
7081         sync_all_data
7082         wait_zfs_commit ost1 2
7083         cancel_lru_locks osc
7084         ls -ls $DIR/$tdir
7085
7086         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7087
7088         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7089
7090         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7091         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7092
7093         rm -f $DIR/$tdir/$tfile.[123]
7094 }
7095 run_test 56ab "lfs find --blocks"
7096
7097 test_56ba() {
7098         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
7099                 skip "Need MDS version at least 2.10.50"
7100
7101         # Create composite files with one component
7102         local dir=$DIR/$tdir
7103
7104         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
7105         # Create composite files with three components
7106         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
7107         # Create non-composite files
7108         createmany -o $dir/${tfile}- 10
7109
7110         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
7111
7112         [[ $nfiles == 10 ]] ||
7113                 error "lfs find -E 1M found $nfiles != 10 files"
7114
7115         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
7116         [[ $nfiles == 25 ]] ||
7117                 error "lfs find ! -E 1M found $nfiles != 25 files"
7118
7119         # All files have a component that starts at 0
7120         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
7121         [[ $nfiles == 35 ]] ||
7122                 error "lfs find --component-start 0 - $nfiles != 35 files"
7123
7124         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
7125         [[ $nfiles == 15 ]] ||
7126                 error "lfs find --component-start 2M - $nfiles != 15 files"
7127
7128         # All files created here have a componenet that does not starts at 2M
7129         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
7130         [[ $nfiles == 35 ]] ||
7131                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
7132
7133         # Find files with a specified number of components
7134         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
7135         [[ $nfiles == 15 ]] ||
7136                 error "lfs find --component-count 3 - $nfiles != 15 files"
7137
7138         # Remember non-composite files have a component count of zero
7139         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
7140         [[ $nfiles == 10 ]] ||
7141                 error "lfs find --component-count 0 - $nfiles != 10 files"
7142
7143         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
7144         [[ $nfiles == 20 ]] ||
7145                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
7146
7147         # All files have a flag called "init"
7148         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
7149         [[ $nfiles == 35 ]] ||
7150                 error "lfs find --component-flags init - $nfiles != 35 files"
7151
7152         # Multi-component files will have a component not initialized
7153         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
7154         [[ $nfiles == 15 ]] ||
7155                 error "lfs find !--component-flags init - $nfiles != 15 files"
7156
7157         rm -rf $dir
7158
7159 }
7160 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
7161
7162 test_56ca() {
7163         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
7164                 skip "Need MDS version at least 2.10.57"
7165
7166         local td=$DIR/$tdir
7167         local tf=$td/$tfile
7168         local dir
7169         local nfiles
7170         local cmd
7171         local i
7172         local j
7173
7174         # create mirrored directories and mirrored files
7175         mkdir $td || error "mkdir $td failed"
7176         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
7177         createmany -o $tf- 10 || error "create $tf- failed"
7178
7179         for i in $(seq 2); do
7180                 dir=$td/dir$i
7181                 mkdir $dir || error "mkdir $dir failed"
7182                 $LFS mirror create -N$((3 + i)) $dir ||
7183                         error "create mirrored dir $dir failed"
7184                 createmany -o $dir/$tfile- 10 ||
7185                         error "create $dir/$tfile- failed"
7186         done
7187
7188         # change the states of some mirrored files
7189         echo foo > $tf-6
7190         for i in $(seq 2); do
7191                 dir=$td/dir$i
7192                 for j in $(seq 4 9); do
7193                         echo foo > $dir/$tfile-$j
7194                 done
7195         done
7196
7197         # find mirrored files with specific mirror count
7198         cmd="$LFS find --mirror-count 3 --type f $td"
7199         nfiles=$($cmd | wc -l)
7200         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
7201
7202         cmd="$LFS find ! --mirror-count 3 --type f $td"
7203         nfiles=$($cmd | wc -l)
7204         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
7205
7206         cmd="$LFS find --mirror-count +2 --type f $td"
7207         nfiles=$($cmd | wc -l)
7208         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7209
7210         cmd="$LFS find --mirror-count -6 --type f $td"
7211         nfiles=$($cmd | wc -l)
7212         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7213
7214         # find mirrored files with specific file state
7215         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
7216         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
7217
7218         cmd="$LFS find --mirror-state=ro --type f $td"
7219         nfiles=$($cmd | wc -l)
7220         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
7221
7222         cmd="$LFS find ! --mirror-state=ro --type f $td"
7223         nfiles=$($cmd | wc -l)
7224         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7225
7226         cmd="$LFS find --mirror-state=wp --type f $td"
7227         nfiles=$($cmd | wc -l)
7228         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7229
7230         cmd="$LFS find ! --mirror-state=sp --type f $td"
7231         nfiles=$($cmd | wc -l)
7232         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7233 }
7234 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
7235
7236 test_57a() {
7237         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7238         # note test will not do anything if MDS is not local
7239         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7240                 skip_env "ldiskfs only test"
7241         fi
7242         remote_mds_nodsh && skip "remote MDS with nodsh"
7243
7244         local MNTDEV="osd*.*MDT*.mntdev"
7245         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
7246         [ -z "$DEV" ] && error "can't access $MNTDEV"
7247         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
7248                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
7249                         error "can't access $DEV"
7250                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
7251                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
7252                 rm $TMP/t57a.dump
7253         done
7254 }
7255 run_test 57a "verify MDS filesystem created with large inodes =="
7256
7257 test_57b() {
7258         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7259         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7260                 skip_env "ldiskfs only test"
7261         fi
7262         remote_mds_nodsh && skip "remote MDS with nodsh"
7263
7264         local dir=$DIR/$tdir
7265         local filecount=100
7266         local file1=$dir/f1
7267         local fileN=$dir/f$filecount
7268
7269         rm -rf $dir || error "removing $dir"
7270         test_mkdir -c1 $dir
7271         local mdtidx=$($LFS getstripe -m $dir)
7272         local mdtname=MDT$(printf %04x $mdtidx)
7273         local facet=mds$((mdtidx + 1))
7274
7275         echo "mcreating $filecount files"
7276         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
7277
7278         # verify that files do not have EAs yet
7279         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
7280                 error "$file1 has an EA"
7281         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
7282                 error "$fileN has an EA"
7283
7284         sync
7285         sleep 1
7286         df $dir  #make sure we get new statfs data
7287         local mdsfree=$(do_facet $facet \
7288                         lctl get_param -n osd*.*$mdtname.kbytesfree)
7289         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7290         local file
7291
7292         echo "opening files to create objects/EAs"
7293         for file in $(seq -f $dir/f%g 1 $filecount); do
7294                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
7295                         error "opening $file"
7296         done
7297
7298         # verify that files have EAs now
7299         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
7300         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
7301
7302         sleep 1  #make sure we get new statfs data
7303         df $dir
7304         local mdsfree2=$(do_facet $facet \
7305                          lctl get_param -n osd*.*$mdtname.kbytesfree)
7306         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7307
7308         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
7309                 if [ "$mdsfree" != "$mdsfree2" ]; then
7310                         error "MDC before $mdcfree != after $mdcfree2"
7311                 else
7312                         echo "MDC before $mdcfree != after $mdcfree2"
7313                         echo "unable to confirm if MDS has large inodes"
7314                 fi
7315         fi
7316         rm -rf $dir
7317 }
7318 run_test 57b "default LOV EAs are stored inside large inodes ==="
7319
7320 test_58() {
7321         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7322         [ -z "$(which wiretest 2>/dev/null)" ] &&
7323                         skip_env "could not find wiretest"
7324
7325         wiretest
7326 }
7327 run_test 58 "verify cross-platform wire constants =============="
7328
7329 test_59() {
7330         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7331
7332         echo "touch 130 files"
7333         createmany -o $DIR/f59- 130
7334         echo "rm 130 files"
7335         unlinkmany $DIR/f59- 130
7336         sync
7337         # wait for commitment of removal
7338         wait_delete_completed
7339 }
7340 run_test 59 "verify cancellation of llog records async ========="
7341
7342 TEST60_HEAD="test_60 run $RANDOM"
7343 test_60a() {
7344         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7345         remote_mgs_nodsh && skip "remote MGS with nodsh"
7346         do_facet mgs "! which run-llog.sh &> /dev/null" &&
7347                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
7348                         skip_env "missing subtest run-llog.sh"
7349
7350         log "$TEST60_HEAD - from kernel mode"
7351         do_facet mgs "$LCTL dk > /dev/null"
7352         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
7353         do_facet mgs $LCTL dk > $TMP/$tfile
7354
7355         # LU-6388: test llog_reader
7356         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
7357         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
7358         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
7359                         skip_env "missing llog_reader"
7360         local fstype=$(facet_fstype mgs)
7361         [ $fstype != ldiskfs -a $fstype != zfs ] &&
7362                 skip_env "Only for ldiskfs or zfs type mgs"
7363
7364         local mntpt=$(facet_mntpt mgs)
7365         local mgsdev=$(mgsdevname 1)
7366         local fid_list
7367         local fid
7368         local rec_list
7369         local rec
7370         local rec_type
7371         local obj_file
7372         local path
7373         local seq
7374         local oid
7375         local pass=true
7376
7377         #get fid and record list
7378         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
7379                 tail -n 4))
7380         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
7381                 tail -n 4))
7382         #remount mgs as ldiskfs or zfs type
7383         stop mgs || error "stop mgs failed"
7384         mount_fstype mgs || error "remount mgs failed"
7385         for ((i = 0; i < ${#fid_list[@]}; i++)); do
7386                 fid=${fid_list[i]}
7387                 rec=${rec_list[i]}
7388                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
7389                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
7390                 oid=$((16#$oid))
7391
7392                 case $fstype in
7393                         ldiskfs )
7394                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
7395                         zfs )
7396                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
7397                 esac
7398                 echo "obj_file is $obj_file"
7399                 do_facet mgs $llog_reader $obj_file
7400
7401                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
7402                         awk '{ print $3 }' | sed -e "s/^type=//g")
7403                 if [ $rec_type != $rec ]; then
7404                         echo "FAILED test_60a wrong record type $rec_type," \
7405                               "should be $rec"
7406                         pass=false
7407                         break
7408                 fi
7409
7410                 #check obj path if record type is LLOG_LOGID_MAGIC
7411                 if [ "$rec" == "1064553b" ]; then
7412                         path=$(do_facet mgs $llog_reader $obj_file |
7413                                 grep "path=" | awk '{ print $NF }' |
7414                                 sed -e "s/^path=//g")
7415                         if [ $obj_file != $mntpt/$path ]; then
7416                                 echo "FAILED test_60a wrong obj path" \
7417                                       "$montpt/$path, should be $obj_file"
7418                                 pass=false
7419                                 break
7420                         fi
7421                 fi
7422         done
7423         rm -f $TMP/$tfile
7424         #restart mgs before "error", otherwise it will block the next test
7425         stop mgs || error "stop mgs failed"
7426         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
7427         $pass || error "test failed, see FAILED test_60a messages for specifics"
7428 }
7429 run_test 60a "llog_test run from kernel module and test llog_reader"
7430
7431 test_60b() { # bug 6411
7432         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7433
7434         dmesg > $DIR/$tfile
7435         LLOG_COUNT=$(do_facet mgs dmesg |
7436                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
7437                           /llog_[a-z]*.c:[0-9]/ {
7438                                 if (marker)
7439                                         from_marker++
7440                                 from_begin++
7441                           }
7442                           END {
7443                                 if (marker)
7444                                         print from_marker
7445                                 else
7446                                         print from_begin
7447                           }")
7448
7449         [[ $LLOG_COUNT -gt 120 ]] &&
7450                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
7451 }
7452 run_test 60b "limit repeated messages from CERROR/CWARN"
7453
7454 test_60c() {
7455         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7456
7457         echo "create 5000 files"
7458         createmany -o $DIR/f60c- 5000
7459 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
7460         lctl set_param fail_loc=0x80000137
7461         unlinkmany $DIR/f60c- 5000
7462         lctl set_param fail_loc=0
7463 }
7464 run_test 60c "unlink file when mds full"
7465
7466 test_60d() {
7467         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7468
7469         SAVEPRINTK=$(lctl get_param -n printk)
7470         # verify "lctl mark" is even working"
7471         MESSAGE="test message ID $RANDOM $$"
7472         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7473         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
7474
7475         lctl set_param printk=0 || error "set lnet.printk failed"
7476         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
7477         MESSAGE="new test message ID $RANDOM $$"
7478         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
7479         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7480         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
7481
7482         lctl set_param -n printk="$SAVEPRINTK"
7483 }
7484 run_test 60d "test printk console message masking"
7485
7486 test_60e() {
7487         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7488         remote_mds_nodsh && skip "remote MDS with nodsh"
7489
7490         touch $DIR/$tfile
7491 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
7492         do_facet mds1 lctl set_param fail_loc=0x15b
7493         rm $DIR/$tfile
7494 }
7495 run_test 60e "no space while new llog is being created"
7496
7497 test_60g() {
7498         local pid
7499         local i
7500
7501         test_mkdir -c $MDSCOUNT $DIR/$tdir
7502
7503         (
7504                 local index=0
7505                 while true; do
7506                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
7507                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
7508                                 2>/dev/null
7509                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
7510                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
7511                         index=$((index + 1))
7512                 done
7513         ) &
7514
7515         pid=$!
7516
7517         for i in {0..100}; do
7518                 # define OBD_FAIL_OSD_TXN_START    0x19a
7519                 local index=$((i % MDSCOUNT + 1))
7520
7521                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
7522                         > /dev/null
7523                 usleep 100
7524         done
7525
7526         kill -9 $pid
7527
7528         for i in $(seq $MDSCOUNT); do
7529                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
7530         done
7531
7532         mkdir $DIR/$tdir/new || error "mkdir failed"
7533         rmdir $DIR/$tdir/new || error "rmdir failed"
7534
7535         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
7536                 -t namespace
7537         for i in $(seq $MDSCOUNT); do
7538                 wait_update_facet mds$i "$LCTL get_param -n \
7539                         mdd.$(facet_svc mds$i).lfsck_namespace |
7540                         awk '/^status/ { print \\\$2 }'" "completed"
7541         done
7542
7543         ls -R $DIR/$tdir || error "ls failed"
7544         rm -rf $DIR/$tdir || error "rmdir failed"
7545 }
7546 run_test 60g "transaction abort won't cause MDT hung"
7547
7548 test_60h() {
7549         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
7550                 skip "Need MDS version at least 2.12.52"
7551         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
7552
7553         local f
7554
7555         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
7556         #define OBD_FAIL_MDS_STRIPE_FID          0x189
7557         for fail_loc in 0x80000188 0x80000189; do
7558                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
7559                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
7560                         error "mkdir $dir-$fail_loc failed"
7561                 for i in {0..10}; do
7562                         # create may fail on missing stripe
7563                         echo $i > $DIR/$tdir-$fail_loc/$i
7564                 done
7565                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7566                         error "getdirstripe $tdir-$fail_loc failed"
7567                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
7568                         error "migrate $tdir-$fail_loc failed"
7569                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7570                         error "getdirstripe $tdir-$fail_loc failed"
7571                 pushd $DIR/$tdir-$fail_loc
7572                 for f in *; do
7573                         echo $f | cmp $f - || error "$f data mismatch"
7574                 done
7575                 popd
7576                 rm -rf $DIR/$tdir-$fail_loc
7577         done
7578 }
7579 run_test 60h "striped directory with missing stripes can be accessed"
7580
7581 test_61a() {
7582         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7583
7584         f="$DIR/f61"
7585         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
7586         cancel_lru_locks osc
7587         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
7588         sync
7589 }
7590 run_test 61a "mmap() writes don't make sync hang ================"
7591
7592 test_61b() {
7593         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
7594 }
7595 run_test 61b "mmap() of unstriped file is successful"
7596
7597 # bug 2330 - insufficient obd_match error checking causes LBUG
7598 test_62() {
7599         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7600
7601         f="$DIR/f62"
7602         echo foo > $f
7603         cancel_lru_locks osc
7604         lctl set_param fail_loc=0x405
7605         cat $f && error "cat succeeded, expect -EIO"
7606         lctl set_param fail_loc=0
7607 }
7608 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
7609 # match every page all of the time.
7610 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
7611
7612 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
7613 # Though this test is irrelevant anymore, it helped to reveal some
7614 # other grant bugs (LU-4482), let's keep it.
7615 test_63a() {   # was test_63
7616         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7617
7618         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
7619
7620         for i in `seq 10` ; do
7621                 dd if=/dev/zero of=$DIR/f63 bs=8k &
7622                 sleep 5
7623                 kill $!
7624                 sleep 1
7625         done
7626
7627         rm -f $DIR/f63 || true
7628 }
7629 run_test 63a "Verify oig_wait interruption does not crash ======="
7630
7631 # bug 2248 - async write errors didn't return to application on sync
7632 # bug 3677 - async write errors left page locked
7633 test_63b() {
7634         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7635
7636         debugsave
7637         lctl set_param debug=-1
7638
7639         # ensure we have a grant to do async writes
7640         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
7641         rm $DIR/$tfile
7642
7643         sync    # sync lest earlier test intercept the fail_loc
7644
7645         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
7646         lctl set_param fail_loc=0x80000406
7647         $MULTIOP $DIR/$tfile Owy && \
7648                 error "sync didn't return ENOMEM"
7649         sync; sleep 2; sync     # do a real sync this time to flush page
7650         lctl get_param -n llite.*.dump_page_cache | grep locked && \
7651                 error "locked page left in cache after async error" || true
7652         debugrestore
7653 }
7654 run_test 63b "async write errors should be returned to fsync ==="
7655
7656 test_64a () {
7657         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7658
7659         lfs df $DIR
7660         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
7661 }
7662 run_test 64a "verify filter grant calculations (in kernel) ====="
7663
7664 test_64b () {
7665         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7666
7667         sh oos.sh $MOUNT || error "oos.sh failed: $?"
7668 }
7669 run_test 64b "check out-of-space detection on client"
7670
7671 test_64c() {
7672         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
7673 }
7674 run_test 64c "verify grant shrink"
7675
7676 # this does exactly what osc_request.c:osc_announce_cached() does in
7677 # order to calculate max amount of grants to ask from server
7678 want_grant() {
7679         local tgt=$1
7680
7681         local nrpages=$($LCTL get_param -n osc.${tgt}.max_pages_per_rpc)
7682         local rpc_in_flight=$($LCTL get_param -n osc.${tgt}.max_rpcs_in_flight)
7683
7684         ((rpc_in_flight ++));
7685         nrpages=$((nrpages * rpc_in_flight))
7686
7687         local dirty_max_pages=$($LCTL get_param -n osc.${tgt}.max_dirty_mb)
7688
7689         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
7690
7691         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
7692         local undirty=$((nrpages * PAGE_SIZE))
7693
7694         local max_extent_pages
7695         max_extent_pages=$($LCTL get_param osc.${tgt}.import |
7696             grep grant_max_extent_size | awk '{print $2}')
7697         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
7698         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
7699         local grant_extent_tax
7700         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
7701             grep grant_extent_tax | awk '{print $2}')
7702
7703         undirty=$((undirty + nrextents * grant_extent_tax))
7704
7705         echo $undirty
7706 }
7707
7708 # this is size of unit for grant allocation. It should be equal to
7709 # what tgt_grant.c:tgt_grant_chunk() calculates
7710 grant_chunk() {
7711         local tgt=$1
7712         local max_brw_size
7713         local grant_extent_tax
7714
7715         max_brw_size=$($LCTL get_param osc.${tgt}.import |
7716             grep max_brw_size | awk '{print $2}')
7717
7718         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
7719             grep grant_extent_tax | awk '{print $2}')
7720
7721         echo $(((max_brw_size + grant_extent_tax) * 2))
7722 }
7723
7724 test_64d() {
7725         [ $OST1_VERSION -lt $(version_code 2.10.56) ] &&
7726                 skip "OST < 2.10.55 doesn't limit grants enough"
7727
7728         local tgt=$($LCTL dl | grep "0000-osc-[^mM]" | awk '{print $4}')
7729         local file=$DIR/$tfile
7730
7731         [[ $($LCTL get_param osc.${tgt}.import |
7732              grep "connect_flags:.*grant_param") ]] ||
7733                 skip "no grant_param connect flag"
7734
7735         local olddebug=$($LCTL get_param -n debug 2> /dev/null)
7736
7737         $LCTL set_param debug="$OLDDEBUG" 2> /dev/null || true
7738
7739         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
7740         stack_trap "rm -f $file" EXIT
7741
7742         $LFS setstripe $file -i 0 -c 1
7743         dd if=/dev/zero of=$file bs=1M count=1000 &
7744         ddpid=$!
7745
7746         while true
7747         do
7748                 local cur_grant=$($LCTL get_param -n osc.${tgt}.cur_grant_bytes)
7749                 if [[ $cur_grant -gt $max_cur_granted ]]
7750                 then
7751                         kill $ddpid
7752                         error "cur_grant $cur_grant > $max_cur_granted"
7753                 fi
7754                 kill -0 $ddpid
7755                 [[ $? -ne 0 ]] && break;
7756                 sleep 2
7757         done
7758
7759         rm -f $DIR/$tfile
7760         wait_delete_completed
7761         $LCTL set_param debug="$olddebug" 2> /dev/null || true
7762 }
7763 run_test 64d "check grant limit exceed"
7764
7765 # bug 1414 - set/get directories' stripe info
7766 test_65a() {
7767         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7768
7769         test_mkdir $DIR/$tdir
7770         touch $DIR/$tdir/f1
7771         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
7772 }
7773 run_test 65a "directory with no stripe info"
7774
7775 test_65b() {
7776         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7777
7778         test_mkdir $DIR/$tdir
7779         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7780
7781         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
7782                                                 error "setstripe"
7783         touch $DIR/$tdir/f2
7784         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
7785 }
7786 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
7787
7788 test_65c() {
7789         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7790         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
7791
7792         test_mkdir $DIR/$tdir
7793         local stripesize=$($LFS getstripe -S $DIR/$tdir)
7794
7795         $LFS setstripe -S $((stripesize * 4)) -i 1 \
7796                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
7797         touch $DIR/$tdir/f3
7798         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
7799 }
7800 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
7801
7802 test_65d() {
7803         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7804
7805         test_mkdir $DIR/$tdir
7806         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
7807         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7808
7809         if [[ $STRIPECOUNT -le 0 ]]; then
7810                 sc=1
7811         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
7812                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
7813                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
7814         else
7815                 sc=$(($STRIPECOUNT - 1))
7816         fi
7817         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
7818         touch $DIR/$tdir/f4 $DIR/$tdir/f5
7819         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
7820                 error "lverify failed"
7821 }
7822 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
7823
7824 test_65e() {
7825         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7826
7827         test_mkdir $DIR/$tdir
7828
7829         $LFS setstripe $DIR/$tdir || error "setstripe"
7830         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
7831                                         error "no stripe info failed"
7832         touch $DIR/$tdir/f6
7833         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
7834 }
7835 run_test 65e "directory setstripe defaults"
7836
7837 test_65f() {
7838         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7839
7840         test_mkdir $DIR/${tdir}f
7841         $RUNAS $LFS setstripe $DIR/${tdir}f &&
7842                 error "setstripe succeeded" || true
7843 }
7844 run_test 65f "dir setstripe permission (should return error) ==="
7845
7846 test_65g() {
7847         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7848
7849         test_mkdir $DIR/$tdir
7850         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7851
7852         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
7853                 error "setstripe -S failed"
7854         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
7855         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
7856                 error "delete default stripe failed"
7857 }
7858 run_test 65g "directory setstripe -d"
7859
7860 test_65h() {
7861         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7862
7863         test_mkdir $DIR/$tdir
7864         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7865
7866         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
7867                 error "setstripe -S failed"
7868         test_mkdir $DIR/$tdir/dd1
7869         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
7870                 error "stripe info inherit failed"
7871 }
7872 run_test 65h "directory stripe info inherit ===================="
7873
7874 test_65i() {
7875         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7876
7877         save_layout_restore_at_exit $MOUNT
7878
7879         # bug6367: set non-default striping on root directory
7880         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
7881
7882         # bug12836: getstripe on -1 default directory striping
7883         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
7884
7885         # bug12836: getstripe -v on -1 default directory striping
7886         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
7887
7888         # bug12836: new find on -1 default directory striping
7889         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
7890 }
7891 run_test 65i "various tests to set root directory striping"
7892
7893 test_65j() { # bug6367
7894         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7895
7896         sync; sleep 1
7897
7898         # if we aren't already remounting for each test, do so for this test
7899         if [ "$I_MOUNTED" = "yes" ]; then
7900                 cleanup || error "failed to unmount"
7901                 setup
7902         fi
7903
7904         save_layout_restore_at_exit $MOUNT
7905
7906         $LFS setstripe -d $MOUNT || error "setstripe failed"
7907 }
7908 run_test 65j "set default striping on root directory (bug 6367)="
7909
7910 cleanup_65k() {
7911         rm -rf $DIR/$tdir
7912         wait_delete_completed
7913         do_facet $SINGLEMDS "lctl set_param -n \
7914                 osp.$ost*MDT0000.max_create_count=$max_count"
7915         do_facet $SINGLEMDS "lctl set_param -n \
7916                 osp.$ost*MDT0000.create_count=$count"
7917         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
7918         echo $INACTIVE_OSC "is Activate"
7919
7920         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
7921 }
7922
7923 test_65k() { # bug11679
7924         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7925         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7926         remote_mds_nodsh && skip "remote MDS with nodsh"
7927
7928         local disable_precreate=true
7929         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
7930                 disable_precreate=false
7931
7932         echo "Check OST status: "
7933         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
7934                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
7935
7936         for OSC in $MDS_OSCS; do
7937                 echo $OSC "is active"
7938                 do_facet $SINGLEMDS lctl --device %$OSC activate
7939         done
7940
7941         for INACTIVE_OSC in $MDS_OSCS; do
7942                 local ost=$(osc_to_ost $INACTIVE_OSC)
7943                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
7944                                lov.*md*.target_obd |
7945                                awk -F: /$ost/'{ print $1 }' | head -n 1)
7946
7947                 mkdir -p $DIR/$tdir
7948                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
7949                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
7950
7951                 echo "Deactivate: " $INACTIVE_OSC
7952                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
7953
7954                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
7955                               osp.$ost*MDT0000.create_count")
7956                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
7957                                   osp.$ost*MDT0000.max_create_count")
7958                 $disable_precreate &&
7959                         do_facet $SINGLEMDS "lctl set_param -n \
7960                                 osp.$ost*MDT0000.max_create_count=0"
7961
7962                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
7963                         [ -f $DIR/$tdir/$idx ] && continue
7964                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
7965                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
7966                                 { cleanup_65k;
7967                                   error "setstripe $idx should succeed"; }
7968                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
7969                 done
7970                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
7971                 rmdir $DIR/$tdir
7972
7973                 do_facet $SINGLEMDS "lctl set_param -n \
7974                         osp.$ost*MDT0000.max_create_count=$max_count"
7975                 do_facet $SINGLEMDS "lctl set_param -n \
7976                         osp.$ost*MDT0000.create_count=$count"
7977                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
7978                 echo $INACTIVE_OSC "is Activate"
7979
7980                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
7981         done
7982 }
7983 run_test 65k "validate manual striping works properly with deactivated OSCs"
7984
7985 test_65l() { # bug 12836
7986         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7987
7988         test_mkdir -p $DIR/$tdir/test_dir
7989         $LFS setstripe -c -1 $DIR/$tdir/test_dir
7990         $LFS find -mtime -1 $DIR/$tdir >/dev/null
7991 }
7992 run_test 65l "lfs find on -1 stripe dir ========================"
7993
7994 test_65m() {
7995         local layout=$(save_layout $MOUNT)
7996         $RUNAS $LFS setstripe -c 2 $MOUNT && {
7997                 restore_layout $MOUNT $layout
7998                 error "setstripe should fail by non-root users"
7999         }
8000         true
8001 }
8002 run_test 65m "normal user can't set filesystem default stripe"
8003
8004 test_65n() {
8005         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
8006         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
8007                 skip "Need MDS version at least 2.12.50"
8008         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8009
8010         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8011         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
8012         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
8013
8014         local root_layout=$(save_layout $MOUNT)
8015         stack_trap "restore_layout $MOUNT $root_layout" EXIT
8016
8017         # new subdirectory under root directory should not inherit
8018         # the default layout from root
8019         local dir1=$MOUNT/$tdir-1
8020         mkdir $dir1 || error "mkdir $dir1 failed"
8021         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
8022                 error "$dir1 shouldn't have LOV EA"
8023
8024         # delete the default layout on root directory
8025         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
8026
8027         local dir2=$MOUNT/$tdir-2
8028         mkdir $dir2 || error "mkdir $dir2 failed"
8029         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
8030                 error "$dir2 shouldn't have LOV EA"
8031
8032         # set a new striping pattern on root directory
8033         local def_stripe_size=$($LFS getstripe -S $MOUNT)
8034         local new_def_stripe_size=$((def_stripe_size * 2))
8035         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
8036                 error "set stripe size on $MOUNT failed"
8037
8038         # new file created in $dir2 should inherit the new stripe size from
8039         # the filesystem default
8040         local file2=$dir2/$tfile-2
8041         touch $file2 || error "touch $file2 failed"
8042
8043         local file2_stripe_size=$($LFS getstripe -S $file2)
8044         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
8045                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
8046
8047         local dir3=$MOUNT/$tdir-3
8048         mkdir $dir3 || error "mkdir $dir3 failed"
8049         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
8050         # the root layout, which is the actual default layout that will be used
8051         # when new files are created in $dir3.
8052         local dir3_layout=$(get_layout_param $dir3)
8053         local root_dir_layout=$(get_layout_param $MOUNT)
8054         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
8055                 error "$dir3 should show the default layout from $MOUNT"
8056
8057         # set OST pool on root directory
8058         local pool=$TESTNAME
8059         pool_add $pool || error "add $pool failed"
8060         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8061                 error "add targets to $pool failed"
8062
8063         $LFS setstripe -p $pool $MOUNT ||
8064                 error "set OST pool on $MOUNT failed"
8065
8066         # new file created in $dir3 should inherit the pool from
8067         # the filesystem default
8068         local file3=$dir3/$tfile-3
8069         touch $file3 || error "touch $file3 failed"
8070
8071         local file3_pool=$($LFS getstripe -p $file3)
8072         [[ "$file3_pool" = "$pool" ]] ||
8073                 error "$file3 didn't inherit OST pool $pool"
8074
8075         local dir4=$MOUNT/$tdir-4
8076         mkdir $dir4 || error "mkdir $dir4 failed"
8077         local dir4_layout=$(get_layout_param $dir4)
8078         root_dir_layout=$(get_layout_param $MOUNT)
8079         echo "$LFS getstripe -d $dir4"
8080         $LFS getstripe -d $dir4
8081         echo "$LFS getstripe -d $MOUNT"
8082         $LFS getstripe -d $MOUNT
8083         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
8084                 error "$dir4 should show the default layout from $MOUNT"
8085
8086         # new file created in $dir4 should inherit the pool from
8087         # the filesystem default
8088         local file4=$dir4/$tfile-4
8089         touch $file4 || error "touch $file4 failed"
8090
8091         local file4_pool=$($LFS getstripe -p $file4)
8092         [[ "$file4_pool" = "$pool" ]] ||
8093                 error "$file4 didn't inherit OST pool $pool"
8094
8095         # new subdirectory under non-root directory should inherit
8096         # the default layout from its parent directory
8097         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
8098                 error "set directory layout on $dir4 failed"
8099
8100         local dir5=$dir4/$tdir-5
8101         mkdir $dir5 || error "mkdir $dir5 failed"
8102
8103         dir4_layout=$(get_layout_param $dir4)
8104         local dir5_layout=$(get_layout_param $dir5)
8105         [[ "$dir4_layout" = "$dir5_layout" ]] ||
8106                 error "$dir5 should inherit the default layout from $dir4"
8107
8108         # though subdir under ROOT doesn't inherit default layout, but
8109         # its sub dir/file should be created with default layout.
8110         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
8111         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
8112                 skip "Need MDS version at least 2.12.59"
8113
8114         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
8115         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
8116         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
8117
8118         if [ $default_lmv_hash == "none" ]; then
8119                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
8120         else
8121                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
8122                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
8123         fi
8124
8125         $LFS setdirstripe -D -c 2 $MOUNT ||
8126                 error "setdirstripe -D -c 2 failed"
8127         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
8128         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
8129         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
8130 }
8131 run_test 65n "don't inherit default layout from root for new subdirectories"
8132
8133 # bug 2543 - update blocks count on client
8134 test_66() {
8135         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8136
8137         COUNT=${COUNT:-8}
8138         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
8139         sync; sync_all_data; sync; sync_all_data
8140         cancel_lru_locks osc
8141         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
8142         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
8143 }
8144 run_test 66 "update inode blocks count on client ==============="
8145
8146 meminfo() {
8147         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
8148 }
8149
8150 swap_used() {
8151         swapon -s | awk '($1 == "'$1'") { print $4 }'
8152 }
8153
8154 # bug5265, obdfilter oa2dentry return -ENOENT
8155 # #define OBD_FAIL_SRV_ENOENT 0x217
8156 test_69() {
8157         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8158         remote_ost_nodsh && skip "remote OST with nodsh"
8159
8160         f="$DIR/$tfile"
8161         $LFS setstripe -c 1 -i 0 $f
8162
8163         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
8164
8165         do_facet ost1 lctl set_param fail_loc=0x217
8166         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
8167         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
8168
8169         do_facet ost1 lctl set_param fail_loc=0
8170         $DIRECTIO write $f 0 2 || error "write error"
8171
8172         cancel_lru_locks osc
8173         $DIRECTIO read $f 0 1 || error "read error"
8174
8175         do_facet ost1 lctl set_param fail_loc=0x217
8176         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
8177
8178         do_facet ost1 lctl set_param fail_loc=0
8179         rm -f $f
8180 }
8181 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
8182
8183 test_71() {
8184         test_mkdir $DIR/$tdir
8185         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
8186         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
8187 }
8188 run_test 71 "Running dbench on lustre (don't segment fault) ===="
8189
8190 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
8191         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8192         [ "$RUNAS_ID" = "$UID" ] &&
8193                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8194         # Check that testing environment is properly set up. Skip if not
8195         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
8196                 skip_env "User $RUNAS_ID does not exist - skipping"
8197
8198         touch $DIR/$tfile
8199         chmod 777 $DIR/$tfile
8200         chmod ug+s $DIR/$tfile
8201         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
8202                 error "$RUNAS dd $DIR/$tfile failed"
8203         # See if we are still setuid/sgid
8204         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8205                 error "S/gid is not dropped on write"
8206         # Now test that MDS is updated too
8207         cancel_lru_locks mdc
8208         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8209                 error "S/gid is not dropped on MDS"
8210         rm -f $DIR/$tfile
8211 }
8212 run_test 72a "Test that remove suid works properly (bug5695) ===="
8213
8214 test_72b() { # bug 24226 -- keep mode setting when size is not changing
8215         local perm
8216
8217         [ "$RUNAS_ID" = "$UID" ] &&
8218                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8219         [ "$RUNAS_ID" -eq 0 ] &&
8220                 skip_env "RUNAS_ID = 0 -- skipping"
8221         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8222         # Check that testing environment is properly set up. Skip if not
8223         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
8224                 skip_env "User $RUNAS_ID does not exist - skipping"
8225
8226         touch $DIR/${tfile}-f{g,u}
8227         test_mkdir $DIR/${tfile}-dg
8228         test_mkdir $DIR/${tfile}-du
8229         chmod 770 $DIR/${tfile}-{f,d}{g,u}
8230         chmod g+s $DIR/${tfile}-{f,d}g
8231         chmod u+s $DIR/${tfile}-{f,d}u
8232         for perm in 777 2777 4777; do
8233                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
8234                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
8235                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
8236                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
8237         done
8238         true
8239 }
8240 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
8241
8242 # bug 3462 - multiple simultaneous MDC requests
8243 test_73() {
8244         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8245
8246         test_mkdir $DIR/d73-1
8247         test_mkdir $DIR/d73-2
8248         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
8249         pid1=$!
8250
8251         lctl set_param fail_loc=0x80000129
8252         $MULTIOP $DIR/d73-1/f73-2 Oc &
8253         sleep 1
8254         lctl set_param fail_loc=0
8255
8256         $MULTIOP $DIR/d73-2/f73-3 Oc &
8257         pid3=$!
8258
8259         kill -USR1 $pid1
8260         wait $pid1 || return 1
8261
8262         sleep 25
8263
8264         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
8265         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
8266         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
8267
8268         rm -rf $DIR/d73-*
8269 }
8270 run_test 73 "multiple MDC requests (should not deadlock)"
8271
8272 test_74a() { # bug 6149, 6184
8273         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8274
8275         touch $DIR/f74a
8276         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8277         #
8278         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8279         # will spin in a tight reconnection loop
8280         $LCTL set_param fail_loc=0x8000030e
8281         # get any lock that won't be difficult - lookup works.
8282         ls $DIR/f74a
8283         $LCTL set_param fail_loc=0
8284         rm -f $DIR/f74a
8285         true
8286 }
8287 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
8288
8289 test_74b() { # bug 13310
8290         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8291
8292         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8293         #
8294         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8295         # will spin in a tight reconnection loop
8296         $LCTL set_param fail_loc=0x8000030e
8297         # get a "difficult" lock
8298         touch $DIR/f74b
8299         $LCTL set_param fail_loc=0
8300         rm -f $DIR/f74b
8301         true
8302 }
8303 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
8304
8305 test_74c() {
8306         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8307
8308         #define OBD_FAIL_LDLM_NEW_LOCK
8309         $LCTL set_param fail_loc=0x319
8310         touch $DIR/$tfile && error "touch successful"
8311         $LCTL set_param fail_loc=0
8312         true
8313 }
8314 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
8315
8316 num_inodes() {
8317         awk '/lustre_inode_cache/ {print $2; exit}' /proc/slabinfo
8318 }
8319
8320 test_76() { # Now for bug 20433, added originally in bug 1443
8321         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8322
8323         cancel_lru_locks osc
8324         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
8325         local before=$(num_inodes)
8326         local count=$((512 * cpus))
8327         [ "$SLOW" = "no" ] && count=$((64 * cpus))
8328
8329         echo "before inodes: $before"
8330         for i in $(seq $count); do
8331                 touch $DIR/$tfile
8332                 rm -f $DIR/$tfile
8333         done
8334         cancel_lru_locks osc
8335         local after=$(num_inodes)
8336         echo "after inodes: $after"
8337         while (( after > before + 8 * ${cpus:-1} )); do
8338                 sleep 1
8339                 after=$(num_inodes)
8340                 wait=$((wait + 1))
8341                 (( wait % 5 == 0 )) && echo "wait $wait seconds inodes: $after"
8342                 if (( wait > 30 )); then
8343                         error "inode slab grew from $before to $after"
8344                 fi
8345         done
8346 }
8347 run_test 76 "confirm clients recycle inodes properly ===="
8348
8349
8350 export ORIG_CSUM=""
8351 set_checksums()
8352 {
8353         # Note: in sptlrpc modes which enable its own bulk checksum, the
8354         # original crc32_le bulk checksum will be automatically disabled,
8355         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
8356         # will be checked by sptlrpc code against sptlrpc bulk checksum.
8357         # In this case set_checksums() will not be no-op, because sptlrpc
8358         # bulk checksum will be enabled all through the test.
8359
8360         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
8361         lctl set_param -n osc.*.checksums $1
8362         return 0
8363 }
8364
8365 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8366                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
8367 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8368                              tr -d [] | head -n1)}
8369 set_checksum_type()
8370 {
8371         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
8372         rc=$?
8373         log "set checksum type to $1, rc = $rc"
8374         return $rc
8375 }
8376
8377 get_osc_checksum_type()
8378 {
8379         # arugment 1: OST name, like OST0000
8380         ost=$1
8381         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
8382                         sed 's/.*\[\(.*\)\].*/\1/g')
8383         rc=$?
8384         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
8385         echo $checksum_type
8386 }
8387
8388 F77_TMP=$TMP/f77-temp
8389 F77SZ=8
8390 setup_f77() {
8391         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
8392                 error "error writing to $F77_TMP"
8393 }
8394
8395 test_77a() { # bug 10889
8396         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8397         $GSS && skip_env "could not run with gss"
8398
8399         [ ! -f $F77_TMP ] && setup_f77
8400         set_checksums 1
8401         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
8402         set_checksums 0
8403         rm -f $DIR/$tfile
8404 }
8405 run_test 77a "normal checksum read/write operation"
8406
8407 test_77b() { # bug 10889
8408         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8409         $GSS && skip_env "could not run with gss"
8410
8411         [ ! -f $F77_TMP ] && setup_f77
8412         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8413         $LCTL set_param fail_loc=0x80000409
8414         set_checksums 1
8415
8416         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8417                 error "dd error: $?"
8418         $LCTL set_param fail_loc=0
8419
8420         for algo in $CKSUM_TYPES; do
8421                 cancel_lru_locks osc
8422                 set_checksum_type $algo
8423                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8424                 $LCTL set_param fail_loc=0x80000408
8425                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
8426                 $LCTL set_param fail_loc=0
8427         done
8428         set_checksums 0
8429         set_checksum_type $ORIG_CSUM_TYPE
8430         rm -f $DIR/$tfile
8431 }
8432 run_test 77b "checksum error on client write, read"
8433
8434 cleanup_77c() {
8435         trap 0
8436         set_checksums 0
8437         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
8438         $check_ost &&
8439                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
8440         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
8441         $check_ost && [ -n "$ost_file_prefix" ] &&
8442                 do_facet ost1 rm -f ${ost_file_prefix}\*
8443 }
8444
8445 test_77c() {
8446         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8447         $GSS && skip_env "could not run with gss"
8448         remote_ost_nodsh && skip "remote OST with nodsh"
8449
8450         local bad1
8451         local osc_file_prefix
8452         local osc_file
8453         local check_ost=false
8454         local ost_file_prefix
8455         local ost_file
8456         local orig_cksum
8457         local dump_cksum
8458         local fid
8459
8460         # ensure corruption will occur on first OSS/OST
8461         $LFS setstripe -i 0 $DIR/$tfile
8462
8463         [ ! -f $F77_TMP ] && setup_f77
8464         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8465                 error "dd write error: $?"
8466         fid=$($LFS path2fid $DIR/$tfile)
8467
8468         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
8469         then
8470                 check_ost=true
8471                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
8472                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
8473         else
8474                 echo "OSS do not support bulk pages dump upon error"
8475         fi
8476
8477         osc_file_prefix=$($LCTL get_param -n debug_path)
8478         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
8479
8480         trap cleanup_77c EXIT
8481
8482         set_checksums 1
8483         # enable bulk pages dump upon error on Client
8484         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
8485         # enable bulk pages dump upon error on OSS
8486         $check_ost &&
8487                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
8488
8489         # flush Client cache to allow next read to reach OSS
8490         cancel_lru_locks osc
8491
8492         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
8493         $LCTL set_param fail_loc=0x80000408
8494         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
8495         $LCTL set_param fail_loc=0
8496
8497         rm -f $DIR/$tfile
8498
8499         # check cksum dump on Client
8500         osc_file=$(ls ${osc_file_prefix}*)
8501         [ -n "$osc_file" ] || error "no checksum dump file on Client"
8502         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
8503         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
8504         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
8505         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
8506                      cksum)
8507         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
8508         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8509                 error "dump content does not match on Client"
8510
8511         $check_ost || skip "No need to check cksum dump on OSS"
8512
8513         # check cksum dump on OSS
8514         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
8515         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
8516         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
8517         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
8518         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8519                 error "dump content does not match on OSS"
8520
8521         cleanup_77c
8522 }
8523 run_test 77c "checksum error on client read with debug"
8524
8525 test_77d() { # bug 10889
8526         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8527         $GSS && skip_env "could not run with gss"
8528
8529         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8530         $LCTL set_param fail_loc=0x80000409
8531         set_checksums 1
8532         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8533                 error "direct write: rc=$?"
8534         $LCTL set_param fail_loc=0
8535         set_checksums 0
8536
8537         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8538         $LCTL set_param fail_loc=0x80000408
8539         set_checksums 1
8540         cancel_lru_locks osc
8541         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8542                 error "direct read: rc=$?"
8543         $LCTL set_param fail_loc=0
8544         set_checksums 0
8545 }
8546 run_test 77d "checksum error on OST direct write, read"
8547
8548 test_77f() { # bug 10889
8549         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8550         $GSS && skip_env "could not run with gss"
8551
8552         set_checksums 1
8553         for algo in $CKSUM_TYPES; do
8554                 cancel_lru_locks osc
8555                 set_checksum_type $algo
8556                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8557                 $LCTL set_param fail_loc=0x409
8558                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
8559                         error "direct write succeeded"
8560                 $LCTL set_param fail_loc=0
8561         done
8562         set_checksum_type $ORIG_CSUM_TYPE
8563         set_checksums 0
8564 }
8565 run_test 77f "repeat checksum error on write (expect error)"
8566
8567 test_77g() { # bug 10889
8568         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8569         $GSS && skip_env "could not run with gss"
8570         remote_ost_nodsh && skip "remote OST with nodsh"
8571
8572         [ ! -f $F77_TMP ] && setup_f77
8573
8574         local file=$DIR/$tfile
8575         stack_trap "rm -f $file" EXIT
8576
8577         $LFS setstripe -c 1 -i 0 $file
8578         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
8579         do_facet ost1 lctl set_param fail_loc=0x8000021a
8580         set_checksums 1
8581         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
8582                 error "write error: rc=$?"
8583         do_facet ost1 lctl set_param fail_loc=0
8584         set_checksums 0
8585
8586         cancel_lru_locks osc
8587         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
8588         do_facet ost1 lctl set_param fail_loc=0x8000021b
8589         set_checksums 1
8590         cmp $F77_TMP $file || error "file compare failed"
8591         do_facet ost1 lctl set_param fail_loc=0
8592         set_checksums 0
8593 }
8594 run_test 77g "checksum error on OST write, read"
8595
8596 test_77k() { # LU-10906
8597         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8598         $GSS && skip_env "could not run with gss"
8599
8600         local cksum_param="osc.$FSNAME*.checksums"
8601         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
8602         local checksum
8603         local i
8604
8605         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
8606         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM" EXIT
8607         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM" \
8608                 EXIT
8609
8610         for i in 0 1; do
8611                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
8612                         error "failed to set checksum=$i on MGS"
8613                 wait_update $HOSTNAME "$get_checksum" $i
8614                 #remount
8615                 echo "remount client, checksum should be $i"
8616                 remount_client $MOUNT || error "failed to remount client"
8617                 checksum=$(eval $get_checksum)
8618                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
8619         done
8620         # remove persistent param to avoid races with checksum mountopt below
8621         do_facet mgs $LCTL set_param -P -d $cksum_param ||
8622                 error "failed to delete checksum on MGS"
8623
8624         for opt in "checksum" "nochecksum"; do
8625                 #remount with mount option
8626                 echo "remount client with option $opt, checksum should be $i"
8627                 umount_client $MOUNT || error "failed to umount client"
8628                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
8629                         error "failed to mount client with option '$opt'"
8630                 checksum=$(eval $get_checksum)
8631                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
8632                 i=$((i - 1))
8633         done
8634
8635         remount_client $MOUNT || error "failed to remount client"
8636 }
8637 run_test 77k "enable/disable checksum correctly"
8638
8639 test_77l() {
8640         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8641         $GSS && skip_env "could not run with gss"
8642
8643         set_checksums 1
8644         stack_trap "set_checksums $ORIG_CSUM" EXIT
8645         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
8646
8647         set_checksum_type invalid && error "unexpected success of invalid checksum type"
8648
8649         $LFS setstripe -c 1 -i 0 $DIR/$tfile
8650         for algo in $CKSUM_TYPES; do
8651                 set_checksum_type $algo || error "fail to set checksum type $algo"
8652                 osc_algo=$(get_osc_checksum_type OST0000)
8653                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
8654
8655                 # no locks, no reqs to let the connection idle
8656                 cancel_lru_locks osc
8657                 lru_resize_disable osc
8658                 wait_osc_import_state client ost1 IDLE
8659
8660                 # ensure ost1 is connected
8661                 stat $DIR/$tfile >/dev/null || error "can't stat"
8662                 wait_osc_import_state client ost1 FULL
8663
8664                 osc_algo=$(get_osc_checksum_type OST0000)
8665                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
8666         done
8667         return 0
8668 }
8669 run_test 77l "preferred checksum type is remembered after reconnected"
8670
8671 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
8672 rm -f $F77_TMP
8673 unset F77_TMP
8674
8675 cleanup_test_78() {
8676         trap 0
8677         rm -f $DIR/$tfile
8678 }
8679
8680 test_78() { # bug 10901
8681         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8682         remote_ost || skip_env "local OST"
8683
8684         NSEQ=5
8685         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
8686         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
8687         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
8688         echo "MemTotal: $MEMTOTAL"
8689
8690         # reserve 256MB of memory for the kernel and other running processes,
8691         # and then take 1/2 of the remaining memory for the read/write buffers.
8692         if [ $MEMTOTAL -gt 512 ] ;then
8693                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
8694         else
8695                 # for those poor memory-starved high-end clusters...
8696                 MEMTOTAL=$((MEMTOTAL / 2))
8697         fi
8698         echo "Mem to use for directio: $MEMTOTAL"
8699
8700         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
8701         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
8702         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
8703         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
8704                 head -n1)
8705         echo "Smallest OST: $SMALLESTOST"
8706         [[ $SMALLESTOST -lt 10240 ]] &&
8707                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
8708
8709         trap cleanup_test_78 EXIT
8710
8711         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
8712                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
8713
8714         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
8715         echo "File size: $F78SIZE"
8716         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
8717         for i in $(seq 1 $NSEQ); do
8718                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
8719                 echo directIO rdwr round $i of $NSEQ
8720                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
8721         done
8722
8723         cleanup_test_78
8724 }
8725 run_test 78 "handle large O_DIRECT writes correctly ============"
8726
8727 test_79() { # bug 12743
8728         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8729
8730         wait_delete_completed
8731
8732         BKTOTAL=$(calc_osc_kbytes kbytestotal)
8733         BKFREE=$(calc_osc_kbytes kbytesfree)
8734         BKAVAIL=$(calc_osc_kbytes kbytesavail)
8735
8736         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
8737         DFTOTAL=`echo $STRING | cut -d, -f1`
8738         DFUSED=`echo $STRING  | cut -d, -f2`
8739         DFAVAIL=`echo $STRING | cut -d, -f3`
8740         DFFREE=$(($DFTOTAL - $DFUSED))
8741
8742         ALLOWANCE=$((64 * $OSTCOUNT))
8743
8744         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
8745            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
8746                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
8747         fi
8748         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
8749            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
8750                 error "df free($DFFREE) mismatch OST free($BKFREE)"
8751         fi
8752         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
8753            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
8754                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
8755         fi
8756 }
8757 run_test 79 "df report consistency check ======================="
8758
8759 test_80() { # bug 10718
8760         remote_ost_nodsh && skip "remote OST with nodsh"
8761         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8762
8763         # relax strong synchronous semantics for slow backends like ZFS
8764         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
8765                 local soc="obdfilter.*.sync_lock_cancel"
8766                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
8767
8768                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
8769                 if [ -z "$save" ]; then
8770                         soc="obdfilter.*.sync_on_lock_cancel"
8771                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
8772                 fi
8773
8774                 if [ "$save" != "never" ]; then
8775                         local hosts=$(comma_list $(osts_nodes))
8776
8777                         do_nodes $hosts $LCTL set_param $soc=never
8778                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
8779                 fi
8780         fi
8781
8782         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
8783         sync; sleep 1; sync
8784         local before=$(date +%s)
8785         cancel_lru_locks osc
8786         local after=$(date +%s)
8787         local diff=$((after - before))
8788         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
8789
8790         rm -f $DIR/$tfile
8791 }
8792 run_test 80 "Page eviction is equally fast at high offsets too"
8793
8794 test_81a() { # LU-456
8795         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8796         remote_ost_nodsh && skip "remote OST with nodsh"
8797
8798         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
8799         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
8800         do_facet ost1 lctl set_param fail_loc=0x80000228
8801
8802         # write should trigger a retry and success
8803         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8804         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
8805         RC=$?
8806         if [ $RC -ne 0 ] ; then
8807                 error "write should success, but failed for $RC"
8808         fi
8809 }
8810 run_test 81a "OST should retry write when get -ENOSPC ==============="
8811
8812 test_81b() { # LU-456
8813         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8814         remote_ost_nodsh && skip "remote OST with nodsh"
8815
8816         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
8817         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
8818         do_facet ost1 lctl set_param fail_loc=0x228
8819
8820         # write should retry several times and return -ENOSPC finally
8821         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8822         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
8823         RC=$?
8824         ENOSPC=28
8825         if [ $RC -ne $ENOSPC ] ; then
8826                 error "dd should fail for -ENOSPC, but succeed."
8827         fi
8828 }
8829 run_test 81b "OST should return -ENOSPC when retry still fails ======="
8830
8831 test_82() { # LU-1031
8832         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10
8833         local gid1=14091995
8834         local gid2=16022000
8835
8836         multiop_bg_pause $DIR/$tfile OG${gid1}_g${gid1}c || return 1
8837         local MULTIPID1=$!
8838         multiop_bg_pause $DIR/$tfile O_G${gid2}r10g${gid2}c || return 2
8839         local MULTIPID2=$!
8840         kill -USR1 $MULTIPID2
8841         sleep 2
8842         if [[ `ps h -o comm -p $MULTIPID2` == "" ]]; then
8843                 error "First grouplock does not block second one"
8844         else
8845                 echo "Second grouplock blocks first one"
8846         fi
8847         kill -USR1 $MULTIPID1
8848         wait $MULTIPID1
8849         wait $MULTIPID2
8850 }
8851 run_test 82 "Basic grouplock test"
8852
8853 test_99() {
8854         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
8855
8856         test_mkdir $DIR/$tdir.cvsroot
8857         chown $RUNAS_ID $DIR/$tdir.cvsroot
8858
8859         cd $TMP
8860         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
8861
8862         cd /etc/init.d
8863         # some versions of cvs import exit(1) when asked to import links or
8864         # files they can't read.  ignore those files.
8865         local toignore=$(find . -type l -printf '-I %f\n' -o \
8866                          ! -perm /4 -printf '-I %f\n')
8867         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
8868                 $tdir.reposname vtag rtag
8869
8870         cd $DIR
8871         test_mkdir $DIR/$tdir.reposname
8872         chown $RUNAS_ID $DIR/$tdir.reposname
8873         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
8874
8875         cd $DIR/$tdir.reposname
8876         $RUNAS touch foo99
8877         $RUNAS cvs add -m 'addmsg' foo99
8878         $RUNAS cvs update
8879         $RUNAS cvs commit -m 'nomsg' foo99
8880         rm -fr $DIR/$tdir.cvsroot
8881 }
8882 run_test 99 "cvs strange file/directory operations"
8883
8884 test_100() {
8885         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8886         [[ "$NETTYPE" =~ tcp ]] ||
8887                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
8888         remote_ost_nodsh && skip "remote OST with nodsh"
8889         remote_mds_nodsh && skip "remote MDS with nodsh"
8890         remote_servers ||
8891                 skip "useless for local single node setup"
8892
8893         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
8894                 [ "$PROT" != "tcp" ] && continue
8895                 RPORT=$(echo $REMOTE | cut -d: -f2)
8896                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
8897
8898                 rc=0
8899                 LPORT=`echo $LOCAL | cut -d: -f2`
8900                 if [ $LPORT -ge 1024 ]; then
8901                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
8902                         netstat -tna
8903                         error_exit "local: $LPORT > 1024, remote: $RPORT"
8904                 fi
8905         done
8906         [ "$rc" = 0 ] || error_exit "privileged port not found" )
8907 }
8908 run_test 100 "check local port using privileged port ==========="
8909
8910 function get_named_value()
8911 {
8912     local tag
8913
8914     tag=$1
8915     while read ;do
8916         line=$REPLY
8917         case $line in
8918         $tag*)
8919             echo $line | sed "s/^$tag[ ]*//"
8920             break
8921             ;;
8922         esac
8923     done
8924 }
8925
8926 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
8927                    awk '/^max_cached_mb/ { print $2 }')
8928
8929 cleanup_101a() {
8930         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
8931         trap 0
8932 }
8933
8934 test_101a() {
8935         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8936
8937         local s
8938         local discard
8939         local nreads=10000
8940         local cache_limit=32
8941
8942         $LCTL set_param -n osc.*-osc*.rpc_stats 0
8943         trap cleanup_101a EXIT
8944         $LCTL set_param -n llite.*.read_ahead_stats 0
8945         $LCTL set_param -n llite.*.max_cached_mb $cache_limit
8946
8947         #
8948         # randomly read 10000 of 64K chunks from file 3x 32MB in size
8949         #
8950         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
8951         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
8952
8953         discard=0
8954         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
8955                 get_named_value 'read but discarded' | cut -d" " -f1); do
8956                         discard=$(($discard + $s))
8957         done
8958         cleanup_101a
8959
8960         $LCTL get_param osc.*-osc*.rpc_stats
8961         $LCTL get_param llite.*.read_ahead_stats
8962
8963         # Discard is generally zero, but sometimes a few random reads line up
8964         # and trigger larger readahead, which is wasted & leads to discards.
8965         if [[ $(($discard)) -gt $nreads ]]; then
8966                 error "too many ($discard) discarded pages"
8967         fi
8968         rm -f $DIR/$tfile || true
8969 }
8970 run_test 101a "check read-ahead for random reads"
8971
8972 setup_test101bc() {
8973         test_mkdir $DIR/$tdir
8974         local ssize=$1
8975         local FILE_LENGTH=$2
8976         STRIPE_OFFSET=0
8977
8978         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
8979
8980         local list=$(comma_list $(osts_nodes))
8981         set_osd_param $list '' read_cache_enable 0
8982         set_osd_param $list '' writethrough_cache_enable 0
8983
8984         trap cleanup_test101bc EXIT
8985         # prepare the read-ahead file
8986         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
8987
8988         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
8989                                 count=$FILE_SIZE_MB 2> /dev/null
8990
8991 }
8992
8993 cleanup_test101bc() {
8994         trap 0
8995         rm -rf $DIR/$tdir
8996         rm -f $DIR/$tfile
8997
8998         local list=$(comma_list $(osts_nodes))
8999         set_osd_param $list '' read_cache_enable 1
9000         set_osd_param $list '' writethrough_cache_enable 1
9001 }
9002
9003 calc_total() {
9004         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
9005 }
9006
9007 ra_check_101() {
9008         local READ_SIZE=$1
9009         local STRIPE_SIZE=$2
9010         local FILE_LENGTH=$3
9011         local RA_INC=1048576
9012         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
9013         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
9014                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
9015         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
9016                         get_named_value 'read but discarded' |
9017                         cut -d" " -f1 | calc_total)
9018         if [[ $DISCARD -gt $discard_limit ]]; then
9019                 $LCTL get_param llite.*.read_ahead_stats
9020                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
9021         else
9022                 echo "Read-ahead success for size ${READ_SIZE}"
9023         fi
9024 }
9025
9026 test_101b() {
9027         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9028         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9029
9030         local STRIPE_SIZE=1048576
9031         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
9032
9033         if [ $SLOW == "yes" ]; then
9034                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
9035         else
9036                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
9037         fi
9038
9039         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
9040
9041         # prepare the read-ahead file
9042         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9043         cancel_lru_locks osc
9044         for BIDX in 2 4 8 16 32 64 128 256
9045         do
9046                 local BSIZE=$((BIDX*4096))
9047                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
9048                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
9049                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
9050                 $LCTL set_param -n llite.*.read_ahead_stats 0
9051                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
9052                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
9053                 cancel_lru_locks osc
9054                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
9055         done
9056         cleanup_test101bc
9057         true
9058 }
9059 run_test 101b "check stride-io mode read-ahead ================="
9060
9061 test_101c() {
9062         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9063
9064         local STRIPE_SIZE=1048576
9065         local FILE_LENGTH=$((STRIPE_SIZE*100))
9066         local nreads=10000
9067         local rsize=65536
9068         local osc_rpc_stats
9069
9070         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9071
9072         cancel_lru_locks osc
9073         $LCTL set_param osc.*.rpc_stats 0
9074         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
9075         $LCTL get_param osc.*.rpc_stats
9076         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
9077                 local stats=$($LCTL get_param -n $osc_rpc_stats)
9078                 local lines=$(echo "$stats" | awk 'END {print NR;}')
9079                 local size
9080
9081                 if [ $lines -le 20 ]; then
9082                         echo "continue debug"
9083                         continue
9084                 fi
9085                 for size in 1 2 4 8; do
9086                         local rpc=$(echo "$stats" |
9087                                     awk '($1 == "'$size':") {print $2; exit; }')
9088                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
9089                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
9090                 done
9091                 echo "$osc_rpc_stats check passed!"
9092         done
9093         cleanup_test101bc
9094         true
9095 }
9096 run_test 101c "check stripe_size aligned read-ahead ================="
9097
9098 test_101d() {
9099         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9100
9101         local file=$DIR/$tfile
9102         local sz_MB=${FILESIZE_101d:-500}
9103         local ra_MB=${READAHEAD_MB:-40}
9104
9105         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
9106         [ $free_MB -lt $sz_MB ] &&
9107                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
9108
9109         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
9110         $LFS setstripe -c -1 $file || error "setstripe failed"
9111
9112         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
9113         echo Cancel LRU locks on lustre client to flush the client cache
9114         cancel_lru_locks osc
9115
9116         echo Disable read-ahead
9117         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9118         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9119         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_RA" EXIT
9120         $LCTL get_param -n llite.*.max_read_ahead_mb
9121
9122         echo Reading the test file $file with read-ahead disabled
9123         local raOFF=$(do_and_time "dd if=$file of=/dev/null bs=1M count=$sz_MB")
9124
9125         echo Cancel LRU locks on lustre client to flush the client cache
9126         cancel_lru_locks osc
9127         echo Enable read-ahead with ${ra_MB}MB
9128         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
9129
9130         echo Reading the test file $file with read-ahead enabled
9131         local raON=$(do_and_time "dd if=$file of=/dev/null bs=1M count=$sz_MB")
9132
9133         echo "read-ahead disabled time read $raOFF"
9134         echo "read-ahead enabled  time read $raON"
9135
9136         rm -f $file
9137         wait_delete_completed
9138
9139         [ $raOFF -le 1 ] || [ $raON -lt $raOFF ] ||
9140                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
9141 }
9142 run_test 101d "file read with and without read-ahead enabled"
9143
9144 test_101e() {
9145         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9146
9147         local file=$DIR/$tfile
9148         local size_KB=500  #KB
9149         local count=100
9150         local bsize=1024
9151
9152         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
9153         local need_KB=$((count * size_KB))
9154         [[ $free_KB -le $need_KB ]] &&
9155                 skip_env "Need free space $need_KB, have $free_KB"
9156
9157         echo "Creating $count ${size_KB}K test files"
9158         for ((i = 0; i < $count; i++)); do
9159                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
9160         done
9161
9162         echo "Cancel LRU locks on lustre client to flush the client cache"
9163         cancel_lru_locks $OSC
9164
9165         echo "Reset readahead stats"
9166         $LCTL set_param -n llite.*.read_ahead_stats 0
9167
9168         for ((i = 0; i < $count; i++)); do
9169                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
9170         done
9171
9172         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9173                      get_named_value 'misses' | cut -d" " -f1 | calc_total)
9174
9175         for ((i = 0; i < $count; i++)); do
9176                 rm -rf $file.$i 2>/dev/null
9177         done
9178
9179         #10000 means 20% reads are missing in readahead
9180         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
9181 }
9182 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
9183
9184 test_101f() {
9185         which iozone || skip_env "no iozone installed"
9186
9187         local old_debug=$($LCTL get_param debug)
9188         old_debug=${old_debug#*=}
9189         $LCTL set_param debug="reada mmap"
9190
9191         # create a test file
9192         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
9193
9194         echo Cancel LRU locks on lustre client to flush the client cache
9195         cancel_lru_locks osc
9196
9197         echo Reset readahead stats
9198         $LCTL set_param -n llite.*.read_ahead_stats 0
9199
9200         echo mmap read the file with small block size
9201         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
9202                 > /dev/null 2>&1
9203
9204         echo checking missing pages
9205         $LCTL get_param llite.*.read_ahead_stats
9206         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9207                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9208
9209         $LCTL set_param debug="$old_debug"
9210         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
9211         rm -f $DIR/$tfile
9212 }
9213 run_test 101f "check mmap read performance"
9214
9215 test_101g_brw_size_test() {
9216         local mb=$1
9217         local pages=$((mb * 1048576 / PAGE_SIZE))
9218         local file=$DIR/$tfile
9219
9220         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
9221                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
9222         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
9223                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
9224                         return 2
9225         done
9226
9227         stack_trap "rm -f $file" EXIT
9228         $LCTL set_param -n osc.*.rpc_stats=0
9229
9230         # 10 RPCs should be enough for the test
9231         local count=10
9232         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
9233                 { error "dd write ${mb} MB blocks failed"; return 3; }
9234         cancel_lru_locks osc
9235         dd of=/dev/null if=$file bs=${mb}M count=$count ||
9236                 { error "dd write ${mb} MB blocks failed"; return 4; }
9237
9238         # calculate number of full-sized read and write RPCs
9239         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
9240                 sed -n '/pages per rpc/,/^$/p' |
9241                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
9242                 END { print reads,writes }'))
9243         [ ${rpcs[0]} -ne $count ] && error "${rpcs[0]} != $count read RPCs" &&
9244                 return 5
9245         [ ${rpcs[1]} -ne $count ] && error "${rpcs[1]} != $count write RPCs" &&
9246                 return 6
9247
9248         return 0
9249 }
9250
9251 test_101g() {
9252         remote_ost_nodsh && skip "remote OST with nodsh"
9253
9254         local rpcs
9255         local osts=$(get_facets OST)
9256         local list=$(comma_list $(osts_nodes))
9257         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9258         local brw_size="obdfilter.*.brw_size"
9259
9260         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9261
9262         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
9263
9264         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
9265                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
9266                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
9267            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
9268                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
9269                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
9270
9271                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
9272                         suffix="M"
9273
9274                 if [[ $orig_mb -lt 16 ]]; then
9275                         save_lustre_params $osts "$brw_size" > $p
9276                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
9277                                 error "set 16MB RPC size failed"
9278
9279                         echo "remount client to enable new RPC size"
9280                         remount_client $MOUNT || error "remount_client failed"
9281                 fi
9282
9283                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
9284                 # should be able to set brw_size=12, but no rpc_stats for that
9285                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
9286         fi
9287
9288         test_101g_brw_size_test 4 || error "4MB RPC test failed"
9289
9290         if [[ $orig_mb -lt 16 ]]; then
9291                 restore_lustre_params < $p
9292                 remount_client $MOUNT || error "remount_client restore failed"
9293         fi
9294
9295         rm -f $p $DIR/$tfile
9296 }
9297 run_test 101g "Big bulk(4/16 MiB) readahead"
9298
9299 test_101h() {
9300         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9301
9302         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
9303                 error "dd 70M file failed"
9304         echo Cancel LRU locks on lustre client to flush the client cache
9305         cancel_lru_locks osc
9306
9307         echo "Reset readahead stats"
9308         $LCTL set_param -n llite.*.read_ahead_stats 0
9309
9310         echo "Read 10M of data but cross 64M bundary"
9311         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
9312         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9313                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9314         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
9315         rm -f $p $DIR/$tfile
9316 }
9317 run_test 101h "Readahead should cover current read window"
9318
9319 test_101i() {
9320         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
9321                 error "dd 10M file failed"
9322
9323         local max_per_file_mb=$($LCTL get_param -n \
9324                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
9325         cancel_lru_locks osc
9326         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
9327         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
9328                 error "set max_read_ahead_per_file_mb to 1 failed"
9329
9330         echo "Reset readahead stats"
9331         $LCTL set_param llite.*.read_ahead_stats=0
9332
9333         dd if=$DIR/$tfile of=/dev/null bs=2M
9334
9335         $LCTL get_param llite.*.read_ahead_stats
9336         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9337                      awk '/misses/ { print $2 }')
9338         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
9339         rm -f $DIR/$tfile
9340 }
9341 run_test 101i "allow current readahead to exceed reservation"
9342
9343 setup_test102() {
9344         test_mkdir $DIR/$tdir
9345         chown $RUNAS_ID $DIR/$tdir
9346         STRIPE_SIZE=65536
9347         STRIPE_OFFSET=1
9348         STRIPE_COUNT=$OSTCOUNT
9349         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
9350
9351         trap cleanup_test102 EXIT
9352         cd $DIR
9353         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
9354         cd $DIR/$tdir
9355         for num in 1 2 3 4; do
9356                 for count in $(seq 1 $STRIPE_COUNT); do
9357                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
9358                                 local size=`expr $STRIPE_SIZE \* $num`
9359                                 local file=file"$num-$idx-$count"
9360                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
9361                         done
9362                 done
9363         done
9364
9365         cd $DIR
9366         $1 tar cf $TMP/f102.tar $tdir --xattrs
9367 }
9368
9369 cleanup_test102() {
9370         trap 0
9371         rm -f $TMP/f102.tar
9372         rm -rf $DIR/d0.sanity/d102
9373 }
9374
9375 test_102a() {
9376         [ "$UID" != 0 ] && skip "must run as root"
9377         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
9378                 skip_env "must have user_xattr"
9379
9380         [ -z "$(which setfattr 2>/dev/null)" ] &&
9381                 skip_env "could not find setfattr"
9382
9383         local testfile=$DIR/$tfile
9384
9385         touch $testfile
9386         echo "set/get xattr..."
9387         setfattr -n trusted.name1 -v value1 $testfile ||
9388                 error "setfattr -n trusted.name1=value1 $testfile failed"
9389         getfattr -n trusted.name1 $testfile 2> /dev/null |
9390           grep "trusted.name1=.value1" ||
9391                 error "$testfile missing trusted.name1=value1"
9392
9393         setfattr -n user.author1 -v author1 $testfile ||
9394                 error "setfattr -n user.author1=author1 $testfile failed"
9395         getfattr -n user.author1 $testfile 2> /dev/null |
9396           grep "user.author1=.author1" ||
9397                 error "$testfile missing trusted.author1=author1"
9398
9399         echo "listxattr..."
9400         setfattr -n trusted.name2 -v value2 $testfile ||
9401                 error "$testfile unable to set trusted.name2"
9402         setfattr -n trusted.name3 -v value3 $testfile ||
9403                 error "$testfile unable to set trusted.name3"
9404         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
9405             grep "trusted.name" | wc -l) -eq 3 ] ||
9406                 error "$testfile missing 3 trusted.name xattrs"
9407
9408         setfattr -n user.author2 -v author2 $testfile ||
9409                 error "$testfile unable to set user.author2"
9410         setfattr -n user.author3 -v author3 $testfile ||
9411                 error "$testfile unable to set user.author3"
9412         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
9413             grep "user.author" | wc -l) -eq 3 ] ||
9414                 error "$testfile missing 3 user.author xattrs"
9415
9416         echo "remove xattr..."
9417         setfattr -x trusted.name1 $testfile ||
9418                 error "$testfile error deleting trusted.name1"
9419         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
9420                 error "$testfile did not delete trusted.name1 xattr"
9421
9422         setfattr -x user.author1 $testfile ||
9423                 error "$testfile error deleting user.author1"
9424         echo "set lustre special xattr ..."
9425         $LFS setstripe -c1 $testfile
9426         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
9427                 awk -F "=" '/trusted.lov/ { print $2 }' )
9428         setfattr -n "trusted.lov" -v $lovea $testfile ||
9429                 error "$testfile doesn't ignore setting trusted.lov again"
9430         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
9431                 error "$testfile allow setting invalid trusted.lov"
9432         rm -f $testfile
9433 }
9434 run_test 102a "user xattr test =================================="
9435
9436 test_102b() {
9437         [ -z "$(which setfattr 2>/dev/null)" ] &&
9438                 skip_env "could not find setfattr"
9439         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9440
9441         # b10930: get/set/list trusted.lov xattr
9442         echo "get/set/list trusted.lov xattr ..."
9443         local testfile=$DIR/$tfile
9444         $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
9445                 error "setstripe failed"
9446         local STRIPECOUNT=$($LFS getstripe -c $testfile) ||
9447                 error "getstripe failed"
9448         getfattr -d -m "^trusted" $testfile 2>/dev/null | grep "trusted.lov" ||
9449                 error "can't get trusted.lov from $testfile"
9450
9451         local testfile2=${testfile}2
9452         local value=$(getfattr -n trusted.lov $testfile 2>/dev/null |
9453                         grep "trusted.lov" | sed -e 's/[^=]\+=//')
9454
9455         $MCREATE $testfile2
9456         setfattr -n trusted.lov -v $value $testfile2
9457         local stripe_size=$($LFS getstripe -S $testfile2)
9458         local stripe_count=$($LFS getstripe -c $testfile2)
9459         [[ $stripe_size -eq 65536 ]] ||
9460                 error "stripe size $stripe_size != 65536"
9461         [[ $stripe_count -eq $STRIPECOUNT ]] ||
9462                 error "stripe count $stripe_count != $STRIPECOUNT"
9463         rm -f $DIR/$tfile
9464 }
9465 run_test 102b "getfattr/setfattr for trusted.lov EAs ============"
9466
9467 test_102c() {
9468         [ -z "$(which setfattr 2>/dev/null)" ] &&
9469                 skip_env "could not find setfattr"
9470         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9471
9472         # b10930: get/set/list lustre.lov xattr
9473         echo "get/set/list lustre.lov xattr ..."
9474         test_mkdir $DIR/$tdir
9475         chown $RUNAS_ID $DIR/$tdir
9476         local testfile=$DIR/$tdir/$tfile
9477         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
9478                 error "setstripe failed"
9479         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
9480                 error "getstripe failed"
9481         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
9482         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
9483
9484         local testfile2=${testfile}2
9485         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
9486                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
9487
9488         $RUNAS $MCREATE $testfile2
9489         $RUNAS setfattr -n lustre.lov -v $value $testfile2
9490         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
9491         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
9492         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
9493         [ $stripe_count -eq $STRIPECOUNT ] ||
9494                 error "stripe count $stripe_count != $STRIPECOUNT"
9495 }
9496 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
9497
9498 compare_stripe_info1() {
9499         local stripe_index_all_zero=true
9500
9501         for num in 1 2 3 4; do
9502                 for count in $(seq 1 $STRIPE_COUNT); do
9503                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
9504                                 local size=$((STRIPE_SIZE * num))
9505                                 local file=file"$num-$offset-$count"
9506                                 stripe_size=$($LFS getstripe -S $PWD/$file)
9507                                 [[ $stripe_size -ne $size ]] &&
9508                                     error "$file: size $stripe_size != $size"
9509                                 stripe_count=$($LFS getstripe -c $PWD/$file)
9510                                 # allow fewer stripes to be created, ORI-601
9511                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
9512                                     error "$file: count $stripe_count != $count"
9513                                 stripe_index=$($LFS getstripe -i $PWD/$file)
9514                                 [[ $stripe_index -ne 0 ]] &&
9515                                         stripe_index_all_zero=false
9516                         done
9517                 done
9518         done
9519         $stripe_index_all_zero &&
9520                 error "all files are being extracted starting from OST index 0"
9521         return 0
9522 }
9523
9524 have_xattrs_include() {
9525         tar --help | grep -q xattrs-include &&
9526                 echo --xattrs-include="lustre.*"
9527 }
9528
9529 test_102d() {
9530         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9531         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9532
9533         XINC=$(have_xattrs_include)
9534         setup_test102
9535         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
9536         cd $DIR/$tdir/$tdir
9537         compare_stripe_info1
9538 }
9539 run_test 102d "tar restore stripe info from tarfile,not keep osts"
9540
9541 test_102f() {
9542         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9543         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9544
9545         XINC=$(have_xattrs_include)
9546         setup_test102
9547         test_mkdir $DIR/$tdir.restore
9548         cd $DIR
9549         tar cf - --xattrs $tdir | tar xf - \
9550                 -C $DIR/$tdir.restore --xattrs $XINC
9551         cd $DIR/$tdir.restore/$tdir
9552         compare_stripe_info1
9553 }
9554 run_test 102f "tar copy files, not keep osts"
9555
9556 grow_xattr() {
9557         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
9558                 skip "must have user_xattr"
9559         [ -z "$(which setfattr 2>/dev/null)" ] &&
9560                 skip_env "could not find setfattr"
9561         [ -z "$(which getfattr 2>/dev/null)" ] &&
9562                 skip_env "could not find getfattr"
9563
9564         local xsize=${1:-1024}  # in bytes
9565         local file=$DIR/$tfile
9566         local value="$(generate_string $xsize)"
9567         local xbig=trusted.big
9568         local toobig=$2
9569
9570         touch $file
9571         log "save $xbig on $file"
9572         if [ -z "$toobig" ]
9573         then
9574                 setfattr -n $xbig -v $value $file ||
9575                         error "saving $xbig on $file failed"
9576         else
9577                 setfattr -n $xbig -v $value $file &&
9578                         error "saving $xbig on $file succeeded"
9579                 return 0
9580         fi
9581
9582         local orig=$(get_xattr_value $xbig $file)
9583         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
9584
9585         local xsml=trusted.sml
9586         log "save $xsml on $file"
9587         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
9588
9589         local new=$(get_xattr_value $xbig $file)
9590         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
9591
9592         log "grow $xsml on $file"
9593         setfattr -n $xsml -v "$value" $file ||
9594                 error "growing $xsml on $file failed"
9595
9596         new=$(get_xattr_value $xbig $file)
9597         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
9598         log "$xbig still valid after growing $xsml"
9599
9600         rm -f $file
9601 }
9602
9603 test_102h() { # bug 15777
9604         grow_xattr 1024
9605 }
9606 run_test 102h "grow xattr from inside inode to external block"
9607
9608 test_102ha() {
9609         large_xattr_enabled || skip_env "ea_inode feature disabled"
9610
9611         echo "setting xattr of max xattr size: $(max_xattr_size)"
9612         grow_xattr $(max_xattr_size)
9613
9614         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
9615         echo "This should fail:"
9616         grow_xattr $(($(max_xattr_size) + 10)) 1
9617 }
9618 run_test 102ha "grow xattr from inside inode to external inode"
9619
9620 test_102i() { # bug 17038
9621         [ -z "$(which getfattr 2>/dev/null)" ] &&
9622                 skip "could not find getfattr"
9623
9624         touch $DIR/$tfile
9625         ln -s $DIR/$tfile $DIR/${tfile}link
9626         getfattr -n trusted.lov $DIR/$tfile ||
9627                 error "lgetxattr on $DIR/$tfile failed"
9628         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
9629                 grep -i "no such attr" ||
9630                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
9631         rm -f $DIR/$tfile $DIR/${tfile}link
9632 }
9633 run_test 102i "lgetxattr test on symbolic link ============"
9634
9635 test_102j() {
9636         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9637         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9638
9639         XINC=$(have_xattrs_include)
9640         setup_test102 "$RUNAS"
9641         chown $RUNAS_ID $DIR/$tdir
9642         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
9643         cd $DIR/$tdir/$tdir
9644         compare_stripe_info1 "$RUNAS"
9645 }
9646 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
9647
9648 test_102k() {
9649         [ -z "$(which setfattr 2>/dev/null)" ] &&
9650                 skip "could not find setfattr"
9651
9652         touch $DIR/$tfile
9653         # b22187 just check that does not crash for regular file.
9654         setfattr -n trusted.lov $DIR/$tfile
9655         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
9656         local test_kdir=$DIR/$tdir
9657         test_mkdir $test_kdir
9658         local default_size=$($LFS getstripe -S $test_kdir)
9659         local default_count=$($LFS getstripe -c $test_kdir)
9660         local default_offset=$($LFS getstripe -i $test_kdir)
9661         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
9662                 error 'dir setstripe failed'
9663         setfattr -n trusted.lov $test_kdir
9664         local stripe_size=$($LFS getstripe -S $test_kdir)
9665         local stripe_count=$($LFS getstripe -c $test_kdir)
9666         local stripe_offset=$($LFS getstripe -i $test_kdir)
9667         [ $stripe_size -eq $default_size ] ||
9668                 error "stripe size $stripe_size != $default_size"
9669         [ $stripe_count -eq $default_count ] ||
9670                 error "stripe count $stripe_count != $default_count"
9671         [ $stripe_offset -eq $default_offset ] ||
9672                 error "stripe offset $stripe_offset != $default_offset"
9673         rm -rf $DIR/$tfile $test_kdir
9674 }
9675 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
9676
9677 test_102l() {
9678         [ -z "$(which getfattr 2>/dev/null)" ] &&
9679                 skip "could not find getfattr"
9680
9681         # LU-532 trusted. xattr is invisible to non-root
9682         local testfile=$DIR/$tfile
9683
9684         touch $testfile
9685
9686         echo "listxattr as user..."
9687         chown $RUNAS_ID $testfile
9688         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
9689             grep -q "trusted" &&
9690                 error "$testfile trusted xattrs are user visible"
9691
9692         return 0;
9693 }
9694 run_test 102l "listxattr size test =================================="
9695
9696 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
9697         local path=$DIR/$tfile
9698         touch $path
9699
9700         listxattr_size_check $path || error "listattr_size_check $path failed"
9701 }
9702 run_test 102m "Ensure listxattr fails on small bufffer ========"
9703
9704 cleanup_test102
9705
9706 getxattr() { # getxattr path name
9707         # Return the base64 encoding of the value of xattr name on path.
9708         local path=$1
9709         local name=$2
9710
9711         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
9712         # file: $path
9713         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
9714         #
9715         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
9716
9717         getfattr --absolute-names --encoding=base64 --name=$name $path |
9718                 awk -F= -v name=$name '$1 == name {
9719                         print substr($0, index($0, "=") + 1);
9720         }'
9721 }
9722
9723 test_102n() { # LU-4101 mdt: protect internal xattrs
9724         [ -z "$(which setfattr 2>/dev/null)" ] &&
9725                 skip "could not find setfattr"
9726         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
9727         then
9728                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
9729         fi
9730
9731         local file0=$DIR/$tfile.0
9732         local file1=$DIR/$tfile.1
9733         local xattr0=$TMP/$tfile.0
9734         local xattr1=$TMP/$tfile.1
9735         local namelist="lov lma lmv link fid version som hsm"
9736         local name
9737         local value
9738
9739         rm -rf $file0 $file1 $xattr0 $xattr1
9740         touch $file0 $file1
9741
9742         # Get 'before' xattrs of $file1.
9743         getfattr --absolute-names --dump --match=- $file1 > $xattr0
9744
9745         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
9746                 namelist+=" lfsck_namespace"
9747         for name in $namelist; do
9748                 # Try to copy xattr from $file0 to $file1.
9749                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
9750
9751                 setfattr --name=trusted.$name --value="$value" $file1 ||
9752                         error "setxattr 'trusted.$name' failed"
9753
9754                 # Try to set a garbage xattr.
9755                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
9756
9757                 if [[ x$name == "xlov" ]]; then
9758                         setfattr --name=trusted.lov --value="$value" $file1 &&
9759                         error "setxattr invalid 'trusted.lov' success"
9760                 else
9761                         setfattr --name=trusted.$name --value="$value" $file1 ||
9762                                 error "setxattr invalid 'trusted.$name' failed"
9763                 fi
9764
9765                 # Try to remove the xattr from $file1. We don't care if this
9766                 # appears to succeed or fail, we just don't want there to be
9767                 # any changes or crashes.
9768                 setfattr --remove=$trusted.$name $file1 2> /dev/null
9769         done
9770
9771         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
9772         then
9773                 name="lfsck_ns"
9774                 # Try to copy xattr from $file0 to $file1.
9775                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
9776
9777                 setfattr --name=trusted.$name --value="$value" $file1 ||
9778                         error "setxattr 'trusted.$name' failed"
9779
9780                 # Try to set a garbage xattr.
9781                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
9782
9783                 setfattr --name=trusted.$name --value="$value" $file1 ||
9784                         error "setxattr 'trusted.$name' failed"
9785
9786                 # Try to remove the xattr from $file1. We don't care if this
9787                 # appears to succeed or fail, we just don't want there to be
9788                 # any changes or crashes.
9789                 setfattr --remove=$trusted.$name $file1 2> /dev/null
9790         fi
9791
9792         # Get 'after' xattrs of file1.
9793         getfattr --absolute-names --dump --match=- $file1 > $xattr1
9794
9795         if ! diff $xattr0 $xattr1; then
9796                 error "before and after xattrs of '$file1' differ"
9797         fi
9798
9799         rm -rf $file0 $file1 $xattr0 $xattr1
9800
9801         return 0
9802 }
9803 run_test 102n "silently ignore setxattr on internal trusted xattrs"
9804
9805 test_102p() { # LU-4703 setxattr did not check ownership
9806         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
9807                 skip "MDS needs to be at least 2.5.56"
9808
9809         local testfile=$DIR/$tfile
9810
9811         touch $testfile
9812
9813         echo "setfacl as user..."
9814         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
9815         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
9816
9817         echo "setfattr as user..."
9818         setfacl -m "u:$RUNAS_ID:---" $testfile
9819         $RUNAS setfattr -x system.posix_acl_access $testfile
9820         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
9821 }
9822 run_test 102p "check setxattr(2) correctly fails without permission"
9823
9824 test_102q() {
9825         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
9826                 skip "MDS needs to be at least 2.6.92"
9827
9828         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
9829 }
9830 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
9831
9832 test_102r() {
9833         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
9834                 skip "MDS needs to be at least 2.6.93"
9835
9836         touch $DIR/$tfile || error "touch"
9837         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
9838         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
9839         rm $DIR/$tfile || error "rm"
9840
9841         #normal directory
9842         mkdir -p $DIR/$tdir || error "mkdir"
9843         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
9844         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
9845         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
9846                 error "$testfile error deleting user.author1"
9847         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
9848                 grep "user.$(basename $tdir)" &&
9849                 error "$tdir did not delete user.$(basename $tdir)"
9850         rmdir $DIR/$tdir || error "rmdir"
9851
9852         #striped directory
9853         test_mkdir $DIR/$tdir
9854         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
9855         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
9856         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
9857                 error "$testfile error deleting user.author1"
9858         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
9859                 grep "user.$(basename $tdir)" &&
9860                 error "$tdir did not delete user.$(basename $tdir)"
9861         rmdir $DIR/$tdir || error "rm striped dir"
9862 }
9863 run_test 102r "set EAs with empty values"
9864
9865 test_102s() {
9866         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
9867                 skip "MDS needs to be at least 2.11.52"
9868
9869         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
9870
9871         save_lustre_params client "llite.*.xattr_cache" > $save
9872
9873         for cache in 0 1; do
9874                 lctl set_param llite.*.xattr_cache=$cache
9875
9876                 rm -f $DIR/$tfile
9877                 touch $DIR/$tfile || error "touch"
9878                 for prefix in lustre security system trusted user; do
9879                         # Note getxattr() may fail with 'Operation not
9880                         # supported' or 'No such attribute' depending
9881                         # on prefix and cache.
9882                         getfattr -n $prefix.n102s $DIR/$tfile &&
9883                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
9884                 done
9885         done
9886
9887         restore_lustre_params < $save
9888 }
9889 run_test 102s "getting nonexistent xattrs should fail"
9890
9891 test_102t() {
9892         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
9893                 skip "MDS needs to be at least 2.11.52"
9894
9895         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
9896
9897         save_lustre_params client "llite.*.xattr_cache" > $save
9898
9899         for cache in 0 1; do
9900                 lctl set_param llite.*.xattr_cache=$cache
9901
9902                 for buf_size in 0 256; do
9903                         rm -f $DIR/$tfile
9904                         touch $DIR/$tfile || error "touch"
9905                         setfattr -n user.multiop $DIR/$tfile
9906                         $MULTIOP $DIR/$tfile oa$buf_size ||
9907                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
9908                 done
9909         done
9910
9911         restore_lustre_params < $save
9912 }
9913 run_test 102t "zero length xattr values handled correctly"
9914
9915 run_acl_subtest()
9916 {
9917     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
9918     return $?
9919 }
9920
9921 test_103a() {
9922         [ "$UID" != 0 ] && skip "must run as root"
9923         $GSS && skip_env "could not run under gss"
9924         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
9925                 skip_env "must have acl enabled"
9926         [ -z "$(which setfacl 2>/dev/null)" ] &&
9927                 skip_env "could not find setfacl"
9928         remote_mds_nodsh && skip "remote MDS with nodsh"
9929
9930         gpasswd -a daemon bin                           # LU-5641
9931         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
9932
9933         declare -a identity_old
9934
9935         for num in $(seq $MDSCOUNT); do
9936                 switch_identity $num true || identity_old[$num]=$?
9937         done
9938
9939         SAVE_UMASK=$(umask)
9940         umask 0022
9941         mkdir -p $DIR/$tdir
9942         cd $DIR/$tdir
9943
9944         echo "performing cp ..."
9945         run_acl_subtest cp || error "run_acl_subtest cp failed"
9946         echo "performing getfacl-noacl..."
9947         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
9948         echo "performing misc..."
9949         run_acl_subtest misc || error  "misc test failed"
9950         echo "performing permissions..."
9951         run_acl_subtest permissions || error "permissions failed"
9952         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
9953         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
9954                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
9955                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
9956         then
9957                 echo "performing permissions xattr..."
9958                 run_acl_subtest permissions_xattr ||
9959                         error "permissions_xattr failed"
9960         fi
9961         echo "performing setfacl..."
9962         run_acl_subtest setfacl || error  "setfacl test failed"
9963
9964         # inheritance test got from HP
9965         echo "performing inheritance..."
9966         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
9967         chmod +x make-tree || error "chmod +x failed"
9968         run_acl_subtest inheritance || error "inheritance test failed"
9969         rm -f make-tree
9970
9971         echo "LU-974 ignore umask when acl is enabled..."
9972         run_acl_subtest 974 || error "LU-974 umask test failed"
9973         if [ $MDSCOUNT -ge 2 ]; then
9974                 run_acl_subtest 974_remote ||
9975                         error "LU-974 umask test failed under remote dir"
9976         fi
9977
9978         echo "LU-2561 newly created file is same size as directory..."
9979         if [ "$mds1_FSTYPE" != "zfs" ]; then
9980                 run_acl_subtest 2561 || error "LU-2561 test failed"
9981         else
9982                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
9983         fi
9984
9985         run_acl_subtest 4924 || error "LU-4924 test failed"
9986
9987         cd $SAVE_PWD
9988         umask $SAVE_UMASK
9989
9990         for num in $(seq $MDSCOUNT); do
9991                 if [ "${identity_old[$num]}" = 1 ]; then
9992                         switch_identity $num false || identity_old[$num]=$?
9993                 fi
9994         done
9995 }
9996 run_test 103a "acl test"
9997
9998 test_103b() {
9999         declare -a pids
10000         local U
10001
10002         for U in {0..511}; do
10003                 {
10004                 local O=$(printf "%04o" $U)
10005
10006                 umask $(printf "%04o" $((511 ^ $O)))
10007                 $LFS setstripe -c 1 $DIR/$tfile.s$O
10008                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
10009
10010                 (( $S == ($O & 0666) )) ||
10011                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
10012
10013                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
10014                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
10015                 (( $S == ($O & 0666) )) ||
10016                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
10017
10018                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
10019                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
10020                 (( $S == ($O & 0666) )) ||
10021                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
10022                 rm -f $DIR/$tfile.[smp]$0
10023                 } &
10024                 local pid=$!
10025
10026                 # limit the concurrently running threads to 64. LU-11878
10027                 local idx=$((U % 64))
10028                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
10029                 pids[idx]=$pid
10030         done
10031         wait
10032 }
10033 run_test 103b "umask lfs setstripe"
10034
10035 test_103c() {
10036         mkdir -p $DIR/$tdir
10037         cp -rp $DIR/$tdir $DIR/$tdir.bak
10038
10039         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
10040                 error "$DIR/$tdir shouldn't contain default ACL"
10041         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
10042                 error "$DIR/$tdir.bak shouldn't contain default ACL"
10043         true
10044 }
10045 run_test 103c "'cp -rp' won't set empty acl"
10046
10047 test_104a() {
10048         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10049
10050         touch $DIR/$tfile
10051         lfs df || error "lfs df failed"
10052         lfs df -ih || error "lfs df -ih failed"
10053         lfs df -h $DIR || error "lfs df -h $DIR failed"
10054         lfs df -i $DIR || error "lfs df -i $DIR failed"
10055         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
10056         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
10057
10058         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
10059         lctl --device %$OSC deactivate
10060         lfs df || error "lfs df with deactivated OSC failed"
10061         lctl --device %$OSC activate
10062         # wait the osc back to normal
10063         wait_osc_import_ready client ost
10064
10065         lfs df || error "lfs df with reactivated OSC failed"
10066         rm -f $DIR/$tfile
10067 }
10068 run_test 104a "lfs df [-ih] [path] test ========================="
10069
10070 test_104b() {
10071         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10072         [ $RUNAS_ID -eq $UID ] &&
10073                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10074
10075         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
10076                         grep "Permission denied" | wc -l)))
10077         if [ $denied_cnt -ne 0 ]; then
10078                 error "lfs check servers test failed"
10079         fi
10080 }
10081 run_test 104b "$RUNAS lfs check servers test ===================="
10082
10083 test_105a() {
10084         # doesn't work on 2.4 kernels
10085         touch $DIR/$tfile
10086         if $(flock_is_enabled); then
10087                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
10088         else
10089                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
10090         fi
10091         rm -f $DIR/$tfile
10092 }
10093 run_test 105a "flock when mounted without -o flock test ========"
10094
10095 test_105b() {
10096         touch $DIR/$tfile
10097         if $(flock_is_enabled); then
10098                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
10099         else
10100                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
10101         fi
10102         rm -f $DIR/$tfile
10103 }
10104 run_test 105b "fcntl when mounted without -o flock test ========"
10105
10106 test_105c() {
10107         touch $DIR/$tfile
10108         if $(flock_is_enabled); then
10109                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
10110         else
10111                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
10112         fi
10113         rm -f $DIR/$tfile
10114 }
10115 run_test 105c "lockf when mounted without -o flock test"
10116
10117 test_105d() { # bug 15924
10118         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10119
10120         test_mkdir $DIR/$tdir
10121         flock_is_enabled || skip_env "mount w/o flock enabled"
10122         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
10123         $LCTL set_param fail_loc=0x80000315
10124         flocks_test 2 $DIR/$tdir
10125 }
10126 run_test 105d "flock race (should not freeze) ========"
10127
10128 test_105e() { # bug 22660 && 22040
10129         flock_is_enabled || skip_env "mount w/o flock enabled"
10130
10131         touch $DIR/$tfile
10132         flocks_test 3 $DIR/$tfile
10133 }
10134 run_test 105e "Two conflicting flocks from same process"
10135
10136 test_106() { #bug 10921
10137         test_mkdir $DIR/$tdir
10138         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
10139         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
10140 }
10141 run_test 106 "attempt exec of dir followed by chown of that dir"
10142
10143 test_107() {
10144         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10145
10146         CDIR=`pwd`
10147         local file=core
10148
10149         cd $DIR
10150         rm -f $file
10151
10152         local save_pattern=$(sysctl -n kernel.core_pattern)
10153         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
10154         sysctl -w kernel.core_pattern=$file
10155         sysctl -w kernel.core_uses_pid=0
10156
10157         ulimit -c unlimited
10158         sleep 60 &
10159         SLEEPPID=$!
10160
10161         sleep 1
10162
10163         kill -s 11 $SLEEPPID
10164         wait $SLEEPPID
10165         if [ -e $file ]; then
10166                 size=`stat -c%s $file`
10167                 [ $size -eq 0 ] && error "Fail to create core file $file"
10168         else
10169                 error "Fail to create core file $file"
10170         fi
10171         rm -f $file
10172         sysctl -w kernel.core_pattern=$save_pattern
10173         sysctl -w kernel.core_uses_pid=$save_uses_pid
10174         cd $CDIR
10175 }
10176 run_test 107 "Coredump on SIG"
10177
10178 test_110() {
10179         test_mkdir $DIR/$tdir
10180         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
10181         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
10182                 error "mkdir with 256 char should fail, but did not"
10183         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
10184                 error "create with 255 char failed"
10185         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
10186                 error "create with 256 char should fail, but did not"
10187
10188         ls -l $DIR/$tdir
10189         rm -rf $DIR/$tdir
10190 }
10191 run_test 110 "filename length checking"
10192
10193 #
10194 # Purpose: To verify dynamic thread (OSS) creation.
10195 #
10196 test_115() {
10197         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10198         remote_ost_nodsh && skip "remote OST with nodsh"
10199
10200         # Lustre does not stop service threads once they are started.
10201         # Reset number of running threads to default.
10202         stopall
10203         setupall
10204
10205         local OSTIO_pre
10206         local save_params="$TMP/sanity-$TESTNAME.parameters"
10207
10208         # Get ll_ost_io count before I/O
10209         OSTIO_pre=$(do_facet ost1 \
10210                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
10211         # Exit if lustre is not running (ll_ost_io not running).
10212         [ -z "$OSTIO_pre" ] && error "no OSS threads"
10213
10214         echo "Starting with $OSTIO_pre threads"
10215         local thread_max=$((OSTIO_pre * 2))
10216         local rpc_in_flight=$((thread_max * 2))
10217         # Number of I/O Process proposed to be started.
10218         local nfiles
10219         local facets=$(get_facets OST)
10220
10221         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
10222         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
10223
10224         # Set in_flight to $rpc_in_flight
10225         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
10226                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
10227         nfiles=${rpc_in_flight}
10228         # Set ost thread_max to $thread_max
10229         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
10230
10231         # 5 Minutes should be sufficient for max number of OSS
10232         # threads(thread_max) to be created.
10233         local timeout=300
10234
10235         # Start I/O.
10236         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
10237         test_mkdir $DIR/$tdir
10238         for i in $(seq $nfiles); do
10239                 local file=$DIR/$tdir/${tfile}-$i
10240                 $LFS setstripe -c -1 -i 0 $file
10241                 ($WTL $file $timeout)&
10242         done
10243
10244         # I/O Started - Wait for thread_started to reach thread_max or report
10245         # error if thread_started is more than thread_max.
10246         echo "Waiting for thread_started to reach thread_max"
10247         local thread_started=0
10248         local end_time=$((SECONDS + timeout))
10249
10250         while [ $SECONDS -le $end_time ] ; do
10251                 echo -n "."
10252                 # Get ost i/o thread_started count.
10253                 thread_started=$(do_facet ost1 \
10254                         "$LCTL get_param \
10255                         ost.OSS.ost_io.threads_started | cut -d= -f2")
10256                 # Break out if thread_started is equal/greater than thread_max
10257                 if [[ $thread_started -ge $thread_max ]]; then
10258                         echo ll_ost_io thread_started $thread_started, \
10259                                 equal/greater than thread_max $thread_max
10260                         break
10261                 fi
10262                 sleep 1
10263         done
10264
10265         # Cleanup - We have the numbers, Kill i/o jobs if running.
10266         jobcount=($(jobs -p))
10267         for i in $(seq 0 $((${#jobcount[@]}-1)))
10268         do
10269                 kill -9 ${jobcount[$i]}
10270                 if [ $? -ne 0 ] ; then
10271                         echo Warning: \
10272                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
10273                 fi
10274         done
10275
10276         # Cleanup files left by WTL binary.
10277         for i in $(seq $nfiles); do
10278                 local file=$DIR/$tdir/${tfile}-$i
10279                 rm -rf $file
10280                 if [ $? -ne 0 ] ; then
10281                         echo "Warning: Failed to delete file $file"
10282                 fi
10283         done
10284
10285         restore_lustre_params <$save_params
10286         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
10287
10288         # Error out if no new thread has started or Thread started is greater
10289         # than thread max.
10290         if [[ $thread_started -le $OSTIO_pre ||
10291                         $thread_started -gt $thread_max ]]; then
10292                 error "ll_ost_io: thread_started $thread_started" \
10293                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
10294                       "No new thread started or thread started greater " \
10295                       "than thread_max."
10296         fi
10297 }
10298 run_test 115 "verify dynamic thread creation===================="
10299
10300 free_min_max () {
10301         wait_delete_completed
10302         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
10303         echo "OST kbytes available: ${AVAIL[@]}"
10304         MAXV=${AVAIL[0]}
10305         MAXI=0
10306         MINV=${AVAIL[0]}
10307         MINI=0
10308         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
10309                 #echo OST $i: ${AVAIL[i]}kb
10310                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
10311                         MAXV=${AVAIL[i]}
10312                         MAXI=$i
10313                 fi
10314                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
10315                         MINV=${AVAIL[i]}
10316                         MINI=$i
10317                 fi
10318         done
10319         echo "Min free space: OST $MINI: $MINV"
10320         echo "Max free space: OST $MAXI: $MAXV"
10321 }
10322
10323 test_116a() { # was previously test_116()
10324         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10325         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10326         remote_mds_nodsh && skip "remote MDS with nodsh"
10327
10328         echo -n "Free space priority "
10329         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
10330                 head -n1
10331         declare -a AVAIL
10332         free_min_max
10333
10334         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
10335         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
10336         trap simple_cleanup_common EXIT
10337
10338         # Check if we need to generate uneven OSTs
10339         test_mkdir -p $DIR/$tdir/OST${MINI}
10340         local FILL=$((MINV / 4))
10341         local DIFF=$((MAXV - MINV))
10342         local DIFF2=$((DIFF * 100 / MINV))
10343
10344         local threshold=$(do_facet $SINGLEMDS \
10345                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
10346         threshold=${threshold%%%}
10347         echo -n "Check for uneven OSTs: "
10348         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
10349
10350         if [[ $DIFF2 -gt $threshold ]]; then
10351                 echo "ok"
10352                 echo "Don't need to fill OST$MINI"
10353         else
10354                 # generate uneven OSTs. Write 2% over the QOS threshold value
10355                 echo "no"
10356                 DIFF=$((threshold - DIFF2 + 2))
10357                 DIFF2=$((MINV * DIFF / 100))
10358                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
10359                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
10360                         error "setstripe failed"
10361                 DIFF=$((DIFF2 / 2048))
10362                 i=0
10363                 while [ $i -lt $DIFF ]; do
10364                         i=$((i + 1))
10365                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
10366                                 bs=2M count=1 2>/dev/null
10367                         echo -n .
10368                 done
10369                 echo .
10370                 sync
10371                 sleep_maxage
10372                 free_min_max
10373         fi
10374
10375         DIFF=$((MAXV - MINV))
10376         DIFF2=$((DIFF * 100 / MINV))
10377         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
10378         if [ $DIFF2 -gt $threshold ]; then
10379                 echo "ok"
10380         else
10381                 echo "failed - QOS mode won't be used"
10382                 simple_cleanup_common
10383                 skip "QOS imbalance criteria not met"
10384         fi
10385
10386         MINI1=$MINI
10387         MINV1=$MINV
10388         MAXI1=$MAXI
10389         MAXV1=$MAXV
10390
10391         # now fill using QOS
10392         $LFS setstripe -c 1 $DIR/$tdir
10393         FILL=$((FILL / 200))
10394         if [ $FILL -gt 600 ]; then
10395                 FILL=600
10396         fi
10397         echo "writing $FILL files to QOS-assigned OSTs"
10398         i=0
10399         while [ $i -lt $FILL ]; do
10400                 i=$((i + 1))
10401                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
10402                         count=1 2>/dev/null
10403                 echo -n .
10404         done
10405         echo "wrote $i 200k files"
10406         sync
10407         sleep_maxage
10408
10409         echo "Note: free space may not be updated, so measurements might be off"
10410         free_min_max
10411         DIFF2=$((MAXV - MINV))
10412         echo "free space delta: orig $DIFF final $DIFF2"
10413         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
10414         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
10415         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
10416         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
10417         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
10418         if [[ $DIFF -gt 0 ]]; then
10419                 FILL=$((DIFF2 * 100 / DIFF - 100))
10420                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
10421         fi
10422
10423         # Figure out which files were written where
10424         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10425                awk '/'$MINI1': / {print $2; exit}')
10426         echo $UUID
10427         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10428         echo "$MINC files created on smaller OST $MINI1"
10429         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10430                awk '/'$MAXI1': / {print $2; exit}')
10431         echo $UUID
10432         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10433         echo "$MAXC files created on larger OST $MAXI1"
10434         if [[ $MINC -gt 0 ]]; then
10435                 FILL=$((MAXC * 100 / MINC - 100))
10436                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
10437         fi
10438         [[ $MAXC -gt $MINC ]] ||
10439                 error_ignore LU-9 "stripe QOS didn't balance free space"
10440         simple_cleanup_common
10441 }
10442 run_test 116a "stripe QOS: free space balance ==================="
10443
10444 test_116b() { # LU-2093
10445         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10446         remote_mds_nodsh && skip "remote MDS with nodsh"
10447
10448 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
10449         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
10450                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
10451         [ -z "$old_rr" ] && skip "no QOS"
10452         do_facet $SINGLEMDS lctl set_param \
10453                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
10454         mkdir -p $DIR/$tdir
10455         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
10456         createmany -o $DIR/$tdir/f- 20 || error "can't create"
10457         do_facet $SINGLEMDS lctl set_param fail_loc=0
10458         rm -rf $DIR/$tdir
10459         do_facet $SINGLEMDS lctl set_param \
10460                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
10461 }
10462 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
10463
10464 test_117() # bug 10891
10465 {
10466         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10467
10468         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
10469         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
10470         lctl set_param fail_loc=0x21e
10471         > $DIR/$tfile || error "truncate failed"
10472         lctl set_param fail_loc=0
10473         echo "Truncate succeeded."
10474         rm -f $DIR/$tfile
10475 }
10476 run_test 117 "verify osd extend =========="
10477
10478 NO_SLOW_RESENDCOUNT=4
10479 export OLD_RESENDCOUNT=""
10480 set_resend_count () {
10481         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
10482         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
10483         lctl set_param -n $PROC_RESENDCOUNT $1
10484         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
10485 }
10486
10487 # for reduce test_118* time (b=14842)
10488 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
10489
10490 # Reset async IO behavior after error case
10491 reset_async() {
10492         FILE=$DIR/reset_async
10493
10494         # Ensure all OSCs are cleared
10495         $LFS setstripe -c -1 $FILE
10496         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
10497         sync
10498         rm $FILE
10499 }
10500
10501 test_118a() #bug 11710
10502 {
10503         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10504
10505         reset_async
10506
10507         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10508         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10509         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10510
10511         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10512                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10513                 return 1;
10514         fi
10515         rm -f $DIR/$tfile
10516 }
10517 run_test 118a "verify O_SYNC works =========="
10518
10519 test_118b()
10520 {
10521         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10522         remote_ost_nodsh && skip "remote OST with nodsh"
10523
10524         reset_async
10525
10526         #define OBD_FAIL_SRV_ENOENT 0x217
10527         set_nodes_failloc "$(osts_nodes)" 0x217
10528         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10529         RC=$?
10530         set_nodes_failloc "$(osts_nodes)" 0
10531         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10532         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10533                     grep -c writeback)
10534
10535         if [[ $RC -eq 0 ]]; then
10536                 error "Must return error due to dropped pages, rc=$RC"
10537                 return 1;
10538         fi
10539
10540         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10541                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10542                 return 1;
10543         fi
10544
10545         echo "Dirty pages not leaked on ENOENT"
10546
10547         # Due to the above error the OSC will issue all RPCs syncronously
10548         # until a subsequent RPC completes successfully without error.
10549         $MULTIOP $DIR/$tfile Ow4096yc
10550         rm -f $DIR/$tfile
10551
10552         return 0
10553 }
10554 run_test 118b "Reclaim dirty pages on fatal error =========="
10555
10556 test_118c()
10557 {
10558         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10559
10560         # for 118c, restore the original resend count, LU-1940
10561         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
10562                                 set_resend_count $OLD_RESENDCOUNT
10563         remote_ost_nodsh && skip "remote OST with nodsh"
10564
10565         reset_async
10566
10567         #define OBD_FAIL_OST_EROFS               0x216
10568         set_nodes_failloc "$(osts_nodes)" 0x216
10569
10570         # multiop should block due to fsync until pages are written
10571         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10572         MULTIPID=$!
10573         sleep 1
10574
10575         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
10576                 error "Multiop failed to block on fsync, pid=$MULTIPID"
10577         fi
10578
10579         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10580                     grep -c writeback)
10581         if [[ $WRITEBACK -eq 0 ]]; then
10582                 error "No page in writeback, writeback=$WRITEBACK"
10583         fi
10584
10585         set_nodes_failloc "$(osts_nodes)" 0
10586         wait $MULTIPID
10587         RC=$?
10588         if [[ $RC -ne 0 ]]; then
10589                 error "Multiop fsync failed, rc=$RC"
10590         fi
10591
10592         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10593         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10594                     grep -c writeback)
10595         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10596                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10597         fi
10598
10599         rm -f $DIR/$tfile
10600         echo "Dirty pages flushed via fsync on EROFS"
10601         return 0
10602 }
10603 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
10604
10605 # continue to use small resend count to reduce test_118* time (b=14842)
10606 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
10607
10608 test_118d()
10609 {
10610         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10611         remote_ost_nodsh && skip "remote OST with nodsh"
10612
10613         reset_async
10614
10615         #define OBD_FAIL_OST_BRW_PAUSE_BULK
10616         set_nodes_failloc "$(osts_nodes)" 0x214
10617         # multiop should block due to fsync until pages are written
10618         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10619         MULTIPID=$!
10620         sleep 1
10621
10622         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
10623                 error "Multiop failed to block on fsync, pid=$MULTIPID"
10624         fi
10625
10626         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10627                     grep -c writeback)
10628         if [[ $WRITEBACK -eq 0 ]]; then
10629                 error "No page in writeback, writeback=$WRITEBACK"
10630         fi
10631
10632         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
10633         set_nodes_failloc "$(osts_nodes)" 0
10634
10635         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10636         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10637                     grep -c writeback)
10638         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10639                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10640         fi
10641
10642         rm -f $DIR/$tfile
10643         echo "Dirty pages gaurenteed flushed via fsync"
10644         return 0
10645 }
10646 run_test 118d "Fsync validation inject a delay of the bulk =========="
10647
10648 test_118f() {
10649         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10650
10651         reset_async
10652
10653         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
10654         lctl set_param fail_loc=0x8000040a
10655
10656         # Should simulate EINVAL error which is fatal
10657         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10658         RC=$?
10659         if [[ $RC -eq 0 ]]; then
10660                 error "Must return error due to dropped pages, rc=$RC"
10661         fi
10662
10663         lctl set_param fail_loc=0x0
10664
10665         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10666         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10667         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10668                     grep -c writeback)
10669         if [[ $LOCKED -ne 0 ]]; then
10670                 error "Locked pages remain in cache, locked=$LOCKED"
10671         fi
10672
10673         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10674                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10675         fi
10676
10677         rm -f $DIR/$tfile
10678         echo "No pages locked after fsync"
10679
10680         reset_async
10681         return 0
10682 }
10683 run_test 118f "Simulate unrecoverable OSC side error =========="
10684
10685 test_118g() {
10686         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10687
10688         reset_async
10689
10690         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
10691         lctl set_param fail_loc=0x406
10692
10693         # simulate local -ENOMEM
10694         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10695         RC=$?
10696
10697         lctl set_param fail_loc=0
10698         if [[ $RC -eq 0 ]]; then
10699                 error "Must return error due to dropped pages, rc=$RC"
10700         fi
10701
10702         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10703         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10704         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10705                         grep -c writeback)
10706         if [[ $LOCKED -ne 0 ]]; then
10707                 error "Locked pages remain in cache, locked=$LOCKED"
10708         fi
10709
10710         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10711                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10712         fi
10713
10714         rm -f $DIR/$tfile
10715         echo "No pages locked after fsync"
10716
10717         reset_async
10718         return 0
10719 }
10720 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
10721
10722 test_118h() {
10723         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10724         remote_ost_nodsh && skip "remote OST with nodsh"
10725
10726         reset_async
10727
10728         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
10729         set_nodes_failloc "$(osts_nodes)" 0x20e
10730         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
10731         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10732         RC=$?
10733
10734         set_nodes_failloc "$(osts_nodes)" 0
10735         if [[ $RC -eq 0 ]]; then
10736                 error "Must return error due to dropped pages, rc=$RC"
10737         fi
10738
10739         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10740         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10741         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10742                     grep -c writeback)
10743         if [[ $LOCKED -ne 0 ]]; then
10744                 error "Locked pages remain in cache, locked=$LOCKED"
10745         fi
10746
10747         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10748                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10749         fi
10750
10751         rm -f $DIR/$tfile
10752         echo "No pages locked after fsync"
10753
10754         return 0
10755 }
10756 run_test 118h "Verify timeout in handling recoverables errors  =========="
10757
10758 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
10759
10760 test_118i() {
10761         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10762         remote_ost_nodsh && skip "remote OST with nodsh"
10763
10764         reset_async
10765
10766         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
10767         set_nodes_failloc "$(osts_nodes)" 0x20e
10768
10769         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
10770         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10771         PID=$!
10772         sleep 5
10773         set_nodes_failloc "$(osts_nodes)" 0
10774
10775         wait $PID
10776         RC=$?
10777         if [[ $RC -ne 0 ]]; then
10778                 error "got error, but should be not, rc=$RC"
10779         fi
10780
10781         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10782         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10783         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10784         if [[ $LOCKED -ne 0 ]]; then
10785                 error "Locked pages remain in cache, locked=$LOCKED"
10786         fi
10787
10788         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10789                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10790         fi
10791
10792         rm -f $DIR/$tfile
10793         echo "No pages locked after fsync"
10794
10795         return 0
10796 }
10797 run_test 118i "Fix error before timeout in recoverable error  =========="
10798
10799 [ "$SLOW" = "no" ] && set_resend_count 4
10800
10801 test_118j() {
10802         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10803         remote_ost_nodsh && skip "remote OST with nodsh"
10804
10805         reset_async
10806
10807         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
10808         set_nodes_failloc "$(osts_nodes)" 0x220
10809
10810         # return -EIO from OST
10811         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10812         RC=$?
10813         set_nodes_failloc "$(osts_nodes)" 0x0
10814         if [[ $RC -eq 0 ]]; then
10815                 error "Must return error due to dropped pages, rc=$RC"
10816         fi
10817
10818         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10819         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10820         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10821         if [[ $LOCKED -ne 0 ]]; then
10822                 error "Locked pages remain in cache, locked=$LOCKED"
10823         fi
10824
10825         # in recoverable error on OST we want resend and stay until it finished
10826         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10827                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10828         fi
10829
10830         rm -f $DIR/$tfile
10831         echo "No pages locked after fsync"
10832
10833         return 0
10834 }
10835 run_test 118j "Simulate unrecoverable OST side error =========="
10836
10837 test_118k()
10838 {
10839         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10840         remote_ost_nodsh && skip "remote OSTs with nodsh"
10841
10842         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
10843         set_nodes_failloc "$(osts_nodes)" 0x20e
10844         test_mkdir $DIR/$tdir
10845
10846         for ((i=0;i<10;i++)); do
10847                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
10848                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
10849                 SLEEPPID=$!
10850                 sleep 0.500s
10851                 kill $SLEEPPID
10852                 wait $SLEEPPID
10853         done
10854
10855         set_nodes_failloc "$(osts_nodes)" 0
10856         rm -rf $DIR/$tdir
10857 }
10858 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
10859
10860 test_118l() # LU-646
10861 {
10862         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10863
10864         test_mkdir $DIR/$tdir
10865         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
10866         rm -rf $DIR/$tdir
10867 }
10868 run_test 118l "fsync dir"
10869
10870 test_118m() # LU-3066
10871 {
10872         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10873
10874         test_mkdir $DIR/$tdir
10875         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
10876         rm -rf $DIR/$tdir
10877 }
10878 run_test 118m "fdatasync dir ========="
10879
10880 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
10881
10882 test_118n()
10883 {
10884         local begin
10885         local end
10886
10887         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10888         remote_ost_nodsh && skip "remote OSTs with nodsh"
10889
10890         # Sleep to avoid a cached response.
10891         #define OBD_STATFS_CACHE_SECONDS 1
10892         sleep 2
10893
10894         # Inject a 10 second delay in the OST_STATFS handler.
10895         #define OBD_FAIL_OST_STATFS_DELAY 0x242
10896         set_nodes_failloc "$(osts_nodes)" 0x242
10897
10898         begin=$SECONDS
10899         stat --file-system $MOUNT > /dev/null
10900         end=$SECONDS
10901
10902         set_nodes_failloc "$(osts_nodes)" 0
10903
10904         if ((end - begin > 20)); then
10905             error "statfs took $((end - begin)) seconds, expected 10"
10906         fi
10907 }
10908 run_test 118n "statfs() sends OST_STATFS requests in parallel"
10909
10910 test_119a() # bug 11737
10911 {
10912         BSIZE=$((512 * 1024))
10913         directio write $DIR/$tfile 0 1 $BSIZE
10914         # We ask to read two blocks, which is more than a file size.
10915         # directio will indicate an error when requested and actual
10916         # sizes aren't equeal (a normal situation in this case) and
10917         # print actual read amount.
10918         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
10919         if [ "$NOB" != "$BSIZE" ]; then
10920                 error "read $NOB bytes instead of $BSIZE"
10921         fi
10922         rm -f $DIR/$tfile
10923 }
10924 run_test 119a "Short directIO read must return actual read amount"
10925
10926 test_119b() # bug 11737
10927 {
10928         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10929
10930         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
10931         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
10932         sync
10933         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
10934                 error "direct read failed"
10935         rm -f $DIR/$tfile
10936 }
10937 run_test 119b "Sparse directIO read must return actual read amount"
10938
10939 test_119c() # bug 13099
10940 {
10941         BSIZE=1048576
10942         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
10943         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
10944         rm -f $DIR/$tfile
10945 }
10946 run_test 119c "Testing for direct read hitting hole"
10947
10948 test_119d() # bug 15950
10949 {
10950         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10951
10952         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
10953         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
10954         BSIZE=1048576
10955         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
10956         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
10957         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
10958         lctl set_param fail_loc=0x40d
10959         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
10960         pid_dio=$!
10961         sleep 1
10962         cat $DIR/$tfile > /dev/null &
10963         lctl set_param fail_loc=0
10964         pid_reads=$!
10965         wait $pid_dio
10966         log "the DIO writes have completed, now wait for the reads (should not block very long)"
10967         sleep 2
10968         [ -n "`ps h -p $pid_reads -o comm`" ] && \
10969         error "the read rpcs have not completed in 2s"
10970         rm -f $DIR/$tfile
10971         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
10972 }
10973 run_test 119d "The DIO path should try to send a new rpc once one is completed"
10974
10975 test_120a() {
10976         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10977         remote_mds_nodsh && skip "remote MDS with nodsh"
10978         test_mkdir -i0 -c1 $DIR/$tdir
10979         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10980                 skip_env "no early lock cancel on server"
10981
10982         lru_resize_disable mdc
10983         lru_resize_disable osc
10984         cancel_lru_locks mdc
10985         # asynchronous object destroy at MDT could cause bl ast to client
10986         cancel_lru_locks osc
10987
10988         stat $DIR/$tdir > /dev/null
10989         can1=$(do_facet mds1 \
10990                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10991                awk '/ldlm_cancel/ {print $2}')
10992         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10993                awk '/ldlm_bl_callback/ {print $2}')
10994         test_mkdir -i0 -c1 $DIR/$tdir/d1
10995         can2=$(do_facet mds1 \
10996                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10997                awk '/ldlm_cancel/ {print $2}')
10998         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10999                awk '/ldlm_bl_callback/ {print $2}')
11000         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11001         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11002         lru_resize_enable mdc
11003         lru_resize_enable osc
11004 }
11005 run_test 120a "Early Lock Cancel: mkdir test"
11006
11007 test_120b() {
11008         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11009         remote_mds_nodsh && skip "remote MDS with nodsh"
11010         test_mkdir $DIR/$tdir
11011         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11012                 skip_env "no early lock cancel on server"
11013
11014         lru_resize_disable mdc
11015         lru_resize_disable osc
11016         cancel_lru_locks mdc
11017         stat $DIR/$tdir > /dev/null
11018         can1=$(do_facet $SINGLEMDS \
11019                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11020                awk '/ldlm_cancel/ {print $2}')
11021         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11022                awk '/ldlm_bl_callback/ {print $2}')
11023         touch $DIR/$tdir/f1
11024         can2=$(do_facet $SINGLEMDS \
11025                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11026                awk '/ldlm_cancel/ {print $2}')
11027         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11028                awk '/ldlm_bl_callback/ {print $2}')
11029         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11030         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11031         lru_resize_enable mdc
11032         lru_resize_enable osc
11033 }
11034 run_test 120b "Early Lock Cancel: create test"
11035
11036 test_120c() {
11037         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11038         remote_mds_nodsh && skip "remote MDS with nodsh"
11039         test_mkdir -i0 -c1 $DIR/$tdir
11040         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11041                 skip "no early lock cancel on server"
11042
11043         lru_resize_disable mdc
11044         lru_resize_disable osc
11045         test_mkdir -i0 -c1 $DIR/$tdir/d1
11046         test_mkdir -i0 -c1 $DIR/$tdir/d2
11047         touch $DIR/$tdir/d1/f1
11048         cancel_lru_locks mdc
11049         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
11050         can1=$(do_facet mds1 \
11051                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11052                awk '/ldlm_cancel/ {print $2}')
11053         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11054                awk '/ldlm_bl_callback/ {print $2}')
11055         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11056         can2=$(do_facet mds1 \
11057                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11058                awk '/ldlm_cancel/ {print $2}')
11059         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11060                awk '/ldlm_bl_callback/ {print $2}')
11061         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11062         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11063         lru_resize_enable mdc
11064         lru_resize_enable osc
11065 }
11066 run_test 120c "Early Lock Cancel: link test"
11067
11068 test_120d() {
11069         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11070         remote_mds_nodsh && skip "remote MDS with nodsh"
11071         test_mkdir -i0 -c1 $DIR/$tdir
11072         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11073                 skip_env "no early lock cancel on server"
11074
11075         lru_resize_disable mdc
11076         lru_resize_disable osc
11077         touch $DIR/$tdir
11078         cancel_lru_locks mdc
11079         stat $DIR/$tdir > /dev/null
11080         can1=$(do_facet mds1 \
11081                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11082                awk '/ldlm_cancel/ {print $2}')
11083         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11084                awk '/ldlm_bl_callback/ {print $2}')
11085         chmod a+x $DIR/$tdir
11086         can2=$(do_facet mds1 \
11087                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11088                awk '/ldlm_cancel/ {print $2}')
11089         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11090                awk '/ldlm_bl_callback/ {print $2}')
11091         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11092         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11093         lru_resize_enable mdc
11094         lru_resize_enable osc
11095 }
11096 run_test 120d "Early Lock Cancel: setattr test"
11097
11098 test_120e() {
11099         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11100         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11101                 skip_env "no early lock cancel on server"
11102         remote_mds_nodsh && skip "remote MDS with nodsh"
11103
11104         local dlmtrace_set=false
11105
11106         test_mkdir -i0 -c1 $DIR/$tdir
11107         lru_resize_disable mdc
11108         lru_resize_disable osc
11109         ! $LCTL get_param debug | grep -q dlmtrace &&
11110                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
11111         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
11112         cancel_lru_locks mdc
11113         cancel_lru_locks osc
11114         dd if=$DIR/$tdir/f1 of=/dev/null
11115         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
11116         # XXX client can not do early lock cancel of OST lock
11117         # during unlink (LU-4206), so cancel osc lock now.
11118         sleep 2
11119         cancel_lru_locks osc
11120         can1=$(do_facet mds1 \
11121                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11122                awk '/ldlm_cancel/ {print $2}')
11123         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11124                awk '/ldlm_bl_callback/ {print $2}')
11125         unlink $DIR/$tdir/f1
11126         sleep 5
11127         can2=$(do_facet mds1 \
11128                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11129                awk '/ldlm_cancel/ {print $2}')
11130         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11131                awk '/ldlm_bl_callback/ {print $2}')
11132         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
11133                 $LCTL dk $TMP/cancel.debug.txt
11134         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
11135                 $LCTL dk $TMP/blocking.debug.txt
11136         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
11137         lru_resize_enable mdc
11138         lru_resize_enable osc
11139 }
11140 run_test 120e "Early Lock Cancel: unlink test"
11141
11142 test_120f() {
11143         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11144         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11145                 skip_env "no early lock cancel on server"
11146         remote_mds_nodsh && skip "remote MDS with nodsh"
11147
11148         test_mkdir -i0 -c1 $DIR/$tdir
11149         lru_resize_disable mdc
11150         lru_resize_disable osc
11151         test_mkdir -i0 -c1 $DIR/$tdir/d1
11152         test_mkdir -i0 -c1 $DIR/$tdir/d2
11153         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
11154         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
11155         cancel_lru_locks mdc
11156         cancel_lru_locks osc
11157         dd if=$DIR/$tdir/d1/f1 of=/dev/null
11158         dd if=$DIR/$tdir/d2/f2 of=/dev/null
11159         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
11160         # XXX client can not do early lock cancel of OST lock
11161         # during rename (LU-4206), so cancel osc lock now.
11162         sleep 2
11163         cancel_lru_locks osc
11164         can1=$(do_facet mds1 \
11165                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11166                awk '/ldlm_cancel/ {print $2}')
11167         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11168                awk '/ldlm_bl_callback/ {print $2}')
11169         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11170         sleep 5
11171         can2=$(do_facet mds1 \
11172                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11173                awk '/ldlm_cancel/ {print $2}')
11174         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11175                awk '/ldlm_bl_callback/ {print $2}')
11176         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11177         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11178         lru_resize_enable mdc
11179         lru_resize_enable osc
11180 }
11181 run_test 120f "Early Lock Cancel: rename test"
11182
11183 test_120g() {
11184         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11185         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11186                 skip_env "no early lock cancel on server"
11187         remote_mds_nodsh && skip "remote MDS with nodsh"
11188
11189         lru_resize_disable mdc
11190         lru_resize_disable osc
11191         count=10000
11192         echo create $count files
11193         test_mkdir $DIR/$tdir
11194         cancel_lru_locks mdc
11195         cancel_lru_locks osc
11196         t0=$(date +%s)
11197
11198         can0=$(do_facet $SINGLEMDS \
11199                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11200                awk '/ldlm_cancel/ {print $2}')
11201         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11202                awk '/ldlm_bl_callback/ {print $2}')
11203         createmany -o $DIR/$tdir/f $count
11204         sync
11205         can1=$(do_facet $SINGLEMDS \
11206                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11207                awk '/ldlm_cancel/ {print $2}')
11208         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11209                awk '/ldlm_bl_callback/ {print $2}')
11210         t1=$(date +%s)
11211         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
11212         echo rm $count files
11213         rm -r $DIR/$tdir
11214         sync
11215         can2=$(do_facet $SINGLEMDS \
11216                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11217                awk '/ldlm_cancel/ {print $2}')
11218         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11219                awk '/ldlm_bl_callback/ {print $2}')
11220         t2=$(date +%s)
11221         echo total: $count removes in $((t2-t1))
11222         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
11223         sleep 2
11224         # wait for commitment of removal
11225         lru_resize_enable mdc
11226         lru_resize_enable osc
11227 }
11228 run_test 120g "Early Lock Cancel: performance test"
11229
11230 test_121() { #bug #10589
11231         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11232
11233         rm -rf $DIR/$tfile
11234         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
11235 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
11236         lctl set_param fail_loc=0x310
11237         cancel_lru_locks osc > /dev/null
11238         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
11239         lctl set_param fail_loc=0
11240         [[ $reads -eq $writes ]] ||
11241                 error "read $reads blocks, must be $writes blocks"
11242 }
11243 run_test 121 "read cancel race ========="
11244
11245 test_123a() { # was test 123, statahead(bug 11401)
11246         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11247
11248         SLOWOK=0
11249         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
11250                 log "testing UP system. Performance may be lower than expected."
11251                 SLOWOK=1
11252         fi
11253
11254         rm -rf $DIR/$tdir
11255         test_mkdir $DIR/$tdir
11256         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
11257         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
11258         MULT=10
11259         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
11260                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
11261
11262                 max=`lctl get_param -n llite.*.statahead_max | head -n 1`
11263                 lctl set_param -n llite.*.statahead_max 0
11264                 lctl get_param llite.*.statahead_max
11265                 cancel_lru_locks mdc
11266                 cancel_lru_locks osc
11267                 stime=`date +%s`
11268                 time ls -l $DIR/$tdir | wc -l
11269                 etime=`date +%s`
11270                 delta=$((etime - stime))
11271                 log "ls $i files without statahead: $delta sec"
11272                 lctl set_param llite.*.statahead_max=$max
11273
11274                 swrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
11275                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
11276                 cancel_lru_locks mdc
11277                 cancel_lru_locks osc
11278                 stime=`date +%s`
11279                 time ls -l $DIR/$tdir | wc -l
11280                 etime=`date +%s`
11281                 delta_sa=$((etime - stime))
11282                 log "ls $i files with statahead: $delta_sa sec"
11283                 lctl get_param -n llite.*.statahead_stats
11284                 ewrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
11285
11286                 [[ $swrong -lt $ewrong ]] &&
11287                         log "statahead was stopped, maybe too many locks held!"
11288                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
11289
11290                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
11291                     max=`lctl get_param -n llite.*.statahead_max | head -n 1`
11292                     lctl set_param -n llite.*.statahead_max 0
11293                     lctl get_param llite.*.statahead_max
11294                     cancel_lru_locks mdc
11295                     cancel_lru_locks osc
11296                     stime=`date +%s`
11297                     time ls -l $DIR/$tdir | wc -l
11298                     etime=`date +%s`
11299                     delta=$((etime - stime))
11300                     log "ls $i files again without statahead: $delta sec"
11301                     lctl set_param llite.*.statahead_max=$max
11302                     if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
11303                         if [  $SLOWOK -eq 0 ]; then
11304                                 error "ls $i files is slower with statahead!"
11305                         else
11306                                 log "ls $i files is slower with statahead!"
11307                         fi
11308                         break
11309                     fi
11310                 fi
11311
11312                 [ $delta -gt 20 ] && break
11313                 [ $delta -gt 8 ] && MULT=$((50 / delta))
11314                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
11315         done
11316         log "ls done"
11317
11318         stime=`date +%s`
11319         rm -r $DIR/$tdir
11320         sync
11321         etime=`date +%s`
11322         delta=$((etime - stime))
11323         log "rm -r $DIR/$tdir/: $delta seconds"
11324         log "rm done"
11325         lctl get_param -n llite.*.statahead_stats
11326 }
11327 run_test 123a "verify statahead work"
11328
11329 test_123b () { # statahead(bug 15027)
11330         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11331
11332         test_mkdir $DIR/$tdir
11333         createmany -o $DIR/$tdir/$tfile-%d 1000
11334
11335         cancel_lru_locks mdc
11336         cancel_lru_locks osc
11337
11338 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
11339         lctl set_param fail_loc=0x80000803
11340         ls -lR $DIR/$tdir > /dev/null
11341         log "ls done"
11342         lctl set_param fail_loc=0x0
11343         lctl get_param -n llite.*.statahead_stats
11344         rm -r $DIR/$tdir
11345         sync
11346
11347 }
11348 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
11349
11350 test_123c() {
11351         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
11352
11353         test_mkdir -i 0 -c 1 $DIR/$tdir.0
11354         test_mkdir -i 1 -c 1 $DIR/$tdir.1
11355         touch $DIR/$tdir.1/{1..3}
11356         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
11357
11358         remount_client $MOUNT
11359
11360         $MULTIOP $DIR/$tdir.0 Q
11361
11362         # let statahead to complete
11363         ls -l $DIR/$tdir.0 > /dev/null
11364
11365         testid=$(echo $TESTNAME | tr '_' ' ')
11366         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
11367                 error "statahead warning" || true
11368 }
11369 run_test 123c "Can not initialize inode warning on DNE statahead"
11370
11371 test_124a() {
11372         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11373         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11374                 skip_env "no lru resize on server"
11375
11376         local NR=2000
11377
11378         test_mkdir $DIR/$tdir
11379
11380         log "create $NR files at $DIR/$tdir"
11381         createmany -o $DIR/$tdir/f $NR ||
11382                 error "failed to create $NR files in $DIR/$tdir"
11383
11384         cancel_lru_locks mdc
11385         ls -l $DIR/$tdir > /dev/null
11386
11387         local NSDIR=""
11388         local LRU_SIZE=0
11389         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
11390                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
11391                 LRU_SIZE=$($LCTL get_param -n $PARAM)
11392                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
11393                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
11394                         log "NSDIR=$NSDIR"
11395                         log "NS=$(basename $NSDIR)"
11396                         break
11397                 fi
11398         done
11399
11400         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
11401                 skip "Not enough cached locks created!"
11402         fi
11403         log "LRU=$LRU_SIZE"
11404
11405         local SLEEP=30
11406
11407         # We know that lru resize allows one client to hold $LIMIT locks
11408         # for 10h. After that locks begin to be killed by client.
11409         local MAX_HRS=10
11410         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
11411         log "LIMIT=$LIMIT"
11412         if [ $LIMIT -lt $LRU_SIZE ]; then
11413                 skip "Limit is too small $LIMIT"
11414         fi
11415
11416         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
11417         # killing locks. Some time was spent for creating locks. This means
11418         # that up to the moment of sleep finish we must have killed some of
11419         # them (10-100 locks). This depends on how fast ther were created.
11420         # Many of them were touched in almost the same moment and thus will
11421         # be killed in groups.
11422         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE))
11423
11424         # Use $LRU_SIZE_B here to take into account real number of locks
11425         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
11426         local LRU_SIZE_B=$LRU_SIZE
11427         log "LVF=$LVF"
11428         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
11429         log "OLD_LVF=$OLD_LVF"
11430         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
11431
11432         # Let's make sure that we really have some margin. Client checks
11433         # cached locks every 10 sec.
11434         SLEEP=$((SLEEP+20))
11435         log "Sleep ${SLEEP} sec"
11436         local SEC=0
11437         while ((SEC<$SLEEP)); do
11438                 echo -n "..."
11439                 sleep 5
11440                 SEC=$((SEC+5))
11441                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
11442                 echo -n "$LRU_SIZE"
11443         done
11444         echo ""
11445         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
11446         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
11447
11448         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
11449                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
11450                 unlinkmany $DIR/$tdir/f $NR
11451                 return
11452         }
11453
11454         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
11455         log "unlink $NR files at $DIR/$tdir"
11456         unlinkmany $DIR/$tdir/f $NR
11457 }
11458 run_test 124a "lru resize ======================================="
11459
11460 get_max_pool_limit()
11461 {
11462         local limit=$($LCTL get_param \
11463                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
11464         local max=0
11465         for l in $limit; do
11466                 if [[ $l -gt $max ]]; then
11467                         max=$l
11468                 fi
11469         done
11470         echo $max
11471 }
11472
11473 test_124b() {
11474         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11475         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11476                 skip_env "no lru resize on server"
11477
11478         LIMIT=$(get_max_pool_limit)
11479
11480         NR=$(($(default_lru_size)*20))
11481         if [[ $NR -gt $LIMIT ]]; then
11482                 log "Limit lock number by $LIMIT locks"
11483                 NR=$LIMIT
11484         fi
11485
11486         IFree=$(mdsrate_inodes_available)
11487         if [ $IFree -lt $NR ]; then
11488                 log "Limit lock number by $IFree inodes"
11489                 NR=$IFree
11490         fi
11491
11492         lru_resize_disable mdc
11493         test_mkdir -p $DIR/$tdir/disable_lru_resize
11494
11495         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
11496         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
11497         cancel_lru_locks mdc
11498         stime=`date +%s`
11499         PID=""
11500         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11501         PID="$PID $!"
11502         sleep 2
11503         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11504         PID="$PID $!"
11505         sleep 2
11506         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11507         PID="$PID $!"
11508         wait $PID
11509         etime=`date +%s`
11510         nolruresize_delta=$((etime-stime))
11511         log "ls -la time: $nolruresize_delta seconds"
11512         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
11513         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
11514
11515         lru_resize_enable mdc
11516         test_mkdir -p $DIR/$tdir/enable_lru_resize
11517
11518         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
11519         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
11520         cancel_lru_locks mdc
11521         stime=`date +%s`
11522         PID=""
11523         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11524         PID="$PID $!"
11525         sleep 2
11526         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11527         PID="$PID $!"
11528         sleep 2
11529         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11530         PID="$PID $!"
11531         wait $PID
11532         etime=`date +%s`
11533         lruresize_delta=$((etime-stime))
11534         log "ls -la time: $lruresize_delta seconds"
11535         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
11536
11537         if [ $lruresize_delta -gt $nolruresize_delta ]; then
11538                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
11539         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
11540                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
11541         else
11542                 log "lru resize performs the same with no lru resize"
11543         fi
11544         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
11545 }
11546 run_test 124b "lru resize (performance test) ======================="
11547
11548 test_124c() {
11549         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11550         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11551                 skip_env "no lru resize on server"
11552
11553         # cache ununsed locks on client
11554         local nr=100
11555         cancel_lru_locks mdc
11556         test_mkdir $DIR/$tdir
11557         createmany -o $DIR/$tdir/f $nr ||
11558                 error "failed to create $nr files in $DIR/$tdir"
11559         ls -l $DIR/$tdir > /dev/null
11560
11561         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
11562         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11563         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
11564         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
11565         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
11566
11567         # set lru_max_age to 1 sec
11568         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
11569         echo "sleep $((recalc_p * 2)) seconds..."
11570         sleep $((recalc_p * 2))
11571
11572         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
11573         # restore lru_max_age
11574         $LCTL set_param -n $nsdir.lru_max_age $max_age
11575         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
11576         unlinkmany $DIR/$tdir/f $nr
11577 }
11578 run_test 124c "LRUR cancel very aged locks"
11579
11580 test_124d() {
11581         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11582         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11583                 skip_env "no lru resize on server"
11584
11585         # cache ununsed locks on client
11586         local nr=100
11587
11588         lru_resize_disable mdc
11589         stack_trap "lru_resize_enable mdc" EXIT
11590
11591         cancel_lru_locks mdc
11592
11593         # asynchronous object destroy at MDT could cause bl ast to client
11594         test_mkdir $DIR/$tdir
11595         createmany -o $DIR/$tdir/f $nr ||
11596                 error "failed to create $nr files in $DIR/$tdir"
11597         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
11598
11599         ls -l $DIR/$tdir > /dev/null
11600
11601         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
11602         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11603         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
11604         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
11605
11606         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
11607
11608         # set lru_max_age to 1 sec
11609         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
11610         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
11611
11612         echo "sleep $((recalc_p * 2)) seconds..."
11613         sleep $((recalc_p * 2))
11614
11615         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
11616
11617         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
11618 }
11619 run_test 124d "cancel very aged locks if lru-resize diasbaled"
11620
11621 test_125() { # 13358
11622         $LCTL get_param -n llite.*.client_type | grep -q local ||
11623                 skip "must run as local client"
11624         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
11625                 skip_env "must have acl enabled"
11626         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
11627
11628         test_mkdir $DIR/$tdir
11629         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
11630         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
11631         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
11632 }
11633 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
11634
11635 test_126() { # bug 12829/13455
11636         $GSS && skip_env "must run as gss disabled"
11637         $LCTL get_param -n llite.*.client_type | grep -q local ||
11638                 skip "must run as local client"
11639         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
11640
11641         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
11642         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
11643         rm -f $DIR/$tfile
11644         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
11645 }
11646 run_test 126 "check that the fsgid provided by the client is taken into account"
11647
11648 test_127a() { # bug 15521
11649         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11650         local name count samp unit min max sum sumsq
11651
11652         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
11653         echo "stats before reset"
11654         $LCTL get_param osc.*.stats
11655         $LCTL set_param osc.*.stats=0
11656         local fsize=$((2048 * 1024))
11657
11658         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
11659         cancel_lru_locks osc
11660         dd if=$DIR/$tfile of=/dev/null bs=$fsize
11661
11662         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
11663         stack_trap "rm -f $TMP/$tfile.tmp"
11664         while read name count samp unit min max sum sumsq; do
11665                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
11666                 [ ! $min ] && error "Missing min value for $name proc entry"
11667                 eval $name=$count || error "Wrong proc format"
11668
11669                 case $name in
11670                 read_bytes|write_bytes)
11671                         [[ "$unit" =~ "bytes" ]] ||
11672                                 error "unit is not 'bytes': $unit"
11673                         (( $min >= 4096 )) || error "min is too small: $min"
11674                         (( $min <= $fsize )) || error "min is too big: $min"
11675                         (( $max >= 4096 )) || error "max is too small: $max"
11676                         (( $max <= $fsize )) || error "max is too big: $max"
11677                         (( $sum == $fsize )) || error "sum is wrong: $sum"
11678                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
11679                                 error "sumsquare is too small: $sumsq"
11680                         (( $sumsq <= $fsize * $fsize )) ||
11681                                 error "sumsquare is too big: $sumsq"
11682                         ;;
11683                 ost_read|ost_write)
11684                         [[ "$unit" =~ "usec" ]] ||
11685                                 error "unit is not 'usec': $unit"
11686                         ;;
11687                 *)      ;;
11688                 esac
11689         done < $DIR/$tfile.tmp
11690
11691         #check that we actually got some stats
11692         [ "$read_bytes" ] || error "Missing read_bytes stats"
11693         [ "$write_bytes" ] || error "Missing write_bytes stats"
11694         [ "$read_bytes" != 0 ] || error "no read done"
11695         [ "$write_bytes" != 0 ] || error "no write done"
11696 }
11697 run_test 127a "verify the client stats are sane"
11698
11699 test_127b() { # bug LU-333
11700         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11701         local name count samp unit min max sum sumsq
11702
11703         echo "stats before reset"
11704         $LCTL get_param llite.*.stats
11705         $LCTL set_param llite.*.stats=0
11706
11707         # perform 2 reads and writes so MAX is different from SUM.
11708         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
11709         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
11710         cancel_lru_locks osc
11711         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
11712         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
11713
11714         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
11715         stack_trap "rm -f $TMP/$tfile.tmp"
11716         while read name count samp unit min max sum sumsq; do
11717                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
11718                 eval $name=$count || error "Wrong proc format"
11719
11720                 case $name in
11721                 read_bytes|write_bytes)
11722                         [[ "$unit" =~ "bytes" ]] ||
11723                                 error "unit is not 'bytes': $unit"
11724                         (( $count == 2 )) || error "count is not 2: $count"
11725                         (( $min == $PAGE_SIZE )) ||
11726                                 error "min is not $PAGE_SIZE: $min"
11727                         (( $max == $PAGE_SIZE )) ||
11728                                 error "max is not $PAGE_SIZE: $max"
11729                         (( $sum == $PAGE_SIZE * 2 )) ||
11730                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
11731                         ;;
11732                 read|write)
11733                         [[ "$unit" =~ "usec" ]] ||
11734                                 error "unit is not 'usec': $unit"
11735                         ;;
11736                 *)      ;;
11737                 esac
11738         done < $TMP/$tfile.tmp
11739
11740         #check that we actually got some stats
11741         [ "$read_bytes" ] || error "Missing read_bytes stats"
11742         [ "$write_bytes" ] || error "Missing write_bytes stats"
11743         [ "$read_bytes" != 0 ] || error "no read done"
11744         [ "$write_bytes" != 0 ] || error "no write done"
11745 }
11746 run_test 127b "verify the llite client stats are sane"
11747
11748 test_127c() { # LU-12394
11749         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
11750         local size
11751         local bsize
11752         local reads
11753         local writes
11754         local count
11755
11756         $LCTL set_param llite.*.extents_stats=1
11757         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
11758
11759         # Use two stripes so there is enough space in default config
11760         $LFS setstripe -c 2 $DIR/$tfile
11761
11762         # Extent stats start at 0-4K and go in power of two buckets
11763         # LL_HIST_START = 12 --> 2^12 = 4K
11764         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
11765         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
11766         # small configs
11767         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
11768                 do
11769                 # Write and read, 2x each, second time at a non-zero offset
11770                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
11771                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
11772                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
11773                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
11774                 rm -f $DIR/$tfile
11775         done
11776
11777         $LCTL get_param llite.*.extents_stats
11778
11779         count=2
11780         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
11781                 do
11782                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
11783                                 grep -m 1 $bsize)
11784                 reads=$(echo $bucket | awk '{print $5}')
11785                 writes=$(echo $bucket | awk '{print $9}')
11786                 [ "$reads" -eq $count ] ||
11787                         error "$reads reads in < $bsize bucket, expect $count"
11788                 [ "$writes" -eq $count ] ||
11789                         error "$writes writes in < $bsize bucket, expect $count"
11790         done
11791
11792         # Test mmap write and read
11793         $LCTL set_param llite.*.extents_stats=c
11794         size=512
11795         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
11796         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
11797         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
11798
11799         $LCTL get_param llite.*.extents_stats
11800
11801         count=$(((size*1024) / PAGE_SIZE))
11802
11803         bsize=$((2 * PAGE_SIZE / 1024))K
11804
11805         bucket=$($LCTL get_param -n llite.*.extents_stats |
11806                         grep -m 1 $bsize)
11807         reads=$(echo $bucket | awk '{print $5}')
11808         writes=$(echo $bucket | awk '{print $9}')
11809         # mmap writes fault in the page first, creating an additonal read
11810         [ "$reads" -eq $((2 * count)) ] ||
11811                 error "$reads reads in < $bsize bucket, expect $count"
11812         [ "$writes" -eq $count ] ||
11813                 error "$writes writes in < $bsize bucket, expect $count"
11814 }
11815 run_test 127c "test llite extent stats with regular & mmap i/o"
11816
11817 test_128() { # bug 15212
11818         touch $DIR/$tfile
11819         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
11820                 find $DIR/$tfile
11821                 find $DIR/$tfile
11822         EOF
11823
11824         result=$(grep error $TMP/$tfile.log)
11825         rm -f $DIR/$tfile $TMP/$tfile.log
11826         [ -z "$result" ] ||
11827                 error "consecutive find's under interactive lfs failed"
11828 }
11829 run_test 128 "interactive lfs for 2 consecutive find's"
11830
11831 set_dir_limits () {
11832         local mntdev
11833         local canondev
11834         local node
11835
11836         local ldproc=/proc/fs/ldiskfs
11837         local facets=$(get_facets MDS)
11838
11839         for facet in ${facets//,/ }; do
11840                 canondev=$(ldiskfs_canon \
11841                            *.$(convert_facet2label $facet).mntdev $facet)
11842                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
11843                         ldproc=/sys/fs/ldiskfs
11844                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
11845                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
11846         done
11847 }
11848
11849 check_mds_dmesg() {
11850         local facets=$(get_facets MDS)
11851         for facet in ${facets//,/ }; do
11852                 do_facet $facet "dmesg | tail -3 | grep -q $1" && return 0
11853         done
11854         return 1
11855 }
11856
11857 test_129() {
11858         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11859         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
11860                 skip "Need MDS version with at least 2.5.56"
11861         if [ "$mds1_FSTYPE" != ldiskfs ]; then
11862                 skip_env "ldiskfs only test"
11863         fi
11864         remote_mds_nodsh && skip "remote MDS with nodsh"
11865
11866         local ENOSPC=28
11867         local EFBIG=27
11868         local has_warning=false
11869
11870         rm -rf $DIR/$tdir
11871         mkdir -p $DIR/$tdir
11872
11873         # block size of mds1
11874         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 5))
11875         set_dir_limits $maxsize $maxsize
11876         local dirsize=$(stat -c%s "$DIR/$tdir")
11877         local nfiles=0
11878         while [[ $dirsize -le $maxsize ]]; do
11879                 $MULTIOP $DIR/$tdir/file_base_$nfiles Oc
11880                 rc=$?
11881                 if ! $has_warning; then
11882                         check_mds_dmesg '"is approaching"' && has_warning=true
11883                 fi
11884                 # check two errors:
11885                 # ENOSPC for new ext4 max_dir_size (kernel commit df981d03ee)
11886                 # EFBIG for previous versions included in ldiskfs series
11887                 if [ $rc -eq $EFBIG ] || [ $rc -eq $ENOSPC ]; then
11888                         set_dir_limits 0 0
11889                         echo "return code $rc received as expected"
11890
11891                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
11892                                 error_exit "create failed w/o dir size limit"
11893
11894                         check_mds_dmesg '"has reached"' ||
11895                                 error_exit "reached message should be output"
11896
11897                         [ $has_warning = "false" ] &&
11898                                 error_exit "warning message should be output"
11899
11900                         dirsize=$(stat -c%s "$DIR/$tdir")
11901
11902                         [[ $dirsize -ge $maxsize ]] && return 0
11903                         error_exit "current dir size $dirsize, " \
11904                                    "previous limit $maxsize"
11905                 elif [ $rc -ne 0 ]; then
11906                         set_dir_limits 0 0
11907                         error_exit "return $rc received instead of expected " \
11908                                    "$EFBIG or $ENOSPC, files in dir $dirsize"
11909                 fi
11910                 nfiles=$((nfiles + 1))
11911                 dirsize=$(stat -c%s "$DIR/$tdir")
11912         done
11913
11914         set_dir_limits 0 0
11915         error "exceeded dir size limit $maxsize($MDSCOUNT) : $dirsize bytes"
11916 }
11917 run_test 129 "test directory size limit ========================"
11918
11919 OLDIFS="$IFS"
11920 cleanup_130() {
11921         trap 0
11922         IFS="$OLDIFS"
11923 }
11924
11925 test_130a() {
11926         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11927         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
11928
11929         trap cleanup_130 EXIT RETURN
11930
11931         local fm_file=$DIR/$tfile
11932         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
11933         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
11934                 error "dd failed for $fm_file"
11935
11936         # LU-1795: test filefrag/FIEMAP once, even if unsupported
11937         filefrag -ves $fm_file
11938         RC=$?
11939         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11940                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11941         [ $RC != 0 ] && error "filefrag $fm_file failed"
11942
11943         filefrag_op=$(filefrag -ve -k $fm_file |
11944                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11945         lun=$($LFS getstripe -i $fm_file)
11946
11947         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
11948         IFS=$'\n'
11949         tot_len=0
11950         for line in $filefrag_op
11951         do
11952                 frag_lun=`echo $line | cut -d: -f5`
11953                 ext_len=`echo $line | cut -d: -f4`
11954                 if (( $frag_lun != $lun )); then
11955                         cleanup_130
11956                         error "FIEMAP on 1-stripe file($fm_file) failed"
11957                         return
11958                 fi
11959                 (( tot_len += ext_len ))
11960         done
11961
11962         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
11963                 cleanup_130
11964                 error "FIEMAP on 1-stripe file($fm_file) failed;"
11965                 return
11966         fi
11967
11968         cleanup_130
11969
11970         echo "FIEMAP on single striped file succeeded"
11971 }
11972 run_test 130a "FIEMAP (1-stripe file)"
11973
11974 test_130b() {
11975         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
11976
11977         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11978         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
11979
11980         trap cleanup_130 EXIT RETURN
11981
11982         local fm_file=$DIR/$tfile
11983         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
11984                         error "setstripe on $fm_file"
11985         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11986                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11987
11988         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
11989                 error "dd failed on $fm_file"
11990
11991         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11992         filefrag_op=$(filefrag -ve -k $fm_file |
11993                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11994
11995         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11996                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11997
11998         IFS=$'\n'
11999         tot_len=0
12000         num_luns=1
12001         for line in $filefrag_op
12002         do
12003                 frag_lun=$(echo $line | cut -d: -f5 |
12004                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12005                 ext_len=$(echo $line | cut -d: -f4)
12006                 if (( $frag_lun != $last_lun )); then
12007                         if (( tot_len != 1024 )); then
12008                                 cleanup_130
12009                                 error "FIEMAP on $fm_file failed; returned " \
12010                                 "len $tot_len for OST $last_lun instead of 1024"
12011                                 return
12012                         else
12013                                 (( num_luns += 1 ))
12014                                 tot_len=0
12015                         fi
12016                 fi
12017                 (( tot_len += ext_len ))
12018                 last_lun=$frag_lun
12019         done
12020         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
12021                 cleanup_130
12022                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12023                         "luns or wrong len for OST $last_lun"
12024                 return
12025         fi
12026
12027         cleanup_130
12028
12029         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
12030 }
12031 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
12032
12033 test_130c() {
12034         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12035
12036         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12037         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12038
12039         trap cleanup_130 EXIT RETURN
12040
12041         local fm_file=$DIR/$tfile
12042         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
12043         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12044                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12045
12046         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
12047                         error "dd failed on $fm_file"
12048
12049         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12050         filefrag_op=$(filefrag -ve -k $fm_file |
12051                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12052
12053         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12054                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12055
12056         IFS=$'\n'
12057         tot_len=0
12058         num_luns=1
12059         for line in $filefrag_op
12060         do
12061                 frag_lun=$(echo $line | cut -d: -f5 |
12062                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12063                 ext_len=$(echo $line | cut -d: -f4)
12064                 if (( $frag_lun != $last_lun )); then
12065                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
12066                         if (( logical != 512 )); then
12067                                 cleanup_130
12068                                 error "FIEMAP on $fm_file failed; returned " \
12069                                 "logical start for lun $logical instead of 512"
12070                                 return
12071                         fi
12072                         if (( tot_len != 512 )); then
12073                                 cleanup_130
12074                                 error "FIEMAP on $fm_file failed; returned " \
12075                                 "len $tot_len for OST $last_lun instead of 1024"
12076                                 return
12077                         else
12078                                 (( num_luns += 1 ))
12079                                 tot_len=0
12080                         fi
12081                 fi
12082                 (( tot_len += ext_len ))
12083                 last_lun=$frag_lun
12084         done
12085         if (( num_luns != 2 || tot_len != 512 )); then
12086                 cleanup_130
12087                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12088                         "luns or wrong len for OST $last_lun"
12089                 return
12090         fi
12091
12092         cleanup_130
12093
12094         echo "FIEMAP on 2-stripe file with hole succeeded"
12095 }
12096 run_test 130c "FIEMAP (2-stripe file with hole)"
12097
12098 test_130d() {
12099         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
12100
12101         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12102         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12103
12104         trap cleanup_130 EXIT RETURN
12105
12106         local fm_file=$DIR/$tfile
12107         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12108                         error "setstripe on $fm_file"
12109         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12110                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12111
12112         local actual_stripe_count=$($LFS getstripe -c $fm_file)
12113         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
12114                 error "dd failed on $fm_file"
12115
12116         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12117         filefrag_op=$(filefrag -ve -k $fm_file |
12118                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12119
12120         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12121                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12122
12123         IFS=$'\n'
12124         tot_len=0
12125         num_luns=1
12126         for line in $filefrag_op
12127         do
12128                 frag_lun=$(echo $line | cut -d: -f5 |
12129                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12130                 ext_len=$(echo $line | cut -d: -f4)
12131                 if (( $frag_lun != $last_lun )); then
12132                         if (( tot_len != 1024 )); then
12133                                 cleanup_130
12134                                 error "FIEMAP on $fm_file failed; returned " \
12135                                 "len $tot_len for OST $last_lun instead of 1024"
12136                                 return
12137                         else
12138                                 (( num_luns += 1 ))
12139                                 tot_len=0
12140                         fi
12141                 fi
12142                 (( tot_len += ext_len ))
12143                 last_lun=$frag_lun
12144         done
12145         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
12146                 cleanup_130
12147                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12148                         "luns or wrong len for OST $last_lun"
12149                 return
12150         fi
12151
12152         cleanup_130
12153
12154         echo "FIEMAP on N-stripe file succeeded"
12155 }
12156 run_test 130d "FIEMAP (N-stripe file)"
12157
12158 test_130e() {
12159         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12160
12161         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12162         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12163
12164         trap cleanup_130 EXIT RETURN
12165
12166         local fm_file=$DIR/$tfile
12167         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
12168         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12169                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12170
12171         NUM_BLKS=512
12172         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
12173         for ((i = 0; i < $NUM_BLKS; i++))
12174         do
12175                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) conv=notrunc > /dev/null 2>&1
12176         done
12177
12178         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12179         filefrag_op=$(filefrag -ve -k $fm_file |
12180                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12181
12182         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12183                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12184
12185         IFS=$'\n'
12186         tot_len=0
12187         num_luns=1
12188         for line in $filefrag_op
12189         do
12190                 frag_lun=$(echo $line | cut -d: -f5 |
12191                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12192                 ext_len=$(echo $line | cut -d: -f4)
12193                 if (( $frag_lun != $last_lun )); then
12194                         if (( tot_len != $EXPECTED_LEN )); then
12195                                 cleanup_130
12196                                 error "FIEMAP on $fm_file failed; returned " \
12197                                 "len $tot_len for OST $last_lun instead " \
12198                                 "of $EXPECTED_LEN"
12199                                 return
12200                         else
12201                                 (( num_luns += 1 ))
12202                                 tot_len=0
12203                         fi
12204                 fi
12205                 (( tot_len += ext_len ))
12206                 last_lun=$frag_lun
12207         done
12208         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
12209                 cleanup_130
12210                 error "FIEMAP on $fm_file failed; returned wrong number " \
12211                         "of luns or wrong len for OST $last_lun"
12212                 return
12213         fi
12214
12215         cleanup_130
12216
12217         echo "FIEMAP with continuation calls succeeded"
12218 }
12219 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
12220
12221 test_130f() {
12222         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12223         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12224
12225         local fm_file=$DIR/$tfile
12226         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
12227                 error "multiop create with lov_delay_create on $fm_file"
12228
12229         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12230         filefrag_extents=$(filefrag -vek $fm_file |
12231                            awk '/extents? found/ { print $2 }')
12232         if [[ "$filefrag_extents" != "0" ]]; then
12233                 error "FIEMAP on $fm_file failed; " \
12234                       "returned $filefrag_extents expected 0"
12235         fi
12236
12237         rm -f $fm_file
12238 }
12239 run_test 130f "FIEMAP (unstriped file)"
12240
12241 # Test for writev/readv
12242 test_131a() {
12243         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
12244                 error "writev test failed"
12245         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
12246                 error "readv failed"
12247         rm -f $DIR/$tfile
12248 }
12249 run_test 131a "test iov's crossing stripe boundary for writev/readv"
12250
12251 test_131b() {
12252         local fsize=$((524288 + 1048576 + 1572864))
12253         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
12254                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12255                         error "append writev test failed"
12256
12257         ((fsize += 1572864 + 1048576))
12258         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
12259                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12260                         error "append writev test failed"
12261         rm -f $DIR/$tfile
12262 }
12263 run_test 131b "test append writev"
12264
12265 test_131c() {
12266         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
12267         error "NOT PASS"
12268 }
12269 run_test 131c "test read/write on file w/o objects"
12270
12271 test_131d() {
12272         rwv -f $DIR/$tfile -w -n 1 1572864
12273         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
12274         if [ "$NOB" != 1572864 ]; then
12275                 error "Short read filed: read $NOB bytes instead of 1572864"
12276         fi
12277         rm -f $DIR/$tfile
12278 }
12279 run_test 131d "test short read"
12280
12281 test_131e() {
12282         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
12283         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
12284         error "read hitting hole failed"
12285         rm -f $DIR/$tfile
12286 }
12287 run_test 131e "test read hitting hole"
12288
12289 check_stats() {
12290         local facet=$1
12291         local op=$2
12292         local want=${3:-0}
12293         local res
12294
12295         case $facet in
12296         mds*) res=$(do_facet $facet \
12297                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
12298                  ;;
12299         ost*) res=$(do_facet $facet \
12300                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
12301                  ;;
12302         *) error "Wrong facet '$facet'" ;;
12303         esac
12304         [ "$res" ] || error "The counter for $op on $facet was not incremented"
12305         # if the argument $3 is zero, it means any stat increment is ok.
12306         if [[ $want -gt 0 ]]; then
12307                 local count=$(echo $res | awk '{ print $2 }')
12308                 [[ $count -ne $want ]] &&
12309                         error "The $op counter on $facet is $count, not $want"
12310         fi
12311 }
12312
12313 test_133a() {
12314         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12315         remote_ost_nodsh && skip "remote OST with nodsh"
12316         remote_mds_nodsh && skip "remote MDS with nodsh"
12317         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
12318                 skip_env "MDS doesn't support rename stats"
12319
12320         local testdir=$DIR/${tdir}/stats_testdir
12321
12322         mkdir -p $DIR/${tdir}
12323
12324         # clear stats.
12325         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12326         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12327
12328         # verify mdt stats first.
12329         mkdir ${testdir} || error "mkdir failed"
12330         check_stats $SINGLEMDS "mkdir" 1
12331         touch ${testdir}/${tfile} || error "touch failed"
12332         check_stats $SINGLEMDS "open" 1
12333         check_stats $SINGLEMDS "close" 1
12334         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
12335                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
12336                 check_stats $SINGLEMDS "mknod" 2
12337         }
12338         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
12339         check_stats $SINGLEMDS "unlink" 1
12340         rm -f ${testdir}/${tfile} || error "file remove failed"
12341         check_stats $SINGLEMDS "unlink" 2
12342
12343         # remove working dir and check mdt stats again.
12344         rmdir ${testdir} || error "rmdir failed"
12345         check_stats $SINGLEMDS "rmdir" 1
12346
12347         local testdir1=$DIR/${tdir}/stats_testdir1
12348         mkdir -p ${testdir}
12349         mkdir -p ${testdir1}
12350         touch ${testdir1}/test1
12351         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
12352         check_stats $SINGLEMDS "crossdir_rename" 1
12353
12354         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
12355         check_stats $SINGLEMDS "samedir_rename" 1
12356
12357         rm -rf $DIR/${tdir}
12358 }
12359 run_test 133a "Verifying MDT stats ========================================"
12360
12361 test_133b() {
12362         local res
12363
12364         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12365         remote_ost_nodsh && skip "remote OST with nodsh"
12366         remote_mds_nodsh && skip "remote MDS with nodsh"
12367
12368         local testdir=$DIR/${tdir}/stats_testdir
12369
12370         mkdir -p ${testdir} || error "mkdir failed"
12371         touch ${testdir}/${tfile} || error "touch failed"
12372         cancel_lru_locks mdc
12373
12374         # clear stats.
12375         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12376         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12377
12378         # extra mdt stats verification.
12379         chmod 444 ${testdir}/${tfile} || error "chmod failed"
12380         check_stats $SINGLEMDS "setattr" 1
12381         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12382         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
12383         then            # LU-1740
12384                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
12385                 check_stats $SINGLEMDS "getattr" 1
12386         fi
12387         rm -rf $DIR/${tdir}
12388
12389         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
12390         # so the check below is not reliable
12391         [ $MDSCOUNT -eq 1 ] || return 0
12392
12393         # Sleep to avoid a cached response.
12394         #define OBD_STATFS_CACHE_SECONDS 1
12395         sleep 2
12396         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12397         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12398         $LFS df || error "lfs failed"
12399         check_stats $SINGLEMDS "statfs" 1
12400
12401         # check aggregated statfs (LU-10018)
12402         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
12403                 return 0
12404         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
12405                 return 0
12406         sleep 2
12407         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12408         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12409         df $DIR
12410         check_stats $SINGLEMDS "statfs" 1
12411
12412         # We want to check that the client didn't send OST_STATFS to
12413         # ost1 but the MDT also uses OST_STATFS for precreate. So some
12414         # extra care is needed here.
12415         if remote_mds; then
12416                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
12417                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
12418
12419                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
12420                 [ "$res" ] && error "OST got STATFS"
12421         fi
12422
12423         return 0
12424 }
12425 run_test 133b "Verifying extra MDT stats =================================="
12426
12427 test_133c() {
12428         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12429         remote_ost_nodsh && skip "remote OST with nodsh"
12430         remote_mds_nodsh && skip "remote MDS with nodsh"
12431
12432         local testdir=$DIR/$tdir/stats_testdir
12433
12434         test_mkdir -p $testdir
12435
12436         # verify obdfilter stats.
12437         $LFS setstripe -c 1 -i 0 $testdir/$tfile
12438         sync
12439         cancel_lru_locks osc
12440         wait_delete_completed
12441
12442         # clear stats.
12443         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12444         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12445
12446         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
12447                 error "dd failed"
12448         sync
12449         cancel_lru_locks osc
12450         check_stats ost1 "write" 1
12451
12452         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
12453         check_stats ost1 "read" 1
12454
12455         > $testdir/$tfile || error "truncate failed"
12456         check_stats ost1 "punch" 1
12457
12458         rm -f $testdir/$tfile || error "file remove failed"
12459         wait_delete_completed
12460         check_stats ost1 "destroy" 1
12461
12462         rm -rf $DIR/$tdir
12463 }
12464 run_test 133c "Verifying OST stats ========================================"
12465
12466 order_2() {
12467         local value=$1
12468         local orig=$value
12469         local order=1
12470
12471         while [ $value -ge 2 ]; do
12472                 order=$((order*2))
12473                 value=$((value/2))
12474         done
12475
12476         if [ $orig -gt $order ]; then
12477                 order=$((order*2))
12478         fi
12479         echo $order
12480 }
12481
12482 size_in_KMGT() {
12483     local value=$1
12484     local size=('K' 'M' 'G' 'T');
12485     local i=0
12486     local size_string=$value
12487
12488     while [ $value -ge 1024 ]; do
12489         if [ $i -gt 3 ]; then
12490             #T is the biggest unit we get here, if that is bigger,
12491             #just return XXXT
12492             size_string=${value}T
12493             break
12494         fi
12495         value=$((value >> 10))
12496         if [ $value -lt 1024 ]; then
12497             size_string=${value}${size[$i]}
12498             break
12499         fi
12500         i=$((i + 1))
12501     done
12502
12503     echo $size_string
12504 }
12505
12506 get_rename_size() {
12507         local size=$1
12508         local context=${2:-.}
12509         local sample=$(do_facet $SINGLEMDS $LCTL \
12510                 get_param mdt.$FSNAME-MDT0000.rename_stats |
12511                 grep -A1 $context |
12512                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
12513         echo $sample
12514 }
12515
12516 test_133d() {
12517         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12518         remote_ost_nodsh && skip "remote OST with nodsh"
12519         remote_mds_nodsh && skip "remote MDS with nodsh"
12520         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
12521                 skip_env "MDS doesn't support rename stats"
12522
12523         local testdir1=$DIR/${tdir}/stats_testdir1
12524         local testdir2=$DIR/${tdir}/stats_testdir2
12525         mkdir -p $DIR/${tdir}
12526
12527         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
12528
12529         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
12530         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
12531
12532         createmany -o $testdir1/test 512 || error "createmany failed"
12533
12534         # check samedir rename size
12535         mv ${testdir1}/test0 ${testdir1}/test_0
12536
12537         local testdir1_size=$(ls -l $DIR/${tdir} |
12538                 awk '/stats_testdir1/ {print $5}')
12539         local testdir2_size=$(ls -l $DIR/${tdir} |
12540                 awk '/stats_testdir2/ {print $5}')
12541
12542         testdir1_size=$(order_2 $testdir1_size)
12543         testdir2_size=$(order_2 $testdir2_size)
12544
12545         testdir1_size=$(size_in_KMGT $testdir1_size)
12546         testdir2_size=$(size_in_KMGT $testdir2_size)
12547
12548         echo "source rename dir size: ${testdir1_size}"
12549         echo "target rename dir size: ${testdir2_size}"
12550
12551         local cmd="do_facet $SINGLEMDS $LCTL "
12552         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
12553
12554         eval $cmd || error "$cmd failed"
12555         local samedir=$($cmd | grep 'same_dir')
12556         local same_sample=$(get_rename_size $testdir1_size)
12557         [ -z "$samedir" ] && error "samedir_rename_size count error"
12558         [[ $same_sample -eq 1 ]] ||
12559                 error "samedir_rename_size error $same_sample"
12560         echo "Check same dir rename stats success"
12561
12562         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
12563
12564         # check crossdir rename size
12565         mv ${testdir1}/test_0 ${testdir2}/test_0
12566
12567         testdir1_size=$(ls -l $DIR/${tdir} |
12568                 awk '/stats_testdir1/ {print $5}')
12569         testdir2_size=$(ls -l $DIR/${tdir} |
12570                 awk '/stats_testdir2/ {print $5}')
12571
12572         testdir1_size=$(order_2 $testdir1_size)
12573         testdir2_size=$(order_2 $testdir2_size)
12574
12575         testdir1_size=$(size_in_KMGT $testdir1_size)
12576         testdir2_size=$(size_in_KMGT $testdir2_size)
12577
12578         echo "source rename dir size: ${testdir1_size}"
12579         echo "target rename dir size: ${testdir2_size}"
12580
12581         eval $cmd || error "$cmd failed"
12582         local crossdir=$($cmd | grep 'crossdir')
12583         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
12584         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
12585         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
12586         [[ $src_sample -eq 1 ]] ||
12587                 error "crossdir_rename_size error $src_sample"
12588         [[ $tgt_sample -eq 1 ]] ||
12589                 error "crossdir_rename_size error $tgt_sample"
12590         echo "Check cross dir rename stats success"
12591         rm -rf $DIR/${tdir}
12592 }
12593 run_test 133d "Verifying rename_stats ========================================"
12594
12595 test_133e() {
12596         remote_mds_nodsh && skip "remote MDS with nodsh"
12597         remote_ost_nodsh && skip "remote OST with nodsh"
12598         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12599
12600         local testdir=$DIR/${tdir}/stats_testdir
12601         local ctr f0 f1 bs=32768 count=42 sum
12602
12603         mkdir -p ${testdir} || error "mkdir failed"
12604
12605         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
12606
12607         for ctr in {write,read}_bytes; do
12608                 sync
12609                 cancel_lru_locks osc
12610
12611                 do_facet ost1 $LCTL set_param -n \
12612                         "obdfilter.*.exports.clear=clear"
12613
12614                 if [ $ctr = write_bytes ]; then
12615                         f0=/dev/zero
12616                         f1=${testdir}/${tfile}
12617                 else
12618                         f0=${testdir}/${tfile}
12619                         f1=/dev/null
12620                 fi
12621
12622                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
12623                         error "dd failed"
12624                 sync
12625                 cancel_lru_locks osc
12626
12627                 sum=$(do_facet ost1 $LCTL get_param \
12628                         "obdfilter.*.exports.*.stats" |
12629                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
12630                                 $1 == ctr { sum += $7 }
12631                                 END { printf("%0.0f", sum) }')
12632
12633                 if ((sum != bs * count)); then
12634                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
12635                 fi
12636         done
12637
12638         rm -rf $DIR/${tdir}
12639 }
12640 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
12641
12642 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
12643
12644 # Some versions of find (4.5.11, 4.5.14) included in CentOS 7.3-7.5 do
12645 # not honor the -ignore_readdir_race option correctly. So we call
12646 # error_ignore() rather than error() in these cases. See LU-11152.
12647 error_133() {
12648         if (find --version; do_facet mds1 find --version) |
12649                 grep -q '\b4\.5\.1[1-4]\b'; then
12650                 error_ignore LU-11152 "$@"
12651         else
12652                 error "$@"
12653         fi
12654 }
12655
12656 test_133f() {
12657         # First without trusting modes.
12658         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
12659         echo "proc_dirs='$proc_dirs'"
12660         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
12661         find $proc_dirs -exec cat '{}' \; &> /dev/null
12662
12663         # Second verifying readability.
12664         $LCTL get_param -R '*' &> /dev/null
12665
12666         # Verifing writability with badarea_io.
12667         find $proc_dirs \
12668                 -ignore_readdir_race \
12669                 -type f \
12670                 -not -name force_lbug \
12671                 -not -name changelog_mask \
12672                 -exec badarea_io '{}' \; ||
12673                         error_133 "find $proc_dirs failed"
12674 }
12675 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
12676
12677 test_133g() {
12678         remote_mds_nodsh && skip "remote MDS with nodsh"
12679         remote_ost_nodsh && skip "remote OST with nodsh"
12680
12681         local facet
12682         for facet in mds1 ost1; do
12683                 local facet_ver=$(lustre_version_code $facet)
12684                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
12685                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
12686                 else
12687                         log "$facet: too old lustre for get_param -R"
12688                 fi
12689                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
12690                         do_facet $facet "$LCTL list_param -R '*' | grep '=' |
12691                                 tr -d= | egrep -v 'force_lbug|changelog_mask' |
12692                                 xargs badarea_io" ||
12693                                         error_133 "$facet badarea_io failed"
12694                 else
12695                         skip_noexit "$facet: too old lustre for get_param -R"
12696                 fi
12697         done
12698
12699         # remount the FS in case writes/reads /proc break the FS
12700         cleanup || error "failed to unmount"
12701         setup || error "failed to setup"
12702         true
12703 }
12704 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
12705
12706 test_133h() {
12707         remote_mds_nodsh && skip "remote MDS with nodsh"
12708         remote_ost_nodsh && skip "remote OST with nodsh"
12709         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
12710                 skip "Need MDS version at least 2.9.54"
12711
12712         local facet
12713
12714         for facet in client mds1 ost1; do
12715                 local facet_proc_dirs=$(do_facet $facet \
12716                                         \\\ls -d $proc_regexp 2> /dev/null)
12717                 [ -z "$facet_proc_dirs" ] && error "no proc_dirs on $facet"
12718                 echo "${facet}_proc_dirs='$facet_proc_dirs'"
12719                 # Get the list of files that are missing the terminating newline
12720                 local missing=($(do_facet $facet \
12721                         find ${facet_proc_dirs} -type f \|              \
12722                                 while read F\; do                       \
12723                                         awk -v FS='\v' -v RS='\v\v'     \
12724                                         "'END { if(NR>0 &&              \
12725                                         \\\$NF !~ /.*\\\n\$/)           \
12726                                                 print FILENAME}'"       \
12727                                         '\$F'\;                         \
12728                                 done 2>/dev/null))
12729                 [ ${#missing[*]} -eq 0 ] ||
12730                         error "files do not end with newline: ${missing[*]}"
12731         done
12732 }
12733 run_test 133h "Proc files should end with newlines"
12734
12735 test_134a() {
12736         remote_mds_nodsh && skip "remote MDS with nodsh"
12737         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
12738                 skip "Need MDS version at least 2.7.54"
12739
12740         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
12741         cancel_lru_locks mdc
12742
12743         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12744         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12745         [ $unused -eq 0 ] || error "$unused locks are not cleared"
12746
12747         local nr=1000
12748         createmany -o $DIR/$tdir/f $nr ||
12749                 error "failed to create $nr files in $DIR/$tdir"
12750         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12751
12752         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
12753         do_facet mds1 $LCTL set_param fail_loc=0x327
12754         do_facet mds1 $LCTL set_param fail_val=500
12755         touch $DIR/$tdir/m
12756
12757         echo "sleep 10 seconds ..."
12758         sleep 10
12759         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
12760
12761         do_facet mds1 $LCTL set_param fail_loc=0
12762         do_facet mds1 $LCTL set_param fail_val=0
12763         [ $lck_cnt -lt $unused ] ||
12764                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
12765
12766         rm $DIR/$tdir/m
12767         unlinkmany $DIR/$tdir/f $nr
12768 }
12769 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
12770
12771 test_134b() {
12772         remote_mds_nodsh && skip "remote MDS with nodsh"
12773         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
12774                 skip "Need MDS version at least 2.7.54"
12775
12776         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
12777         cancel_lru_locks mdc
12778
12779         local low_wm=$(do_facet mds1 $LCTL get_param -n \
12780                         ldlm.lock_reclaim_threshold_mb)
12781         # disable reclaim temporarily
12782         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
12783
12784         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
12785         do_facet mds1 $LCTL set_param fail_loc=0x328
12786         do_facet mds1 $LCTL set_param fail_val=500
12787
12788         $LCTL set_param debug=+trace
12789
12790         local nr=600
12791         createmany -o $DIR/$tdir/f $nr &
12792         local create_pid=$!
12793
12794         echo "Sleep $TIMEOUT seconds ..."
12795         sleep $TIMEOUT
12796         if ! ps -p $create_pid  > /dev/null 2>&1; then
12797                 do_facet mds1 $LCTL set_param fail_loc=0
12798                 do_facet mds1 $LCTL set_param fail_val=0
12799                 do_facet mds1 $LCTL set_param \
12800                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
12801                 error "createmany finished incorrectly!"
12802         fi
12803         do_facet mds1 $LCTL set_param fail_loc=0
12804         do_facet mds1 $LCTL set_param fail_val=0
12805         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
12806         wait $create_pid || return 1
12807
12808         unlinkmany $DIR/$tdir/f $nr
12809 }
12810 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
12811
12812 test_135() {
12813         remote_mds_nodsh && skip "remote MDS with nodsh"
12814         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
12815                 skip "Need MDS version at least 2.13.50"
12816         local fname
12817
12818         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
12819
12820 #define OBD_FAIL_PLAIN_RECORDS 0x1319
12821         #set only one record at plain llog
12822         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
12823
12824         #fill already existed plain llog each 64767
12825         #wrapping whole catalog
12826         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
12827
12828         createmany -o $DIR/$tdir/$tfile_ 64700
12829         for (( i = 0; i < 64700; i = i + 2 ))
12830         do
12831                 rm $DIR/$tdir/$tfile_$i &
12832                 rm $DIR/$tdir/$tfile_$((i + 1)) &
12833                 local pid=$!
12834                 wait $pid
12835         done
12836
12837         #waiting osp synchronization
12838         wait_delete_completed
12839 }
12840 run_test 135 "Race catalog processing"
12841
12842 test_136() {
12843         remote_mds_nodsh && skip "remote MDS with nodsh"
12844         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
12845                 skip "Need MDS version at least 2.13.50"
12846         local fname
12847
12848         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
12849         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
12850         #set only one record at plain llog
12851 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
12852         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
12853
12854         #fill already existed 2 plain llogs each 64767
12855         #wrapping whole catalog
12856         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
12857         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
12858         wait_delete_completed
12859
12860         createmany -o $DIR/$tdir/$tfile_ 10
12861         sleep 25
12862
12863         do_facet $SINGLEMDS $LCTL set_param fail_val=3
12864         for (( i = 0; i < 10; i = i + 3 ))
12865         do
12866                 rm $DIR/$tdir/$tfile_$i &
12867                 rm $DIR/$tdir/$tfile_$((i + 1)) &
12868                 local pid=$!
12869                 wait $pid
12870                 sleep 7
12871                 rm $DIR/$tdir/$tfile_$((i + 2)) &
12872         done
12873
12874         #waiting osp synchronization
12875         wait_delete_completed
12876 }
12877 run_test 136 "Race catalog processing 2"
12878
12879 test_140() { #bug-17379
12880         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12881
12882         test_mkdir $DIR/$tdir
12883         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
12884         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
12885
12886         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
12887         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
12888         local i=0
12889         while i=$((i + 1)); do
12890                 test_mkdir $i
12891                 cd $i || error "Changing to $i"
12892                 ln -s ../stat stat || error "Creating stat symlink"
12893                 # Read the symlink until ELOOP present,
12894                 # not LBUGing the system is considered success,
12895                 # we didn't overrun the stack.
12896                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
12897                 if [ $ret -ne 0 ]; then
12898                         if [ $ret -eq 40 ]; then
12899                                 break  # -ELOOP
12900                         else
12901                                 error "Open stat symlink"
12902                                         return
12903                         fi
12904                 fi
12905         done
12906         i=$((i - 1))
12907         echo "The symlink depth = $i"
12908         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
12909                 error "Invalid symlink depth"
12910
12911         # Test recursive symlink
12912         ln -s symlink_self symlink_self
12913         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
12914         echo "open symlink_self returns $ret"
12915         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
12916 }
12917 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
12918
12919 test_150() {
12920         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12921
12922         local TF="$TMP/$tfile"
12923
12924         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
12925         cp $TF $DIR/$tfile
12926         cancel_lru_locks $OSC
12927         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
12928         remount_client $MOUNT
12929         df -P $MOUNT
12930         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
12931
12932         $TRUNCATE $TF 6000
12933         $TRUNCATE $DIR/$tfile 6000
12934         cancel_lru_locks $OSC
12935         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
12936
12937         echo "12345" >>$TF
12938         echo "12345" >>$DIR/$tfile
12939         cancel_lru_locks $OSC
12940         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
12941
12942         echo "12345" >>$TF
12943         echo "12345" >>$DIR/$tfile
12944         cancel_lru_locks $OSC
12945         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
12946
12947         rm -f $TF
12948         true
12949 }
12950 run_test 150 "truncate/append tests"
12951
12952 #LU-2902 roc_hit was not able to read all values from lproc
12953 function roc_hit_init() {
12954         local list=$(comma_list $(osts_nodes))
12955         local dir=$DIR/$tdir-check
12956         local file=$dir/$tfile
12957         local BEFORE
12958         local AFTER
12959         local idx
12960
12961         test_mkdir $dir
12962         #use setstripe to do a write to every ost
12963         for i in $(seq 0 $((OSTCOUNT-1))); do
12964                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
12965                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
12966                 idx=$(printf %04x $i)
12967                 BEFORE=$(get_osd_param $list *OST*$idx stats |
12968                         awk '$1 == "cache_access" {sum += $7}
12969                                 END { printf("%0.0f", sum) }')
12970
12971                 cancel_lru_locks osc
12972                 cat $file >/dev/null
12973
12974                 AFTER=$(get_osd_param $list *OST*$idx stats |
12975                         awk '$1 == "cache_access" {sum += $7}
12976                                 END { printf("%0.0f", sum) }')
12977
12978                 echo BEFORE:$BEFORE AFTER:$AFTER
12979                 if ! let "AFTER - BEFORE == 4"; then
12980                         rm -rf $dir
12981                         error "roc_hit is not safe to use"
12982                 fi
12983                 rm $file
12984         done
12985
12986         rm -rf $dir
12987 }
12988
12989 function roc_hit() {
12990         local list=$(comma_list $(osts_nodes))
12991         echo $(get_osd_param $list '' stats |
12992                 awk '$1 == "cache_hit" {sum += $7}
12993                         END { printf("%0.0f", sum) }')
12994 }
12995
12996 function set_cache() {
12997         local on=1
12998
12999         if [ "$2" == "off" ]; then
13000                 on=0;
13001         fi
13002         local list=$(comma_list $(osts_nodes))
13003         set_osd_param $list '' $1_cache_enable $on
13004
13005         cancel_lru_locks osc
13006 }
13007
13008 test_151() {
13009         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13010         remote_ost_nodsh && skip "remote OST with nodsh"
13011
13012         local CPAGES=3
13013         local list=$(comma_list $(osts_nodes))
13014
13015         # check whether obdfilter is cache capable at all
13016         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
13017                 skip "not cache-capable obdfilter"
13018         fi
13019
13020         # check cache is enabled on all obdfilters
13021         if get_osd_param $list '' read_cache_enable | grep 0; then
13022                 skip "oss cache is disabled"
13023         fi
13024
13025         set_osd_param $list '' writethrough_cache_enable 1
13026
13027         # check write cache is enabled on all obdfilters
13028         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
13029                 skip "oss write cache is NOT enabled"
13030         fi
13031
13032         roc_hit_init
13033
13034         #define OBD_FAIL_OBD_NO_LRU  0x609
13035         do_nodes $list $LCTL set_param fail_loc=0x609
13036
13037         # pages should be in the case right after write
13038         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
13039                 error "dd failed"
13040
13041         local BEFORE=$(roc_hit)
13042         cancel_lru_locks osc
13043         cat $DIR/$tfile >/dev/null
13044         local AFTER=$(roc_hit)
13045
13046         do_nodes $list $LCTL set_param fail_loc=0
13047
13048         if ! let "AFTER - BEFORE == CPAGES"; then
13049                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
13050         fi
13051
13052         cancel_lru_locks osc
13053         # invalidates OST cache
13054         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
13055         set_osd_param $list '' read_cache_enable 0
13056         cat $DIR/$tfile >/dev/null
13057
13058         # now data shouldn't be found in the cache
13059         BEFORE=$(roc_hit)
13060         cancel_lru_locks osc
13061         cat $DIR/$tfile >/dev/null
13062         AFTER=$(roc_hit)
13063         if let "AFTER - BEFORE != 0"; then
13064                 error "IN CACHE: before: $BEFORE, after: $AFTER"
13065         fi
13066
13067         set_osd_param $list '' read_cache_enable 1
13068         rm -f $DIR/$tfile
13069 }
13070 run_test 151 "test cache on oss and controls ==============================="
13071
13072 test_152() {
13073         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13074
13075         local TF="$TMP/$tfile"
13076
13077         # simulate ENOMEM during write
13078 #define OBD_FAIL_OST_NOMEM      0x226
13079         lctl set_param fail_loc=0x80000226
13080         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13081         cp $TF $DIR/$tfile
13082         sync || error "sync failed"
13083         lctl set_param fail_loc=0
13084
13085         # discard client's cache
13086         cancel_lru_locks osc
13087
13088         # simulate ENOMEM during read
13089         lctl set_param fail_loc=0x80000226
13090         cmp $TF $DIR/$tfile || error "cmp failed"
13091         lctl set_param fail_loc=0
13092
13093         rm -f $TF
13094 }
13095 run_test 152 "test read/write with enomem ============================"
13096
13097 test_153() {
13098         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
13099 }
13100 run_test 153 "test if fdatasync does not crash ======================="
13101
13102 dot_lustre_fid_permission_check() {
13103         local fid=$1
13104         local ffid=$MOUNT/.lustre/fid/$fid
13105         local test_dir=$2
13106
13107         echo "stat fid $fid"
13108         stat $ffid > /dev/null || error "stat $ffid failed."
13109         echo "touch fid $fid"
13110         touch $ffid || error "touch $ffid failed."
13111         echo "write to fid $fid"
13112         cat /etc/hosts > $ffid || error "write $ffid failed."
13113         echo "read fid $fid"
13114         diff /etc/hosts $ffid || error "read $ffid failed."
13115         echo "append write to fid $fid"
13116         cat /etc/hosts >> $ffid || error "append write $ffid failed."
13117         echo "rename fid $fid"
13118         mv $ffid $test_dir/$tfile.1 &&
13119                 error "rename $ffid to $tfile.1 should fail."
13120         touch $test_dir/$tfile.1
13121         mv $test_dir/$tfile.1 $ffid &&
13122                 error "rename $tfile.1 to $ffid should fail."
13123         rm -f $test_dir/$tfile.1
13124         echo "truncate fid $fid"
13125         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
13126         echo "link fid $fid"
13127         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
13128         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
13129                 echo "setfacl fid $fid"
13130                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
13131                 echo "getfacl fid $fid"
13132                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
13133         fi
13134         echo "unlink fid $fid"
13135         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
13136         echo "mknod fid $fid"
13137         mknod $ffid c 1 3 && error "mknod $ffid should fail."
13138
13139         fid=[0xf00000400:0x1:0x0]
13140         ffid=$MOUNT/.lustre/fid/$fid
13141
13142         echo "stat non-exist fid $fid"
13143         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
13144         echo "write to non-exist fid $fid"
13145         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
13146         echo "link new fid $fid"
13147         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
13148
13149         mkdir -p $test_dir/$tdir
13150         touch $test_dir/$tdir/$tfile
13151         fid=$($LFS path2fid $test_dir/$tdir)
13152         rc=$?
13153         [ $rc -ne 0 ] &&
13154                 error "error: could not get fid for $test_dir/$dir/$tfile."
13155
13156         ffid=$MOUNT/.lustre/fid/$fid
13157
13158         echo "ls $fid"
13159         ls $ffid > /dev/null || error "ls $ffid failed."
13160         echo "touch $fid/$tfile.1"
13161         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
13162
13163         echo "touch $MOUNT/.lustre/fid/$tfile"
13164         touch $MOUNT/.lustre/fid/$tfile && \
13165                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
13166
13167         echo "setxattr to $MOUNT/.lustre/fid"
13168         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
13169
13170         echo "listxattr for $MOUNT/.lustre/fid"
13171         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
13172
13173         echo "delxattr from $MOUNT/.lustre/fid"
13174         setfattr -x trusted.name1 $MOUNT/.lustre/fid
13175
13176         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
13177         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
13178                 error "touch invalid fid should fail."
13179
13180         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
13181         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
13182                 error "touch non-normal fid should fail."
13183
13184         echo "rename $tdir to $MOUNT/.lustre/fid"
13185         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
13186                 error "rename to $MOUNT/.lustre/fid should fail."
13187
13188         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
13189         then            # LU-3547
13190                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
13191                 local new_obf_mode=777
13192
13193                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
13194                 chmod $new_obf_mode $DIR/.lustre/fid ||
13195                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
13196
13197                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
13198                 [ $obf_mode -eq $new_obf_mode ] ||
13199                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
13200
13201                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
13202                 chmod $old_obf_mode $DIR/.lustre/fid ||
13203                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
13204         fi
13205
13206         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
13207         fid=$($LFS path2fid $test_dir/$tfile-2)
13208
13209         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
13210         then # LU-5424
13211                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
13212                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
13213                         error "create lov data thru .lustre failed"
13214         fi
13215         echo "cp /etc/passwd $test_dir/$tfile-2"
13216         cp /etc/passwd $test_dir/$tfile-2 ||
13217                 error "copy to $test_dir/$tfile-2 failed."
13218         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
13219         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
13220                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
13221
13222         rm -rf $test_dir/tfile.lnk
13223         rm -rf $test_dir/$tfile-2
13224 }
13225
13226 test_154A() {
13227         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13228                 skip "Need MDS version at least 2.4.1"
13229
13230         local tf=$DIR/$tfile
13231         touch $tf
13232
13233         local fid=$($LFS path2fid $tf)
13234         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
13235
13236         # check that we get the same pathname back
13237         local found=$($LFS fid2path $MOUNT "$fid")
13238         [ -z "$found" ] && error "fid2path unable to get '$fid' path"
13239         [ "$found" == "$tf" ] ||
13240                 error "fid2path($fid=path2fid($tf)) = $found != $tf"
13241 }
13242 run_test 154A "lfs path2fid and fid2path basic checks"
13243
13244 test_154B() {
13245         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13246                 skip "Need MDS version at least 2.4.1"
13247
13248         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
13249         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
13250         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
13251         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
13252
13253         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
13254         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
13255
13256         # check that we get the same pathname
13257         echo "PFID: $PFID, name: $name"
13258         local FOUND=$($LFS fid2path $MOUNT "$PFID")
13259         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
13260         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
13261                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
13262
13263         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
13264 }
13265 run_test 154B "verify the ll_decode_linkea tool"
13266
13267 test_154a() {
13268         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13269         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13270         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
13271                 skip "Need MDS version at least 2.2.51"
13272         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13273
13274         cp /etc/hosts $DIR/$tfile
13275
13276         fid=$($LFS path2fid $DIR/$tfile)
13277         rc=$?
13278         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
13279
13280         dot_lustre_fid_permission_check "$fid" $DIR ||
13281                 error "dot lustre permission check $fid failed"
13282
13283         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
13284
13285         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
13286
13287         touch $MOUNT/.lustre/file &&
13288                 error "creation is not allowed under .lustre"
13289
13290         mkdir $MOUNT/.lustre/dir &&
13291                 error "mkdir is not allowed under .lustre"
13292
13293         rm -rf $DIR/$tfile
13294 }
13295 run_test 154a "Open-by-FID"
13296
13297 test_154b() {
13298         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13299         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13300         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13301         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
13302                 skip "Need MDS version at least 2.2.51"
13303
13304         local remote_dir=$DIR/$tdir/remote_dir
13305         local MDTIDX=1
13306         local rc=0
13307
13308         mkdir -p $DIR/$tdir
13309         $LFS mkdir -i $MDTIDX $remote_dir ||
13310                 error "create remote directory failed"
13311
13312         cp /etc/hosts $remote_dir/$tfile
13313
13314         fid=$($LFS path2fid $remote_dir/$tfile)
13315         rc=$?
13316         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
13317
13318         dot_lustre_fid_permission_check "$fid" $remote_dir ||
13319                 error "dot lustre permission check $fid failed"
13320         rm -rf $DIR/$tdir
13321 }
13322 run_test 154b "Open-by-FID for remote directory"
13323
13324 test_154c() {
13325         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13326                 skip "Need MDS version at least 2.4.1"
13327
13328         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
13329         local FID1=$($LFS path2fid $DIR/$tfile.1)
13330         local FID2=$($LFS path2fid $DIR/$tfile.2)
13331         local FID3=$($LFS path2fid $DIR/$tfile.3)
13332
13333         local N=1
13334         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
13335                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
13336                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
13337                 local want=FID$N
13338                 [ "$FID" = "${!want}" ] ||
13339                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
13340                 N=$((N + 1))
13341         done
13342
13343         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
13344         do
13345                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
13346                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
13347                 N=$((N + 1))
13348         done
13349 }
13350 run_test 154c "lfs path2fid and fid2path multiple arguments"
13351
13352 test_154d() {
13353         remote_mds_nodsh && skip "remote MDS with nodsh"
13354         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
13355                 skip "Need MDS version at least 2.5.53"
13356
13357         if remote_mds; then
13358                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
13359         else
13360                 nid="0@lo"
13361         fi
13362         local proc_ofile="mdt.*.exports.'$nid'.open_files"
13363         local fd
13364         local cmd
13365
13366         rm -f $DIR/$tfile
13367         touch $DIR/$tfile
13368
13369         local fid=$($LFS path2fid $DIR/$tfile)
13370         # Open the file
13371         fd=$(free_fd)
13372         cmd="exec $fd<$DIR/$tfile"
13373         eval $cmd
13374         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
13375         echo "$fid_list" | grep "$fid"
13376         rc=$?
13377
13378         cmd="exec $fd>/dev/null"
13379         eval $cmd
13380         if [ $rc -ne 0 ]; then
13381                 error "FID $fid not found in open files list $fid_list"
13382         fi
13383 }
13384 run_test 154d "Verify open file fid"
13385
13386 test_154e()
13387 {
13388         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
13389                 skip "Need MDS version at least 2.6.50"
13390
13391         if ls -a $MOUNT | grep -q '^\.lustre$'; then
13392                 error ".lustre returned by readdir"
13393         fi
13394 }
13395 run_test 154e ".lustre is not returned by readdir"
13396
13397 test_154f() {
13398         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13399
13400         # create parent directory on a single MDT to avoid cross-MDT hardlinks
13401         test_mkdir -p -c1 $DIR/$tdir/d
13402         # test dirs inherit from its stripe
13403         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
13404         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
13405         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
13406         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
13407         touch $DIR/f
13408
13409         # get fid of parents
13410         local FID0=$($LFS path2fid $DIR/$tdir/d)
13411         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
13412         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
13413         local FID3=$($LFS path2fid $DIR)
13414
13415         # check that path2fid --parents returns expected <parent_fid>/name
13416         # 1) test for a directory (single parent)
13417         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
13418         [ "$parent" == "$FID0/foo1" ] ||
13419                 error "expected parent: $FID0/foo1, got: $parent"
13420
13421         # 2) test for a file with nlink > 1 (multiple parents)
13422         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
13423         echo "$parent" | grep -F "$FID1/$tfile" ||
13424                 error "$FID1/$tfile not returned in parent list"
13425         echo "$parent" | grep -F "$FID2/link" ||
13426                 error "$FID2/link not returned in parent list"
13427
13428         # 3) get parent by fid
13429         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
13430         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13431         echo "$parent" | grep -F "$FID1/$tfile" ||
13432                 error "$FID1/$tfile not returned in parent list (by fid)"
13433         echo "$parent" | grep -F "$FID2/link" ||
13434                 error "$FID2/link not returned in parent list (by fid)"
13435
13436         # 4) test for entry in root directory
13437         parent=$($LFS path2fid --parents $DIR/f)
13438         echo "$parent" | grep -F "$FID3/f" ||
13439                 error "$FID3/f not returned in parent list"
13440
13441         # 5) test it on root directory
13442         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
13443                 error "$MOUNT should not have parents"
13444
13445         # enable xattr caching and check that linkea is correctly updated
13446         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
13447         save_lustre_params client "llite.*.xattr_cache" > $save
13448         lctl set_param llite.*.xattr_cache 1
13449
13450         # 6.1) linkea update on rename
13451         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
13452
13453         # get parents by fid
13454         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13455         # foo1 should no longer be returned in parent list
13456         echo "$parent" | grep -F "$FID1" &&
13457                 error "$FID1 should no longer be in parent list"
13458         # the new path should appear
13459         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
13460                 error "$FID2/$tfile.moved is not in parent list"
13461
13462         # 6.2) linkea update on unlink
13463         rm -f $DIR/$tdir/d/foo2/link
13464         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13465         # foo2/link should no longer be returned in parent list
13466         echo "$parent" | grep -F "$FID2/link" &&
13467                 error "$FID2/link should no longer be in parent list"
13468         true
13469
13470         rm -f $DIR/f
13471         restore_lustre_params < $save
13472         rm -f $save
13473 }
13474 run_test 154f "get parent fids by reading link ea"
13475
13476 test_154g()
13477 {
13478         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13479         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
13480            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
13481                 skip "Need MDS version at least 2.6.92"
13482
13483         mkdir -p $DIR/$tdir
13484         llapi_fid_test -d $DIR/$tdir
13485 }
13486 run_test 154g "various llapi FID tests"
13487
13488 test_155_small_load() {
13489     local temp=$TMP/$tfile
13490     local file=$DIR/$tfile
13491
13492     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
13493         error "dd of=$temp bs=6096 count=1 failed"
13494     cp $temp $file
13495     cancel_lru_locks $OSC
13496     cmp $temp $file || error "$temp $file differ"
13497
13498     $TRUNCATE $temp 6000
13499     $TRUNCATE $file 6000
13500     cmp $temp $file || error "$temp $file differ (truncate1)"
13501
13502     echo "12345" >>$temp
13503     echo "12345" >>$file
13504     cmp $temp $file || error "$temp $file differ (append1)"
13505
13506     echo "12345" >>$temp
13507     echo "12345" >>$file
13508     cmp $temp $file || error "$temp $file differ (append2)"
13509
13510     rm -f $temp $file
13511     true
13512 }
13513
13514 test_155_big_load() {
13515         remote_ost_nodsh && skip "remote OST with nodsh"
13516
13517         local temp=$TMP/$tfile
13518         local file=$DIR/$tfile
13519
13520         free_min_max
13521         local cache_size=$(do_facet ost$((MAXI+1)) \
13522                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
13523         local large_file_size=$((cache_size * 2))
13524
13525         echo "OSS cache size: $cache_size KB"
13526         echo "Large file size: $large_file_size KB"
13527
13528         [ $MAXV -le $large_file_size ] &&
13529                 skip_env "max available OST size needs > $large_file_size KB"
13530
13531         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
13532
13533         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
13534                 error "dd of=$temp bs=$large_file_size count=1k failed"
13535         cp $temp $file
13536         ls -lh $temp $file
13537         cancel_lru_locks osc
13538         cmp $temp $file || error "$temp $file differ"
13539
13540         rm -f $temp $file
13541         true
13542 }
13543
13544 save_writethrough() {
13545         local facets=$(get_facets OST)
13546
13547         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
13548 }
13549
13550 test_155a() {
13551         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13552
13553         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13554
13555         save_writethrough $p
13556
13557         set_cache read on
13558         set_cache writethrough on
13559         test_155_small_load
13560         restore_lustre_params < $p
13561         rm -f $p
13562 }
13563 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
13564
13565 test_155b() {
13566         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13567
13568         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13569
13570         save_writethrough $p
13571
13572         set_cache read on
13573         set_cache writethrough off
13574         test_155_small_load
13575         restore_lustre_params < $p
13576         rm -f $p
13577 }
13578 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
13579
13580 test_155c() {
13581         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13582
13583         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13584
13585         save_writethrough $p
13586
13587         set_cache read off
13588         set_cache writethrough on
13589         test_155_small_load
13590         restore_lustre_params < $p
13591         rm -f $p
13592 }
13593 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
13594
13595 test_155d() {
13596         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13597
13598         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13599
13600         save_writethrough $p
13601
13602         set_cache read off
13603         set_cache writethrough off
13604         test_155_small_load
13605         restore_lustre_params < $p
13606         rm -f $p
13607 }
13608 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
13609
13610 test_155e() {
13611         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13612
13613         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13614
13615         save_writethrough $p
13616
13617         set_cache read on
13618         set_cache writethrough on
13619         test_155_big_load
13620         restore_lustre_params < $p
13621         rm -f $p
13622 }
13623 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
13624
13625 test_155f() {
13626         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13627
13628         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13629
13630         save_writethrough $p
13631
13632         set_cache read on
13633         set_cache writethrough off
13634         test_155_big_load
13635         restore_lustre_params < $p
13636         rm -f $p
13637 }
13638 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
13639
13640 test_155g() {
13641         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13642
13643         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13644
13645         save_writethrough $p
13646
13647         set_cache read off
13648         set_cache writethrough on
13649         test_155_big_load
13650         restore_lustre_params < $p
13651         rm -f $p
13652 }
13653 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
13654
13655 test_155h() {
13656         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13657
13658         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13659
13660         save_writethrough $p
13661
13662         set_cache read off
13663         set_cache writethrough off
13664         test_155_big_load
13665         restore_lustre_params < $p
13666         rm -f $p
13667 }
13668 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
13669
13670 test_156() {
13671         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13672         remote_ost_nodsh && skip "remote OST with nodsh"
13673         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
13674                 skip "stats not implemented on old servers"
13675         [ "$ost1_FSTYPE" = "zfs" ] &&
13676                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
13677
13678         local CPAGES=3
13679         local BEFORE
13680         local AFTER
13681         local file="$DIR/$tfile"
13682         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13683
13684         save_writethrough $p
13685         roc_hit_init
13686
13687         log "Turn on read and write cache"
13688         set_cache read on
13689         set_cache writethrough on
13690
13691         log "Write data and read it back."
13692         log "Read should be satisfied from the cache."
13693         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
13694         BEFORE=$(roc_hit)
13695         cancel_lru_locks osc
13696         cat $file >/dev/null
13697         AFTER=$(roc_hit)
13698         if ! let "AFTER - BEFORE == CPAGES"; then
13699                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
13700         else
13701                 log "cache hits: before: $BEFORE, after: $AFTER"
13702         fi
13703
13704         log "Read again; it should be satisfied from the cache."
13705         BEFORE=$AFTER
13706         cancel_lru_locks osc
13707         cat $file >/dev/null
13708         AFTER=$(roc_hit)
13709         if ! let "AFTER - BEFORE == CPAGES"; then
13710                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
13711         else
13712                 log "cache hits:: before: $BEFORE, after: $AFTER"
13713         fi
13714
13715         log "Turn off the read cache and turn on the write cache"
13716         set_cache read off
13717         set_cache writethrough on
13718
13719         log "Read again; it should be satisfied from the cache."
13720         BEFORE=$(roc_hit)
13721         cancel_lru_locks osc
13722         cat $file >/dev/null
13723         AFTER=$(roc_hit)
13724         if ! let "AFTER - BEFORE == CPAGES"; then
13725                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
13726         else
13727                 log "cache hits:: before: $BEFORE, after: $AFTER"
13728         fi
13729
13730         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
13731                 # > 2.12.56 uses pagecache if cached
13732                 log "Read again; it should not be satisfied from the cache."
13733                 BEFORE=$AFTER
13734                 cancel_lru_locks osc
13735                 cat $file >/dev/null
13736                 AFTER=$(roc_hit)
13737                 if ! let "AFTER - BEFORE == 0"; then
13738                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
13739                 else
13740                         log "cache hits:: before: $BEFORE, after: $AFTER"
13741                 fi
13742         fi
13743
13744         log "Write data and read it back."
13745         log "Read should be satisfied from the cache."
13746         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
13747         BEFORE=$(roc_hit)
13748         cancel_lru_locks osc
13749         cat $file >/dev/null
13750         AFTER=$(roc_hit)
13751         if ! let "AFTER - BEFORE == CPAGES"; then
13752                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
13753         else
13754                 log "cache hits:: before: $BEFORE, after: $AFTER"
13755         fi
13756
13757         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
13758                 # > 2.12.56 uses pagecache if cached
13759                 log "Read again; it should not be satisfied from the cache."
13760                 BEFORE=$AFTER
13761                 cancel_lru_locks osc
13762                 cat $file >/dev/null
13763                 AFTER=$(roc_hit)
13764                 if ! let "AFTER - BEFORE == 0"; then
13765                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
13766                 else
13767                         log "cache hits:: before: $BEFORE, after: $AFTER"
13768                 fi
13769         fi
13770
13771         log "Turn off read and write cache"
13772         set_cache read off
13773         set_cache writethrough off
13774
13775         log "Write data and read it back"
13776         log "It should not be satisfied from the cache."
13777         rm -f $file
13778         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
13779         cancel_lru_locks osc
13780         BEFORE=$(roc_hit)
13781         cat $file >/dev/null
13782         AFTER=$(roc_hit)
13783         if ! let "AFTER - BEFORE == 0"; then
13784                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
13785         else
13786                 log "cache hits:: before: $BEFORE, after: $AFTER"
13787         fi
13788
13789         log "Turn on the read cache and turn off the write cache"
13790         set_cache read on
13791         set_cache writethrough off
13792
13793         log "Write data and read it back"
13794         log "It should not be satisfied from the cache."
13795         rm -f $file
13796         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
13797         BEFORE=$(roc_hit)
13798         cancel_lru_locks osc
13799         cat $file >/dev/null
13800         AFTER=$(roc_hit)
13801         if ! let "AFTER - BEFORE == 0"; then
13802                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
13803         else
13804                 log "cache hits:: before: $BEFORE, after: $AFTER"
13805         fi
13806
13807         log "Read again; it should be satisfied from the cache."
13808         BEFORE=$(roc_hit)
13809         cancel_lru_locks osc
13810         cat $file >/dev/null
13811         AFTER=$(roc_hit)
13812         if ! let "AFTER - BEFORE == CPAGES"; then
13813                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
13814         else
13815                 log "cache hits:: before: $BEFORE, after: $AFTER"
13816         fi
13817
13818         restore_lustre_params < $p
13819         rm -f $p $file
13820 }
13821 run_test 156 "Verification of tunables"
13822
13823 test_160a() {
13824         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13825         remote_mds_nodsh && skip "remote MDS with nodsh"
13826         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
13827                 skip "Need MDS version at least 2.2.0"
13828
13829         changelog_register || error "changelog_register failed"
13830         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
13831         changelog_users $SINGLEMDS | grep -q $cl_user ||
13832                 error "User $cl_user not found in changelog_users"
13833
13834         # change something
13835         test_mkdir -p $DIR/$tdir/pics/2008/zachy
13836         changelog_clear 0 || error "changelog_clear failed"
13837         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
13838         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
13839         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
13840         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
13841         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
13842         rm $DIR/$tdir/pics/desktop.jpg
13843
13844         changelog_dump | tail -10
13845
13846         echo "verifying changelog mask"
13847         changelog_chmask "-MKDIR"
13848         changelog_chmask "-CLOSE"
13849
13850         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
13851         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
13852
13853         changelog_chmask "+MKDIR"
13854         changelog_chmask "+CLOSE"
13855
13856         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
13857         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
13858
13859         changelog_dump | tail -10
13860         MKDIRS=$(changelog_dump | grep -c "MKDIR")
13861         CLOSES=$(changelog_dump | grep -c "CLOSE")
13862         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
13863         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
13864
13865         # verify contents
13866         echo "verifying target fid"
13867         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
13868         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
13869         [ "$fidc" == "$fidf" ] ||
13870                 error "changelog '$tfile' fid $fidc != file fid $fidf"
13871         echo "verifying parent fid"
13872         # The FID returned from the Changelog may be the directory shard on
13873         # a different MDT, and not the FID returned by path2fid on the parent.
13874         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
13875         # since this is what will matter when recreating this file in the tree.
13876         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
13877         local pathp=$($LFS fid2path $MOUNT "$fidp")
13878         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
13879                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
13880
13881         echo "getting records for $cl_user"
13882         changelog_users $SINGLEMDS
13883         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
13884         local nclr=3
13885         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
13886                 error "changelog_clear failed"
13887         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
13888         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
13889         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
13890                 error "user index expect $user_rec1 + $nclr != $user_rec2"
13891
13892         local min0_rec=$(changelog_users $SINGLEMDS |
13893                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
13894         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
13895                           awk '{ print $1; exit; }')
13896
13897         changelog_dump | tail -n 5
13898         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
13899         [ $first_rec == $((min0_rec + 1)) ] ||
13900                 error "first index should be $min0_rec + 1 not $first_rec"
13901
13902         # LU-3446 changelog index reset on MDT restart
13903         local cur_rec1=$(changelog_users $SINGLEMDS |
13904                          awk '/^current.index:/ { print $NF }')
13905         changelog_clear 0 ||
13906                 error "clear all changelog records for $cl_user failed"
13907         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
13908         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
13909                 error "Fail to start $SINGLEMDS"
13910         local cur_rec2=$(changelog_users $SINGLEMDS |
13911                          awk '/^current.index:/ { print $NF }')
13912         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
13913         [ $cur_rec1 == $cur_rec2 ] ||
13914                 error "current index should be $cur_rec1 not $cur_rec2"
13915
13916         echo "verifying users from this test are deregistered"
13917         changelog_deregister || error "changelog_deregister failed"
13918         changelog_users $SINGLEMDS | grep -q $cl_user &&
13919                 error "User '$cl_user' still in changelog_users"
13920
13921         # lctl get_param -n mdd.*.changelog_users
13922         # current index: 144
13923         # ID    index (idle seconds)
13924         # cl3   144 (2)
13925         if ! changelog_users $SINGLEMDS | grep "^cl"; then
13926                 # this is the normal case where all users were deregistered
13927                 # make sure no new records are added when no users are present
13928                 local last_rec1=$(changelog_users $SINGLEMDS |
13929                                   awk '/^current.index:/ { print $NF }')
13930                 touch $DIR/$tdir/chloe
13931                 local last_rec2=$(changelog_users $SINGLEMDS |
13932                                   awk '/^current.index:/ { print $NF }')
13933                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
13934                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
13935         else
13936                 # any changelog users must be leftovers from a previous test
13937                 changelog_users $SINGLEMDS
13938                 echo "other changelog users; can't verify off"
13939         fi
13940 }
13941 run_test 160a "changelog sanity"
13942
13943 test_160b() { # LU-3587
13944         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13945         remote_mds_nodsh && skip "remote MDS with nodsh"
13946         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
13947                 skip "Need MDS version at least 2.2.0"
13948
13949         changelog_register || error "changelog_register failed"
13950         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
13951         changelog_users $SINGLEMDS | grep -q $cl_user ||
13952                 error "User '$cl_user' not found in changelog_users"
13953
13954         local longname1=$(str_repeat a 255)
13955         local longname2=$(str_repeat b 255)
13956
13957         cd $DIR
13958         echo "creating very long named file"
13959         touch $longname1 || error "create of '$longname1' failed"
13960         echo "renaming very long named file"
13961         mv $longname1 $longname2
13962
13963         changelog_dump | grep RENME | tail -n 5
13964         rm -f $longname2
13965 }
13966 run_test 160b "Verify that very long rename doesn't crash in changelog"
13967
13968 test_160c() {
13969         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13970         remote_mds_nodsh && skip "remote MDS with nodsh"
13971
13972         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
13973                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
13974                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
13975                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
13976
13977         local rc=0
13978
13979         # Registration step
13980         changelog_register || error "changelog_register failed"
13981
13982         rm -rf $DIR/$tdir
13983         mkdir -p $DIR/$tdir
13984         $MCREATE $DIR/$tdir/foo_160c
13985         changelog_chmask "-TRUNC"
13986         $TRUNCATE $DIR/$tdir/foo_160c 200
13987         changelog_chmask "+TRUNC"
13988         $TRUNCATE $DIR/$tdir/foo_160c 199
13989         changelog_dump | tail -n 5
13990         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
13991         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
13992 }
13993 run_test 160c "verify that changelog log catch the truncate event"
13994
13995 test_160d() {
13996         remote_mds_nodsh && skip "remote MDS with nodsh"
13997         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13998         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13999         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
14000                 skip "Need MDS version at least 2.7.60"
14001
14002         # Registration step
14003         changelog_register || error "changelog_register failed"
14004
14005         mkdir -p $DIR/$tdir/migrate_dir
14006         changelog_clear 0 || error "changelog_clear failed"
14007
14008         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
14009         changelog_dump | tail -n 5
14010         local migrates=$(changelog_dump | grep -c "MIGRT")
14011         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
14012 }
14013 run_test 160d "verify that changelog log catch the migrate event"
14014
14015 test_160e() {
14016         remote_mds_nodsh && skip "remote MDS with nodsh"
14017
14018         # Create a user
14019         changelog_register || error "changelog_register failed"
14020
14021         # Delete a future user (expect fail)
14022         local MDT0=$(facet_svc $SINGLEMDS)
14023         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
14024         local rc=$?
14025
14026         if [ $rc -eq 0 ]; then
14027                 error "Deleted non-existant user cl77"
14028         elif [ $rc -ne 2 ]; then
14029                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
14030         fi
14031
14032         # Clear to a bad index (1 billion should be safe)
14033         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
14034         rc=$?
14035
14036         if [ $rc -eq 0 ]; then
14037                 error "Successfully cleared to invalid CL index"
14038         elif [ $rc -ne 22 ]; then
14039                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
14040         fi
14041 }
14042 run_test 160e "changelog negative testing (should return errors)"
14043
14044 test_160f() {
14045         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14046         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14047                 skip "Need MDS version at least 2.10.56"
14048
14049         local mdts=$(comma_list $(mdts_nodes))
14050
14051         # Create a user
14052         changelog_register || error "first changelog_register failed"
14053         changelog_register || error "second changelog_register failed"
14054         local cl_users
14055         declare -A cl_user1
14056         declare -A cl_user2
14057         local user_rec1
14058         local user_rec2
14059         local i
14060
14061         # generate some changelog records to accumulate on each MDT
14062         # use fnv1a because created files should be evenly distributed
14063         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14064                 error "test_mkdir $tdir failed"
14065         log "$(date +%s): creating first files"
14066         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14067                 error "create $DIR/$tdir/$tfile failed"
14068
14069         # check changelogs have been generated
14070         local start=$SECONDS
14071         local idle_time=$((MDSCOUNT * 5 + 5))
14072         local nbcl=$(changelog_dump | wc -l)
14073         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14074
14075         for param in "changelog_max_idle_time=$idle_time" \
14076                      "changelog_gc=1" \
14077                      "changelog_min_gc_interval=2" \
14078                      "changelog_min_free_cat_entries=3"; do
14079                 local MDT0=$(facet_svc $SINGLEMDS)
14080                 local var="${param%=*}"
14081                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14082
14083                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14084                 do_nodes $mdts $LCTL set_param mdd.*.$param
14085         done
14086
14087         # force cl_user2 to be idle (1st part), but also cancel the
14088         # cl_user1 records so that it is not evicted later in the test.
14089         local sleep1=$((idle_time / 2))
14090         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
14091         sleep $sleep1
14092
14093         # simulate changelog catalog almost full
14094         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
14095         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
14096
14097         for i in $(seq $MDSCOUNT); do
14098                 cl_users=(${CL_USERS[mds$i]})
14099                 cl_user1[mds$i]="${cl_users[0]}"
14100                 cl_user2[mds$i]="${cl_users[1]}"
14101
14102                 [ -n "${cl_user1[mds$i]}" ] ||
14103                         error "mds$i: no user registered"
14104                 [ -n "${cl_user2[mds$i]}" ] ||
14105                         error "mds$i: only ${cl_user2[mds$i]} is registered"
14106
14107                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14108                 [ -n "$user_rec1" ] ||
14109                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14110                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14111                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14112                 [ -n "$user_rec2" ] ||
14113                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14114                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14115                      "$user_rec1 + 2 == $user_rec2"
14116                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14117                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14118                               "$user_rec1 + 2, but is $user_rec2"
14119                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14120                 [ -n "$user_rec2" ] ||
14121                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14122                 [ $user_rec1 == $user_rec2 ] ||
14123                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14124                               "$user_rec1, but is $user_rec2"
14125         done
14126
14127         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
14128         local sleep2=$((idle_time - (SECONDS - start) + 1))
14129         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
14130         sleep $sleep2
14131
14132         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
14133         # cl_user1 should be OK because it recently processed records.
14134         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
14135         createmany -m $DIR/$tdir/${tfile}b $((MDSCOUNT * 2)) ||
14136                 error "create $DIR/$tdir/${tfile}b failed"
14137
14138         # ensure gc thread is done
14139         for i in $(mdts_nodes); do
14140                 wait_update $i \
14141                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
14142                         error "$i: GC-thread not done"
14143         done
14144
14145         local first_rec
14146         for i in $(seq $MDSCOUNT); do
14147                 # check cl_user1 still registered
14148                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14149                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14150                 # check cl_user2 unregistered
14151                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14152                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14153
14154                 # check changelogs are present and starting at $user_rec1 + 1
14155                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14156                 [ -n "$user_rec1" ] ||
14157                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14158                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14159                             awk '{ print $1; exit; }')
14160
14161                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14162                 [ $((user_rec1 + 1)) == $first_rec ] ||
14163                         error "mds$i: first index should be $user_rec1 + 1, " \
14164                               "but is $first_rec"
14165         done
14166 }
14167 run_test 160f "changelog garbage collect (timestamped users)"
14168
14169 test_160g() {
14170         remote_mds_nodsh && skip "remote MDS with nodsh"
14171         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14172                 skip "Need MDS version at least 2.10.56"
14173
14174         local mdts=$(comma_list $(mdts_nodes))
14175
14176         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
14177         do_nodes $mdts $LCTL set_param fail_loc=0x1314
14178
14179         # Create a user
14180         changelog_register || error "first changelog_register failed"
14181         changelog_register || error "second changelog_register failed"
14182         local cl_users
14183         declare -A cl_user1
14184         declare -A cl_user2
14185         local user_rec1
14186         local user_rec2
14187         local i
14188
14189         # generate some changelog records to accumulate on each MDT
14190         # use fnv1a because created files should be evenly distributed
14191         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14192                 error "mkdir $tdir failed"
14193         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14194                 error "create $DIR/$tdir/$tfile failed"
14195
14196         # check changelogs have been generated
14197         local nbcl=$(changelog_dump | wc -l)
14198         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14199
14200         # reduce the max_idle_indexes value to make sure we exceed it
14201         max_ndx=$((nbcl / 2 - 1))
14202
14203         for param in "changelog_max_idle_indexes=$max_ndx" \
14204                      "changelog_gc=1" \
14205                      "changelog_min_gc_interval=2" \
14206                      "changelog_min_free_cat_entries=3"; do
14207                 local MDT0=$(facet_svc $SINGLEMDS)
14208                 local var="${param%=*}"
14209                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14210
14211                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14212                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
14213                         error "unable to set mdd.*.$param"
14214         done
14215
14216         # simulate changelog catalog almost full
14217         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
14218         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
14219
14220         for i in $(seq $MDSCOUNT); do
14221                 cl_users=(${CL_USERS[mds$i]})
14222                 cl_user1[mds$i]="${cl_users[0]}"
14223                 cl_user2[mds$i]="${cl_users[1]}"
14224
14225                 [ -n "${cl_user1[mds$i]}" ] ||
14226                         error "mds$i: no user registered"
14227                 [ -n "${cl_user2[mds$i]}" ] ||
14228                         error "mds$i: only ${cl_user1[mds$i]} is registered"
14229
14230                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14231                 [ -n "$user_rec1" ] ||
14232                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14233                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14234                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14235                 [ -n "$user_rec2" ] ||
14236                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14237                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14238                      "$user_rec1 + 2 == $user_rec2"
14239                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14240                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14241                               "$user_rec1 + 2, but is $user_rec2"
14242                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14243                 [ -n "$user_rec2" ] ||
14244                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14245                 [ $user_rec1 == $user_rec2 ] ||
14246                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14247                               "$user_rec1, but is $user_rec2"
14248         done
14249
14250         # ensure we are past the previous changelog_min_gc_interval set above
14251         sleep 2
14252
14253         # generate one more changelog to trigger fail_loc
14254         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14255                 error "create $DIR/$tdir/${tfile}bis failed"
14256
14257         # ensure gc thread is done
14258         for i in $(mdts_nodes); do
14259                 wait_update $i \
14260                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
14261                         error "$i: GC-thread not done"
14262         done
14263
14264         local first_rec
14265         for i in $(seq $MDSCOUNT); do
14266                 # check cl_user1 still registered
14267                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14268                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14269                 # check cl_user2 unregistered
14270                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14271                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14272
14273                 # check changelogs are present and starting at $user_rec1 + 1
14274                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14275                 [ -n "$user_rec1" ] ||
14276                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14277                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14278                             awk '{ print $1; exit; }')
14279
14280                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14281                 [ $((user_rec1 + 1)) == $first_rec ] ||
14282                         error "mds$i: first index should be $user_rec1 + 1, " \
14283                               "but is $first_rec"
14284         done
14285 }
14286 run_test 160g "changelog garbage collect (old users)"
14287
14288 test_160h() {
14289         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14290         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14291                 skip "Need MDS version at least 2.10.56"
14292
14293         local mdts=$(comma_list $(mdts_nodes))
14294
14295         # Create a user
14296         changelog_register || error "first changelog_register failed"
14297         changelog_register || error "second changelog_register failed"
14298         local cl_users
14299         declare -A cl_user1
14300         declare -A cl_user2
14301         local user_rec1
14302         local user_rec2
14303         local i
14304
14305         # generate some changelog records to accumulate on each MDT
14306         # use fnv1a because created files should be evenly distributed
14307         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14308                 error "test_mkdir $tdir failed"
14309         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14310                 error "create $DIR/$tdir/$tfile failed"
14311
14312         # check changelogs have been generated
14313         local nbcl=$(changelog_dump | wc -l)
14314         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14315
14316         for param in "changelog_max_idle_time=10" \
14317                      "changelog_gc=1" \
14318                      "changelog_min_gc_interval=2"; do
14319                 local MDT0=$(facet_svc $SINGLEMDS)
14320                 local var="${param%=*}"
14321                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14322
14323                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14324                 do_nodes $mdts $LCTL set_param mdd.*.$param
14325         done
14326
14327         # force cl_user2 to be idle (1st part)
14328         sleep 9
14329
14330         for i in $(seq $MDSCOUNT); do
14331                 cl_users=(${CL_USERS[mds$i]})
14332                 cl_user1[mds$i]="${cl_users[0]}"
14333                 cl_user2[mds$i]="${cl_users[1]}"
14334
14335                 [ -n "${cl_user1[mds$i]}" ] ||
14336                         error "mds$i: no user registered"
14337                 [ -n "${cl_user2[mds$i]}" ] ||
14338                         error "mds$i: only ${cl_user2[mds$i]} is registered"
14339
14340                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14341                 [ -n "$user_rec1" ] ||
14342                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14343                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14344                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14345                 [ -n "$user_rec2" ] ||
14346                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14347                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14348                      "$user_rec1 + 2 == $user_rec2"
14349                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14350                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14351                               "$user_rec1 + 2, but is $user_rec2"
14352                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14353                 [ -n "$user_rec2" ] ||
14354                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14355                 [ $user_rec1 == $user_rec2 ] ||
14356                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14357                               "$user_rec1, but is $user_rec2"
14358         done
14359
14360         # force cl_user2 to be idle (2nd part) and to reach
14361         # changelog_max_idle_time
14362         sleep 2
14363
14364         # force each GC-thread start and block then
14365         # one per MDT/MDD, set fail_val accordingly
14366         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
14367         do_nodes $mdts $LCTL set_param fail_loc=0x1316
14368
14369         # generate more changelogs to trigger fail_loc
14370         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14371                 error "create $DIR/$tdir/${tfile}bis failed"
14372
14373         # stop MDT to stop GC-thread, should be done in back-ground as it will
14374         # block waiting for the thread to be released and exit
14375         declare -A stop_pids
14376         for i in $(seq $MDSCOUNT); do
14377                 stop mds$i &
14378                 stop_pids[mds$i]=$!
14379         done
14380
14381         for i in $(mdts_nodes); do
14382                 local facet
14383                 local nb=0
14384                 local facets=$(facets_up_on_host $i)
14385
14386                 for facet in ${facets//,/ }; do
14387                         if [[ $facet == mds* ]]; then
14388                                 nb=$((nb + 1))
14389                         fi
14390                 done
14391                 # ensure each MDS's gc threads are still present and all in "R"
14392                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
14393                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
14394                         error "$i: expected $nb GC-thread"
14395                 wait_update $i \
14396                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
14397                         "R" 20 ||
14398                         error "$i: GC-thread not found in R-state"
14399                 # check umounts of each MDT on MDS have reached kthread_stop()
14400                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
14401                         error "$i: expected $nb umount"
14402                 wait_update $i \
14403                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
14404                         error "$i: umount not found in D-state"
14405         done
14406
14407         # release all GC-threads
14408         do_nodes $mdts $LCTL set_param fail_loc=0
14409
14410         # wait for MDT stop to complete
14411         for i in $(seq $MDSCOUNT); do
14412                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
14413         done
14414
14415         # XXX
14416         # may try to check if any orphan changelog records are present
14417         # via ldiskfs/zfs and llog_reader...
14418
14419         # re-start/mount MDTs
14420         for i in $(seq $MDSCOUNT); do
14421                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
14422                         error "Fail to start mds$i"
14423         done
14424
14425         local first_rec
14426         for i in $(seq $MDSCOUNT); do
14427                 # check cl_user1 still registered
14428                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14429                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14430                 # check cl_user2 unregistered
14431                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14432                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14433
14434                 # check changelogs are present and starting at $user_rec1 + 1
14435                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14436                 [ -n "$user_rec1" ] ||
14437                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14438                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14439                             awk '{ print $1; exit; }')
14440
14441                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14442                 [ $((user_rec1 + 1)) == $first_rec ] ||
14443                         error "mds$i: first index should be $user_rec1 + 1, " \
14444                               "but is $first_rec"
14445         done
14446 }
14447 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
14448               "during mount"
14449
14450 test_160i() {
14451
14452         local mdts=$(comma_list $(mdts_nodes))
14453
14454         changelog_register || error "first changelog_register failed"
14455
14456         # generate some changelog records to accumulate on each MDT
14457         # use fnv1a because created files should be evenly distributed
14458         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14459                 error "mkdir $tdir failed"
14460         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14461                 error "create $DIR/$tdir/$tfile failed"
14462
14463         # check changelogs have been generated
14464         local nbcl=$(changelog_dump | wc -l)
14465         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14466
14467         # simulate race between register and unregister
14468         # XXX as fail_loc is set per-MDS, with DNE configs the race
14469         # simulation will only occur for one MDT per MDS and for the
14470         # others the normal race scenario will take place
14471         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
14472         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
14473         do_nodes $mdts $LCTL set_param fail_val=1
14474
14475         # unregister 1st user
14476         changelog_deregister &
14477         local pid1=$!
14478         # wait some time for deregister work to reach race rdv
14479         sleep 2
14480         # register 2nd user
14481         changelog_register || error "2nd user register failed"
14482
14483         wait $pid1 || error "1st user deregister failed"
14484
14485         local i
14486         local last_rec
14487         declare -A LAST_REC
14488         for i in $(seq $MDSCOUNT); do
14489                 if changelog_users mds$i | grep "^cl"; then
14490                         # make sure new records are added with one user present
14491                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
14492                                           awk '/^current.index:/ { print $NF }')
14493                 else
14494                         error "mds$i has no user registered"
14495                 fi
14496         done
14497
14498         # generate more changelog records to accumulate on each MDT
14499         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14500                 error "create $DIR/$tdir/${tfile}bis failed"
14501
14502         for i in $(seq $MDSCOUNT); do
14503                 last_rec=$(changelog_users $SINGLEMDS |
14504                            awk '/^current.index:/ { print $NF }')
14505                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
14506                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
14507                         error "changelogs are off on mds$i"
14508         done
14509 }
14510 run_test 160i "changelog user register/unregister race"
14511
14512 test_160j() {
14513         remote_mds_nodsh && skip "remote MDS with nodsh"
14514         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
14515                 skip "Need MDS version at least 2.12.56"
14516
14517         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
14518         stack_trap "umount $MOUNT2" EXIT
14519
14520         changelog_register || error "first changelog_register failed"
14521         stack_trap "changelog_deregister" EXIT
14522
14523         # generate some changelog
14524         # use fnv1a because created files should be evenly distributed
14525         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14526                 error "mkdir $tdir failed"
14527         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14528                 error "create $DIR/$tdir/${tfile}bis failed"
14529
14530         # open the changelog device
14531         exec 3>/dev/changelog-$FSNAME-MDT0000
14532         stack_trap "exec 3>&-" EXIT
14533         exec 4</dev/changelog-$FSNAME-MDT0000
14534         stack_trap "exec 4<&-" EXIT
14535
14536         # umount the first lustre mount
14537         umount $MOUNT
14538         stack_trap "mount_client $MOUNT" EXIT
14539
14540         # read changelog
14541         cat <&4 >/dev/null || error "read changelog failed"
14542
14543         # clear changelog
14544         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14545         changelog_users $SINGLEMDS | grep -q $cl_user ||
14546                 error "User $cl_user not found in changelog_users"
14547
14548         printf 'clear:'$cl_user':0' >&3
14549 }
14550 run_test 160j "client can be umounted  while its chanangelog is being used"
14551
14552 test_160k() {
14553         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14554         remote_mds_nodsh && skip "remote MDS with nodsh"
14555
14556         mkdir -p $DIR/$tdir/1/1
14557
14558         changelog_register || error "changelog_register failed"
14559         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14560
14561         changelog_users $SINGLEMDS | grep -q $cl_user ||
14562                 error "User '$cl_user' not found in changelog_users"
14563 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
14564         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
14565         rmdir $DIR/$tdir/1/1 & sleep 1
14566         mkdir $DIR/$tdir/2
14567         touch $DIR/$tdir/2/2
14568         rm -rf $DIR/$tdir/2
14569
14570         wait
14571         sleep 4
14572
14573         changelog_dump | grep rmdir || error "rmdir not recorded"
14574
14575         rm -rf $DIR/$tdir
14576         changelog_deregister
14577 }
14578 run_test 160k "Verify that changelog records are not lost"
14579
14580 test_161a() {
14581         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14582
14583         test_mkdir -c1 $DIR/$tdir
14584         cp /etc/hosts $DIR/$tdir/$tfile
14585         test_mkdir -c1 $DIR/$tdir/foo1
14586         test_mkdir -c1 $DIR/$tdir/foo2
14587         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
14588         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
14589         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
14590         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
14591         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
14592         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
14593                 $LFS fid2path $DIR $FID
14594                 error "bad link ea"
14595         fi
14596         # middle
14597         rm $DIR/$tdir/foo2/zachary
14598         # last
14599         rm $DIR/$tdir/foo2/thor
14600         # first
14601         rm $DIR/$tdir/$tfile
14602         # rename
14603         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
14604         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
14605                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
14606         rm $DIR/$tdir/foo2/maggie
14607
14608         # overflow the EA
14609         local longname=$tfile.avg_len_is_thirty_two_
14610         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
14611                 error_noexit 'failed to unlink many hardlinks'" EXIT
14612         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
14613                 error "failed to hardlink many files"
14614         links=$($LFS fid2path $DIR $FID | wc -l)
14615         echo -n "${links}/1000 links in link EA"
14616         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
14617 }
14618 run_test 161a "link ea sanity"
14619
14620 test_161b() {
14621         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14622         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
14623
14624         local MDTIDX=1
14625         local remote_dir=$DIR/$tdir/remote_dir
14626
14627         mkdir -p $DIR/$tdir
14628         $LFS mkdir -i $MDTIDX $remote_dir ||
14629                 error "create remote directory failed"
14630
14631         cp /etc/hosts $remote_dir/$tfile
14632         mkdir -p $remote_dir/foo1
14633         mkdir -p $remote_dir/foo2
14634         ln $remote_dir/$tfile $remote_dir/foo1/sofia
14635         ln $remote_dir/$tfile $remote_dir/foo2/zachary
14636         ln $remote_dir/$tfile $remote_dir/foo1/luna
14637         ln $remote_dir/$tfile $remote_dir/foo2/thor
14638
14639         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
14640                      tr -d ']')
14641         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
14642                 $LFS fid2path $DIR $FID
14643                 error "bad link ea"
14644         fi
14645         # middle
14646         rm $remote_dir/foo2/zachary
14647         # last
14648         rm $remote_dir/foo2/thor
14649         # first
14650         rm $remote_dir/$tfile
14651         # rename
14652         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
14653         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
14654         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
14655                 $LFS fid2path $DIR $FID
14656                 error "bad link rename"
14657         fi
14658         rm $remote_dir/foo2/maggie
14659
14660         # overflow the EA
14661         local longname=filename_avg_len_is_thirty_two_
14662         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
14663                 error "failed to hardlink many files"
14664         links=$($LFS fid2path $DIR $FID | wc -l)
14665         echo -n "${links}/1000 links in link EA"
14666         [[ ${links} -gt 60 ]] ||
14667                 error "expected at least 60 links in link EA"
14668         unlinkmany $remote_dir/foo2/$longname 1000 ||
14669         error "failed to unlink many hardlinks"
14670 }
14671 run_test 161b "link ea sanity under remote directory"
14672
14673 test_161c() {
14674         remote_mds_nodsh && skip "remote MDS with nodsh"
14675         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14676         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
14677                 skip "Need MDS version at least 2.1.5"
14678
14679         # define CLF_RENAME_LAST 0x0001
14680         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
14681         changelog_register || error "changelog_register failed"
14682
14683         rm -rf $DIR/$tdir
14684         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
14685         touch $DIR/$tdir/foo_161c
14686         touch $DIR/$tdir/bar_161c
14687         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
14688         changelog_dump | grep RENME | tail -n 5
14689         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
14690         changelog_clear 0 || error "changelog_clear failed"
14691         if [ x$flags != "x0x1" ]; then
14692                 error "flag $flags is not 0x1"
14693         fi
14694
14695         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
14696         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
14697         touch $DIR/$tdir/foo_161c
14698         touch $DIR/$tdir/bar_161c
14699         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
14700         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
14701         changelog_dump | grep RENME | tail -n 5
14702         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
14703         changelog_clear 0 || error "changelog_clear failed"
14704         if [ x$flags != "x0x0" ]; then
14705                 error "flag $flags is not 0x0"
14706         fi
14707         echo "rename overwrite a target having nlink > 1," \
14708                 "changelog record has flags of $flags"
14709
14710         # rename doesn't overwrite a target (changelog flag 0x0)
14711         touch $DIR/$tdir/foo_161c
14712         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
14713         changelog_dump | grep RENME | tail -n 5
14714         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
14715         changelog_clear 0 || error "changelog_clear failed"
14716         if [ x$flags != "x0x0" ]; then
14717                 error "flag $flags is not 0x0"
14718         fi
14719         echo "rename doesn't overwrite a target," \
14720                 "changelog record has flags of $flags"
14721
14722         # define CLF_UNLINK_LAST 0x0001
14723         # unlink a file having nlink = 1 (changelog flag 0x1)
14724         rm -f $DIR/$tdir/foo2_161c
14725         changelog_dump | grep UNLNK | tail -n 5
14726         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
14727         changelog_clear 0 || error "changelog_clear failed"
14728         if [ x$flags != "x0x1" ]; then
14729                 error "flag $flags is not 0x1"
14730         fi
14731         echo "unlink a file having nlink = 1," \
14732                 "changelog record has flags of $flags"
14733
14734         # unlink a file having nlink > 1 (changelog flag 0x0)
14735         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
14736         rm -f $DIR/$tdir/foobar_161c
14737         changelog_dump | grep UNLNK | tail -n 5
14738         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
14739         changelog_clear 0 || error "changelog_clear failed"
14740         if [ x$flags != "x0x0" ]; then
14741                 error "flag $flags is not 0x0"
14742         fi
14743         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
14744 }
14745 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
14746
14747 test_161d() {
14748         remote_mds_nodsh && skip "remote MDS with nodsh"
14749         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
14750
14751         local pid
14752         local fid
14753
14754         changelog_register || error "changelog_register failed"
14755
14756         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
14757         # interfer with $MOUNT/.lustre/fid/ access
14758         mkdir $DIR/$tdir
14759         [[ $? -eq 0 ]] || error "mkdir failed"
14760
14761         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
14762         $LCTL set_param fail_loc=0x8000140c
14763         # 5s pause
14764         $LCTL set_param fail_val=5
14765
14766         # create file
14767         echo foofoo > $DIR/$tdir/$tfile &
14768         pid=$!
14769
14770         # wait for create to be delayed
14771         sleep 2
14772
14773         ps -p $pid
14774         [[ $? -eq 0 ]] || error "create should be blocked"
14775
14776         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
14777         stack_trap "rm -f $tempfile"
14778         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
14779         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
14780         # some delay may occur during ChangeLog publishing and file read just
14781         # above, that could allow file write to happen finally
14782         [[ -s $tempfile ]] && echo "file should be empty"
14783
14784         $LCTL set_param fail_loc=0
14785
14786         wait $pid
14787         [[ $? -eq 0 ]] || error "create failed"
14788 }
14789 run_test 161d "create with concurrent .lustre/fid access"
14790
14791 check_path() {
14792         local expected="$1"
14793         shift
14794         local fid="$2"
14795
14796         local path
14797         path=$($LFS fid2path "$@")
14798         local rc=$?
14799
14800         if [ $rc -ne 0 ]; then
14801                 error "path looked up of '$expected' failed: rc=$rc"
14802         elif [ "$path" != "$expected" ]; then
14803                 error "path looked up '$path' instead of '$expected'"
14804         else
14805                 echo "FID '$fid' resolves to path '$path' as expected"
14806         fi
14807 }
14808
14809 test_162a() { # was test_162
14810         test_mkdir -p -c1 $DIR/$tdir/d2
14811         touch $DIR/$tdir/d2/$tfile
14812         touch $DIR/$tdir/d2/x1
14813         touch $DIR/$tdir/d2/x2
14814         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
14815         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
14816         # regular file
14817         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
14818         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
14819
14820         # softlink
14821         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
14822         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
14823         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
14824
14825         # softlink to wrong file
14826         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
14827         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
14828         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
14829
14830         # hardlink
14831         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
14832         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
14833         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
14834         # fid2path dir/fsname should both work
14835         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
14836         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
14837
14838         # hardlink count: check that there are 2 links
14839         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
14840         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
14841
14842         # hardlink indexing: remove the first link
14843         rm $DIR/$tdir/d2/p/q/r/hlink
14844         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
14845 }
14846 run_test 162a "path lookup sanity"
14847
14848 test_162b() {
14849         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14850         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14851
14852         mkdir $DIR/$tdir
14853         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
14854                                 error "create striped dir failed"
14855
14856         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
14857                                         tail -n 1 | awk '{print $2}')
14858         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
14859
14860         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
14861         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
14862
14863         # regular file
14864         for ((i=0;i<5;i++)); do
14865                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
14866                         error "get fid for f$i failed"
14867                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
14868
14869                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
14870                         error "get fid for d$i failed"
14871                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
14872         done
14873
14874         return 0
14875 }
14876 run_test 162b "striped directory path lookup sanity"
14877
14878 # LU-4239: Verify fid2path works with paths 100 or more directories deep
14879 test_162c() {
14880         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
14881                 skip "Need MDS version at least 2.7.51"
14882
14883         local lpath=$tdir.local
14884         local rpath=$tdir.remote
14885
14886         test_mkdir $DIR/$lpath
14887         test_mkdir $DIR/$rpath
14888
14889         for ((i = 0; i <= 101; i++)); do
14890                 lpath="$lpath/$i"
14891                 mkdir $DIR/$lpath
14892                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
14893                         error "get fid for local directory $DIR/$lpath failed"
14894                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
14895
14896                 rpath="$rpath/$i"
14897                 test_mkdir $DIR/$rpath
14898                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
14899                         error "get fid for remote directory $DIR/$rpath failed"
14900                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
14901         done
14902
14903         return 0
14904 }
14905 run_test 162c "fid2path works with paths 100 or more directories deep"
14906
14907 test_169() {
14908         # do directio so as not to populate the page cache
14909         log "creating a 10 Mb file"
14910         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
14911         log "starting reads"
14912         dd if=$DIR/$tfile of=/dev/null bs=4096 &
14913         log "truncating the file"
14914         $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
14915         log "killing dd"
14916         kill %+ || true # reads might have finished
14917         echo "wait until dd is finished"
14918         wait
14919         log "removing the temporary file"
14920         rm -rf $DIR/$tfile || error "tmp file removal failed"
14921 }
14922 run_test 169 "parallel read and truncate should not deadlock"
14923
14924 test_170() {
14925         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14926
14927         $LCTL clear     # bug 18514
14928         $LCTL debug_daemon start $TMP/${tfile}_log_good
14929         touch $DIR/$tfile
14930         $LCTL debug_daemon stop
14931         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
14932                 error "sed failed to read log_good"
14933
14934         $LCTL debug_daemon start $TMP/${tfile}_log_good
14935         rm -rf $DIR/$tfile
14936         $LCTL debug_daemon stop
14937
14938         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
14939                error "lctl df log_bad failed"
14940
14941         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
14942         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
14943
14944         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
14945         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
14946
14947         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
14948                 error "bad_line good_line1 good_line2 are empty"
14949
14950         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
14951         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
14952         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
14953
14954         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
14955         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
14956         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
14957
14958         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
14959                 error "bad_line_new good_line_new are empty"
14960
14961         local expected_good=$((good_line1 + good_line2*2))
14962
14963         rm -f $TMP/${tfile}*
14964         # LU-231, short malformed line may not be counted into bad lines
14965         if [ $bad_line -ne $bad_line_new ] &&
14966                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
14967                 error "expected $bad_line bad lines, but got $bad_line_new"
14968                 return 1
14969         fi
14970
14971         if [ $expected_good -ne $good_line_new ]; then
14972                 error "expected $expected_good good lines, but got $good_line_new"
14973                 return 2
14974         fi
14975         true
14976 }
14977 run_test 170 "test lctl df to handle corrupted log ====================="
14978
14979 test_171() { # bug20592
14980         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14981
14982         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
14983         $LCTL set_param fail_loc=0x50e
14984         $LCTL set_param fail_val=3000
14985         multiop_bg_pause $DIR/$tfile O_s || true
14986         local MULTIPID=$!
14987         kill -USR1 $MULTIPID
14988         # cause log dump
14989         sleep 3
14990         wait $MULTIPID
14991         if dmesg | grep "recursive fault"; then
14992                 error "caught a recursive fault"
14993         fi
14994         $LCTL set_param fail_loc=0
14995         true
14996 }
14997 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
14998
14999 # it would be good to share it with obdfilter-survey/iokit-libecho code
15000 setup_obdecho_osc () {
15001         local rc=0
15002         local ost_nid=$1
15003         local obdfilter_name=$2
15004         echo "Creating new osc for $obdfilter_name on $ost_nid"
15005         # make sure we can find loopback nid
15006         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
15007
15008         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
15009                            ${obdfilter_name}_osc_UUID || rc=2; }
15010         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
15011                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
15012         return $rc
15013 }
15014
15015 cleanup_obdecho_osc () {
15016         local obdfilter_name=$1
15017         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
15018         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
15019         return 0
15020 }
15021
15022 obdecho_test() {
15023         local OBD=$1
15024         local node=$2
15025         local pages=${3:-64}
15026         local rc=0
15027         local id
15028
15029         local count=10
15030         local obd_size=$(get_obd_size $node $OBD)
15031         local page_size=$(get_page_size $node)
15032         if [[ -n "$obd_size" ]]; then
15033                 local new_count=$((obd_size / (pages * page_size / 1024)))
15034                 [[ $new_count -ge $count ]] || count=$new_count
15035         fi
15036
15037         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
15038         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
15039                            rc=2; }
15040         if [ $rc -eq 0 ]; then
15041             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
15042             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
15043         fi
15044         echo "New object id is $id"
15045         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
15046                            rc=4; }
15047         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
15048                            "test_brw $count w v $pages $id" || rc=4; }
15049         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
15050                            rc=4; }
15051         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
15052                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
15053         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
15054                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
15055         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
15056         return $rc
15057 }
15058
15059 test_180a() {
15060         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15061
15062         if ! module_loaded obdecho; then
15063                 load_module obdecho/obdecho &&
15064                         stack_trap "rmmod obdecho" EXIT ||
15065                         error "unable to load obdecho on client"
15066         fi
15067
15068         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
15069         local host=$($LCTL get_param -n osc.$osc.import |
15070                      awk '/current_connection:/ { print $2 }' )
15071         local target=$($LCTL get_param -n osc.$osc.import |
15072                        awk '/target:/ { print $2 }' )
15073         target=${target%_UUID}
15074
15075         if [ -n "$target" ]; then
15076                 setup_obdecho_osc $host $target &&
15077                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
15078                         { error "obdecho setup failed with $?"; return; }
15079
15080                 obdecho_test ${target}_osc client ||
15081                         error "obdecho_test failed on ${target}_osc"
15082         else
15083                 $LCTL get_param osc.$osc.import
15084                 error "there is no osc.$osc.import target"
15085         fi
15086 }
15087 run_test 180a "test obdecho on osc"
15088
15089 test_180b() {
15090         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15091         remote_ost_nodsh && skip "remote OST with nodsh"
15092
15093         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
15094                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
15095                 error "failed to load module obdecho"
15096
15097         local target=$(do_facet ost1 $LCTL dl |
15098                        awk '/obdfilter/ { print $4; exit; }')
15099
15100         if [ -n "$target" ]; then
15101                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
15102         else
15103                 do_facet ost1 $LCTL dl
15104                 error "there is no obdfilter target on ost1"
15105         fi
15106 }
15107 run_test 180b "test obdecho directly on obdfilter"
15108
15109 test_180c() { # LU-2598
15110         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15111         remote_ost_nodsh && skip "remote OST with nodsh"
15112         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
15113                 skip "Need MDS version at least 2.4.0"
15114
15115         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
15116                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
15117                 error "failed to load module obdecho"
15118
15119         local target=$(do_facet ost1 $LCTL dl |
15120                        awk '/obdfilter/ { print $4; exit; }')
15121
15122         if [ -n "$target" ]; then
15123                 local pages=16384 # 64MB bulk I/O RPC size
15124
15125                 obdecho_test "$target" ost1 "$pages" ||
15126                         error "obdecho_test with pages=$pages failed with $?"
15127         else
15128                 do_facet ost1 $LCTL dl
15129                 error "there is no obdfilter target on ost1"
15130         fi
15131 }
15132 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
15133
15134 test_181() { # bug 22177
15135         test_mkdir $DIR/$tdir
15136         # create enough files to index the directory
15137         createmany -o $DIR/$tdir/foobar 4000
15138         # print attributes for debug purpose
15139         lsattr -d .
15140         # open dir
15141         multiop_bg_pause $DIR/$tdir D_Sc || return 1
15142         MULTIPID=$!
15143         # remove the files & current working dir
15144         unlinkmany $DIR/$tdir/foobar 4000
15145         rmdir $DIR/$tdir
15146         kill -USR1 $MULTIPID
15147         wait $MULTIPID
15148         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
15149         return 0
15150 }
15151 run_test 181 "Test open-unlinked dir ========================"
15152
15153 test_182() {
15154         local fcount=1000
15155         local tcount=10
15156
15157         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
15158
15159         $LCTL set_param mdc.*.rpc_stats=clear
15160
15161         for (( i = 0; i < $tcount; i++ )) ; do
15162                 mkdir $DIR/$tdir/$i
15163         done
15164
15165         for (( i = 0; i < $tcount; i++ )) ; do
15166                 createmany -o $DIR/$tdir/$i/f- $fcount &
15167         done
15168         wait
15169
15170         for (( i = 0; i < $tcount; i++ )) ; do
15171                 unlinkmany $DIR/$tdir/$i/f- $fcount &
15172         done
15173         wait
15174
15175         $LCTL get_param mdc.*.rpc_stats
15176
15177         rm -rf $DIR/$tdir
15178 }
15179 run_test 182 "Test parallel modify metadata operations ================"
15180
15181 test_183() { # LU-2275
15182         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15183         remote_mds_nodsh && skip "remote MDS with nodsh"
15184         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
15185                 skip "Need MDS version at least 2.3.56"
15186
15187         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
15188         echo aaa > $DIR/$tdir/$tfile
15189
15190 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
15191         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
15192
15193         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
15194         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
15195
15196         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
15197
15198         # Flush negative dentry cache
15199         touch $DIR/$tdir/$tfile
15200
15201         # We are not checking for any leaked references here, they'll
15202         # become evident next time we do cleanup with module unload.
15203         rm -rf $DIR/$tdir
15204 }
15205 run_test 183 "No crash or request leak in case of strange dispositions ========"
15206
15207 # test suite 184 is for LU-2016, LU-2017
15208 test_184a() {
15209         check_swap_layouts_support
15210
15211         dir0=$DIR/$tdir/$testnum
15212         test_mkdir -p -c1 $dir0
15213         ref1=/etc/passwd
15214         ref2=/etc/group
15215         file1=$dir0/f1
15216         file2=$dir0/f2
15217         $LFS setstripe -c1 $file1
15218         cp $ref1 $file1
15219         $LFS setstripe -c2 $file2
15220         cp $ref2 $file2
15221         gen1=$($LFS getstripe -g $file1)
15222         gen2=$($LFS getstripe -g $file2)
15223
15224         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
15225         gen=$($LFS getstripe -g $file1)
15226         [[ $gen1 != $gen ]] ||
15227                 "Layout generation on $file1 does not change"
15228         gen=$($LFS getstripe -g $file2)
15229         [[ $gen2 != $gen ]] ||
15230                 "Layout generation on $file2 does not change"
15231
15232         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
15233         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
15234
15235         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
15236 }
15237 run_test 184a "Basic layout swap"
15238
15239 test_184b() {
15240         check_swap_layouts_support
15241
15242         dir0=$DIR/$tdir/$testnum
15243         mkdir -p $dir0 || error "creating dir $dir0"
15244         file1=$dir0/f1
15245         file2=$dir0/f2
15246         file3=$dir0/f3
15247         dir1=$dir0/d1
15248         dir2=$dir0/d2
15249         mkdir $dir1 $dir2
15250         $LFS setstripe -c1 $file1
15251         $LFS setstripe -c2 $file2
15252         $LFS setstripe -c1 $file3
15253         chown $RUNAS_ID $file3
15254         gen1=$($LFS getstripe -g $file1)
15255         gen2=$($LFS getstripe -g $file2)
15256
15257         $LFS swap_layouts $dir1 $dir2 &&
15258                 error "swap of directories layouts should fail"
15259         $LFS swap_layouts $dir1 $file1 &&
15260                 error "swap of directory and file layouts should fail"
15261         $RUNAS $LFS swap_layouts $file1 $file2 &&
15262                 error "swap of file we cannot write should fail"
15263         $LFS swap_layouts $file1 $file3 &&
15264                 error "swap of file with different owner should fail"
15265         /bin/true # to clear error code
15266 }
15267 run_test 184b "Forbidden layout swap (will generate errors)"
15268
15269 test_184c() {
15270         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
15271         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
15272         check_swap_layouts_support
15273
15274         local dir0=$DIR/$tdir/$testnum
15275         mkdir -p $dir0 || error "creating dir $dir0"
15276
15277         local ref1=$dir0/ref1
15278         local ref2=$dir0/ref2
15279         local file1=$dir0/file1
15280         local file2=$dir0/file2
15281         # create a file large enough for the concurrent test
15282         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
15283         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
15284         echo "ref file size: ref1($(stat -c %s $ref1))," \
15285              "ref2($(stat -c %s $ref2))"
15286
15287         cp $ref2 $file2
15288         dd if=$ref1 of=$file1 bs=16k &
15289         local DD_PID=$!
15290
15291         # Make sure dd starts to copy file
15292         while [ ! -f $file1 ]; do sleep 0.1; done
15293
15294         $LFS swap_layouts $file1 $file2
15295         local rc=$?
15296         wait $DD_PID
15297         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
15298         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
15299
15300         # how many bytes copied before swapping layout
15301         local copied=$(stat -c %s $file2)
15302         local remaining=$(stat -c %s $ref1)
15303         remaining=$((remaining - copied))
15304         echo "Copied $copied bytes before swapping layout..."
15305
15306         cmp -n $copied $file1 $ref2 | grep differ &&
15307                 error "Content mismatch [0, $copied) of ref2 and file1"
15308         cmp -n $copied $file2 $ref1 ||
15309                 error "Content mismatch [0, $copied) of ref1 and file2"
15310         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
15311                 error "Content mismatch [$copied, EOF) of ref1 and file1"
15312
15313         # clean up
15314         rm -f $ref1 $ref2 $file1 $file2
15315 }
15316 run_test 184c "Concurrent write and layout swap"
15317
15318 test_184d() {
15319         check_swap_layouts_support
15320         [ -z "$(which getfattr 2>/dev/null)" ] &&
15321                 skip_env "no getfattr command"
15322
15323         local file1=$DIR/$tdir/$tfile-1
15324         local file2=$DIR/$tdir/$tfile-2
15325         local file3=$DIR/$tdir/$tfile-3
15326         local lovea1
15327         local lovea2
15328
15329         mkdir -p $DIR/$tdir
15330         touch $file1 || error "create $file1 failed"
15331         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
15332                 error "create $file2 failed"
15333         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
15334                 error "create $file3 failed"
15335         lovea1=$(get_layout_param $file1)
15336
15337         $LFS swap_layouts $file2 $file3 ||
15338                 error "swap $file2 $file3 layouts failed"
15339         $LFS swap_layouts $file1 $file2 ||
15340                 error "swap $file1 $file2 layouts failed"
15341
15342         lovea2=$(get_layout_param $file2)
15343         echo "$lovea1"
15344         echo "$lovea2"
15345         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
15346
15347         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
15348         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
15349 }
15350 run_test 184d "allow stripeless layouts swap"
15351
15352 test_184e() {
15353         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
15354                 skip "Need MDS version at least 2.6.94"
15355         check_swap_layouts_support
15356         [ -z "$(which getfattr 2>/dev/null)" ] &&
15357                 skip_env "no getfattr command"
15358
15359         local file1=$DIR/$tdir/$tfile-1
15360         local file2=$DIR/$tdir/$tfile-2
15361         local file3=$DIR/$tdir/$tfile-3
15362         local lovea
15363
15364         mkdir -p $DIR/$tdir
15365         touch $file1 || error "create $file1 failed"
15366         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
15367                 error "create $file2 failed"
15368         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
15369                 error "create $file3 failed"
15370
15371         $LFS swap_layouts $file1 $file2 ||
15372                 error "swap $file1 $file2 layouts failed"
15373
15374         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
15375         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
15376
15377         echo 123 > $file1 || error "Should be able to write into $file1"
15378
15379         $LFS swap_layouts $file1 $file3 ||
15380                 error "swap $file1 $file3 layouts failed"
15381
15382         echo 123 > $file1 || error "Should be able to write into $file1"
15383
15384         rm -rf $file1 $file2 $file3
15385 }
15386 run_test 184e "Recreate layout after stripeless layout swaps"
15387
15388 test_184f() {
15389         # Create a file with name longer than sizeof(struct stat) ==
15390         # 144 to see if we can get chars from the file name to appear
15391         # in the returned striping. Note that 'f' == 0x66.
15392         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
15393
15394         mkdir -p $DIR/$tdir
15395         mcreate $DIR/$tdir/$file
15396         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
15397                 error "IOC_MDC_GETFILEINFO returned garbage striping"
15398         fi
15399 }
15400 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
15401
15402 test_185() { # LU-2441
15403         # LU-3553 - no volatile file support in old servers
15404         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
15405                 skip "Need MDS version at least 2.3.60"
15406
15407         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
15408         touch $DIR/$tdir/spoo
15409         local mtime1=$(stat -c "%Y" $DIR/$tdir)
15410         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
15411                 error "cannot create/write a volatile file"
15412         [ "$FILESET" == "" ] &&
15413         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
15414                 error "FID is still valid after close"
15415
15416         multiop_bg_pause $DIR/$tdir vVw4096_c
15417         local multi_pid=$!
15418
15419         local OLD_IFS=$IFS
15420         IFS=":"
15421         local fidv=($fid)
15422         IFS=$OLD_IFS
15423         # assume that the next FID for this client is sequential, since stdout
15424         # is unfortunately eaten by multiop_bg_pause
15425         local n=$((${fidv[1]} + 1))
15426         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
15427         if [ "$FILESET" == "" ]; then
15428                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
15429                         error "FID is missing before close"
15430         fi
15431         kill -USR1 $multi_pid
15432         # 1 second delay, so if mtime change we will see it
15433         sleep 1
15434         local mtime2=$(stat -c "%Y" $DIR/$tdir)
15435         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
15436 }
15437 run_test 185 "Volatile file support"
15438
15439 function create_check_volatile() {
15440         local idx=$1
15441         local tgt
15442
15443         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
15444         local PID=$!
15445         sleep 1
15446         local FID=$(cat /tmp/${tfile}.fid)
15447         [ "$FID" == "" ] && error "can't get FID for volatile"
15448         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
15449         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
15450         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
15451         kill -USR1 $PID
15452         wait
15453         sleep 1
15454         cancel_lru_locks mdc # flush opencache
15455         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
15456         return 0
15457 }
15458
15459 test_185a(){
15460         # LU-12516 - volatile creation via .lustre
15461         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
15462                 skip "Need MDS version at least 2.3.55"
15463
15464         create_check_volatile 0
15465         [ $MDSCOUNT -lt 2 ] && return 0
15466
15467         # DNE case
15468         create_check_volatile 1
15469
15470         return 0
15471 }
15472 run_test 185a "Volatile file creation in .lustre/fid/"
15473
15474 test_187a() {
15475         remote_mds_nodsh && skip "remote MDS with nodsh"
15476         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
15477                 skip "Need MDS version at least 2.3.0"
15478
15479         local dir0=$DIR/$tdir/$testnum
15480         mkdir -p $dir0 || error "creating dir $dir0"
15481
15482         local file=$dir0/file1
15483         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
15484         local dv1=$($LFS data_version $file)
15485         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
15486         local dv2=$($LFS data_version $file)
15487         [[ $dv1 != $dv2 ]] ||
15488                 error "data version did not change on write $dv1 == $dv2"
15489
15490         # clean up
15491         rm -f $file1
15492 }
15493 run_test 187a "Test data version change"
15494
15495 test_187b() {
15496         remote_mds_nodsh && skip "remote MDS with nodsh"
15497         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
15498                 skip "Need MDS version at least 2.3.0"
15499
15500         local dir0=$DIR/$tdir/$testnum
15501         mkdir -p $dir0 || error "creating dir $dir0"
15502
15503         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
15504         [[ ${DV[0]} != ${DV[1]} ]] ||
15505                 error "data version did not change on write"\
15506                       " ${DV[0]} == ${DV[1]}"
15507
15508         # clean up
15509         rm -f $file1
15510 }
15511 run_test 187b "Test data version change on volatile file"
15512
15513 test_200() {
15514         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15515         remote_mgs_nodsh && skip "remote MGS with nodsh"
15516         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15517
15518         local POOL=${POOL:-cea1}
15519         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
15520         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
15521         # Pool OST targets
15522         local first_ost=0
15523         local last_ost=$(($OSTCOUNT - 1))
15524         local ost_step=2
15525         local ost_list=$(seq $first_ost $ost_step $last_ost)
15526         local ost_range="$first_ost $last_ost $ost_step"
15527         local test_path=$POOL_ROOT/$POOL_DIR_NAME
15528         local file_dir=$POOL_ROOT/file_tst
15529         local subdir=$test_path/subdir
15530         local rc=0
15531
15532         while : ; do
15533                 # former test_200a test_200b
15534                 pool_add $POOL                          || { rc=$? ; break; }
15535                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
15536                 # former test_200c test_200d
15537                 mkdir -p $test_path
15538                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
15539                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
15540                 mkdir -p $subdir
15541                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
15542                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
15543                                                         || { rc=$? ; break; }
15544                 # former test_200e test_200f
15545                 local files=$((OSTCOUNT*3))
15546                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
15547                                                         || { rc=$? ; break; }
15548                 pool_create_files $POOL $file_dir $files "$ost_list" \
15549                                                         || { rc=$? ; break; }
15550                 # former test_200g test_200h
15551                 pool_lfs_df $POOL                       || { rc=$? ; break; }
15552                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
15553
15554                 # former test_201a test_201b test_201c
15555                 pool_remove_first_target $POOL          || { rc=$? ; break; }
15556
15557                 local f=$test_path/$tfile
15558                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
15559                 pool_remove $POOL $f                    || { rc=$? ; break; }
15560                 break
15561         done
15562
15563         destroy_test_pools
15564
15565         return $rc
15566 }
15567 run_test 200 "OST pools"
15568
15569 # usage: default_attr <count | size | offset>
15570 default_attr() {
15571         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
15572 }
15573
15574 # usage: check_default_stripe_attr
15575 check_default_stripe_attr() {
15576         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
15577         case $1 in
15578         --stripe-count|-c)
15579                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
15580         --stripe-size|-S)
15581                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
15582         --stripe-index|-i)
15583                 EXPECTED=-1;;
15584         *)
15585                 error "unknown getstripe attr '$1'"
15586         esac
15587
15588         [ $ACTUAL == $EXPECTED ] ||
15589                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
15590 }
15591
15592 test_204a() {
15593         test_mkdir $DIR/$tdir
15594         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
15595
15596         check_default_stripe_attr --stripe-count
15597         check_default_stripe_attr --stripe-size
15598         check_default_stripe_attr --stripe-index
15599 }
15600 run_test 204a "Print default stripe attributes"
15601
15602 test_204b() {
15603         test_mkdir $DIR/$tdir
15604         $LFS setstripe --stripe-count 1 $DIR/$tdir
15605
15606         check_default_stripe_attr --stripe-size
15607         check_default_stripe_attr --stripe-index
15608 }
15609 run_test 204b "Print default stripe size and offset"
15610
15611 test_204c() {
15612         test_mkdir $DIR/$tdir
15613         $LFS setstripe --stripe-size 65536 $DIR/$tdir
15614
15615         check_default_stripe_attr --stripe-count
15616         check_default_stripe_attr --stripe-index
15617 }
15618 run_test 204c "Print default stripe count and offset"
15619
15620 test_204d() {
15621         test_mkdir $DIR/$tdir
15622         $LFS setstripe --stripe-index 0 $DIR/$tdir
15623
15624         check_default_stripe_attr --stripe-count
15625         check_default_stripe_attr --stripe-size
15626 }
15627 run_test 204d "Print default stripe count and size"
15628
15629 test_204e() {
15630         test_mkdir $DIR/$tdir
15631         $LFS setstripe -d $DIR/$tdir
15632
15633         check_default_stripe_attr --stripe-count --raw
15634         check_default_stripe_attr --stripe-size --raw
15635         check_default_stripe_attr --stripe-index --raw
15636 }
15637 run_test 204e "Print raw stripe attributes"
15638
15639 test_204f() {
15640         test_mkdir $DIR/$tdir
15641         $LFS setstripe --stripe-count 1 $DIR/$tdir
15642
15643         check_default_stripe_attr --stripe-size --raw
15644         check_default_stripe_attr --stripe-index --raw
15645 }
15646 run_test 204f "Print raw stripe size and offset"
15647
15648 test_204g() {
15649         test_mkdir $DIR/$tdir
15650         $LFS setstripe --stripe-size 65536 $DIR/$tdir
15651
15652         check_default_stripe_attr --stripe-count --raw
15653         check_default_stripe_attr --stripe-index --raw
15654 }
15655 run_test 204g "Print raw stripe count and offset"
15656
15657 test_204h() {
15658         test_mkdir $DIR/$tdir
15659         $LFS setstripe --stripe-index 0 $DIR/$tdir
15660
15661         check_default_stripe_attr --stripe-count --raw
15662         check_default_stripe_attr --stripe-size --raw
15663 }
15664 run_test 204h "Print raw stripe count and size"
15665
15666 # Figure out which job scheduler is being used, if any,
15667 # or use a fake one
15668 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
15669         JOBENV=SLURM_JOB_ID
15670 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
15671         JOBENV=LSB_JOBID
15672 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
15673         JOBENV=PBS_JOBID
15674 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
15675         JOBENV=LOADL_STEP_ID
15676 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
15677         JOBENV=JOB_ID
15678 else
15679         $LCTL list_param jobid_name > /dev/null 2>&1
15680         if [ $? -eq 0 ]; then
15681                 JOBENV=nodelocal
15682         else
15683                 JOBENV=FAKE_JOBID
15684         fi
15685 fi
15686 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
15687
15688 verify_jobstats() {
15689         local cmd=($1)
15690         shift
15691         local facets="$@"
15692
15693 # we don't really need to clear the stats for this test to work, since each
15694 # command has a unique jobid, but it makes debugging easier if needed.
15695 #       for facet in $facets; do
15696 #               local dev=$(convert_facet2label $facet)
15697 #               # clear old jobstats
15698 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
15699 #       done
15700
15701         # use a new JobID for each test, or we might see an old one
15702         [ "$JOBENV" = "FAKE_JOBID" ] &&
15703                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
15704
15705         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
15706
15707         [ "$JOBENV" = "nodelocal" ] && {
15708                 FAKE_JOBID=id.$testnum.%e.$RANDOM
15709                 $LCTL set_param jobid_name=$FAKE_JOBID
15710                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
15711         }
15712
15713         log "Test: ${cmd[*]}"
15714         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
15715
15716         if [ $JOBENV = "FAKE_JOBID" ]; then
15717                 FAKE_JOBID=$JOBVAL ${cmd[*]}
15718         else
15719                 ${cmd[*]}
15720         fi
15721
15722         # all files are created on OST0000
15723         for facet in $facets; do
15724                 local stats="*.$(convert_facet2label $facet).job_stats"
15725
15726                 # strip out libtool wrappers for in-tree executables
15727                 if [ $(do_facet $facet lctl get_param $stats |
15728                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
15729                         do_facet $facet lctl get_param $stats
15730                         error "No jobstats for $JOBVAL found on $facet::$stats"
15731                 fi
15732         done
15733 }
15734
15735 jobstats_set() {
15736         local new_jobenv=$1
15737
15738         set_persistent_param_and_check client "jobid_var" \
15739                 "$FSNAME.sys.jobid_var" $new_jobenv
15740 }
15741
15742 test_205a() { # Job stats
15743         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15744         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
15745                 skip "Need MDS version with at least 2.7.1"
15746         remote_mgs_nodsh && skip "remote MGS with nodsh"
15747         remote_mds_nodsh && skip "remote MDS with nodsh"
15748         remote_ost_nodsh && skip "remote OST with nodsh"
15749         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
15750                 skip "Server doesn't support jobstats"
15751         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
15752
15753         local old_jobenv=$($LCTL get_param -n jobid_var)
15754         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
15755
15756         if [[ $PERM_CMD == *"set_param -P"* ]]; then
15757                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
15758         else
15759                 stack_trap "do_facet mgs $PERM_CMD \
15760                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
15761         fi
15762         changelog_register
15763
15764         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
15765                                 mdt.*.job_cleanup_interval | head -n 1)
15766         local new_interval=5
15767         do_facet $SINGLEMDS \
15768                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
15769         stack_trap "do_facet $SINGLEMDS \
15770                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
15771         local start=$SECONDS
15772
15773         local cmd
15774         # mkdir
15775         cmd="mkdir $DIR/$tdir"
15776         verify_jobstats "$cmd" "$SINGLEMDS"
15777         # rmdir
15778         cmd="rmdir $DIR/$tdir"
15779         verify_jobstats "$cmd" "$SINGLEMDS"
15780         # mkdir on secondary MDT
15781         if [ $MDSCOUNT -gt 1 ]; then
15782                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
15783                 verify_jobstats "$cmd" "mds2"
15784         fi
15785         # mknod
15786         cmd="mknod $DIR/$tfile c 1 3"
15787         verify_jobstats "$cmd" "$SINGLEMDS"
15788         # unlink
15789         cmd="rm -f $DIR/$tfile"
15790         verify_jobstats "$cmd" "$SINGLEMDS"
15791         # create all files on OST0000 so verify_jobstats can find OST stats
15792         # open & close
15793         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
15794         verify_jobstats "$cmd" "$SINGLEMDS"
15795         # setattr
15796         cmd="touch $DIR/$tfile"
15797         verify_jobstats "$cmd" "$SINGLEMDS ost1"
15798         # write
15799         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
15800         verify_jobstats "$cmd" "ost1"
15801         # read
15802         cancel_lru_locks osc
15803         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
15804         verify_jobstats "$cmd" "ost1"
15805         # truncate
15806         cmd="$TRUNCATE $DIR/$tfile 0"
15807         verify_jobstats "$cmd" "$SINGLEMDS ost1"
15808         # rename
15809         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
15810         verify_jobstats "$cmd" "$SINGLEMDS"
15811         # jobstats expiry - sleep until old stats should be expired
15812         local left=$((new_interval + 5 - (SECONDS - start)))
15813         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
15814                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
15815                         "0" $left
15816         cmd="mkdir $DIR/$tdir.expire"
15817         verify_jobstats "$cmd" "$SINGLEMDS"
15818         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
15819             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
15820
15821         # Ensure that jobid are present in changelog (if supported by MDS)
15822         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
15823                 changelog_dump | tail -10
15824                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
15825                 [ $jobids -eq 9 ] ||
15826                         error "Wrong changelog jobid count $jobids != 9"
15827
15828                 # LU-5862
15829                 JOBENV="disable"
15830                 jobstats_set $JOBENV
15831                 touch $DIR/$tfile
15832                 changelog_dump | grep $tfile
15833                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
15834                 [ $jobids -eq 0 ] ||
15835                         error "Unexpected jobids when jobid_var=$JOBENV"
15836         fi
15837
15838         lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"
15839         JOBENV="JOBCOMPLEX"
15840         JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
15841
15842         verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
15843 }
15844 run_test 205a "Verify job stats"
15845
15846 # LU-13117
15847 test_205b() {
15848         $LCTL set_param jobid_var=USER jobid_name="%e.%u"
15849         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
15850         do_facet $SINGLEMDS $LCTL get_param mdt.*.job_stats |
15851                 grep job_id: | grep foolish &&
15852                         error "Unexpected jobid found"
15853         true
15854 }
15855 run_test 205b "Verify job stats jobid parsing"
15856
15857 # LU-1480, LU-1773 and LU-1657
15858 test_206() {
15859         mkdir -p $DIR/$tdir
15860         $LFS setstripe -c -1 $DIR/$tdir
15861 #define OBD_FAIL_LOV_INIT 0x1403
15862         $LCTL set_param fail_loc=0xa0001403
15863         $LCTL set_param fail_val=1
15864         touch $DIR/$tdir/$tfile || true
15865 }
15866 run_test 206 "fail lov_init_raid0() doesn't lbug"
15867
15868 test_207a() {
15869         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
15870         local fsz=`stat -c %s $DIR/$tfile`
15871         cancel_lru_locks mdc
15872
15873         # do not return layout in getattr intent
15874 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
15875         $LCTL set_param fail_loc=0x170
15876         local sz=`stat -c %s $DIR/$tfile`
15877
15878         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
15879
15880         rm -rf $DIR/$tfile
15881 }
15882 run_test 207a "can refresh layout at glimpse"
15883
15884 test_207b() {
15885         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
15886         local cksum=`md5sum $DIR/$tfile`
15887         local fsz=`stat -c %s $DIR/$tfile`
15888         cancel_lru_locks mdc
15889         cancel_lru_locks osc
15890
15891         # do not return layout in getattr intent
15892 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
15893         $LCTL set_param fail_loc=0x171
15894
15895         # it will refresh layout after the file is opened but before read issues
15896         echo checksum is "$cksum"
15897         echo "$cksum" |md5sum -c --quiet || error "file differs"
15898
15899         rm -rf $DIR/$tfile
15900 }
15901 run_test 207b "can refresh layout at open"
15902
15903 test_208() {
15904         # FIXME: in this test suite, only RD lease is used. This is okay
15905         # for now as only exclusive open is supported. After generic lease
15906         # is done, this test suite should be revised. - Jinshan
15907
15908         remote_mds_nodsh && skip "remote MDS with nodsh"
15909         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
15910                 skip "Need MDS version at least 2.4.52"
15911
15912         echo "==== test 1: verify get lease work"
15913         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
15914
15915         echo "==== test 2: verify lease can be broken by upcoming open"
15916         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
15917         local PID=$!
15918         sleep 1
15919
15920         $MULTIOP $DIR/$tfile oO_RDONLY:c
15921         kill -USR1 $PID && wait $PID || error "break lease error"
15922
15923         echo "==== test 3: verify lease can't be granted if an open already exists"
15924         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
15925         local PID=$!
15926         sleep 1
15927
15928         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
15929         kill -USR1 $PID && wait $PID || error "open file error"
15930
15931         echo "==== test 4: lease can sustain over recovery"
15932         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
15933         PID=$!
15934         sleep 1
15935
15936         fail mds1
15937
15938         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
15939
15940         echo "==== test 5: lease broken can't be regained by replay"
15941         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
15942         PID=$!
15943         sleep 1
15944
15945         # open file to break lease and then recovery
15946         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
15947         fail mds1
15948
15949         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
15950
15951         rm -f $DIR/$tfile
15952 }
15953 run_test 208 "Exclusive open"
15954
15955 test_209() {
15956         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
15957                 skip_env "must have disp_stripe"
15958
15959         touch $DIR/$tfile
15960         sync; sleep 5; sync;
15961
15962         echo 3 > /proc/sys/vm/drop_caches
15963         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
15964
15965         # open/close 500 times
15966         for i in $(seq 500); do
15967                 cat $DIR/$tfile
15968         done
15969
15970         echo 3 > /proc/sys/vm/drop_caches
15971         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
15972
15973         echo "before: $req_before, after: $req_after"
15974         [ $((req_after - req_before)) -ge 300 ] &&
15975                 error "open/close requests are not freed"
15976         return 0
15977 }
15978 run_test 209 "read-only open/close requests should be freed promptly"
15979
15980 test_212() {
15981         size=`date +%s`
15982         size=$((size % 8192 + 1))
15983         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
15984         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
15985         rm -f $DIR/f212 $DIR/f212.xyz
15986 }
15987 run_test 212 "Sendfile test ============================================"
15988
15989 test_213() {
15990         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
15991         cancel_lru_locks osc
15992         lctl set_param fail_loc=0x8000040f
15993         # generate a read lock
15994         cat $DIR/$tfile > /dev/null
15995         # write to the file, it will try to cancel the above read lock.
15996         cat /etc/hosts >> $DIR/$tfile
15997 }
15998 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
15999
16000 test_214() { # for bug 20133
16001         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
16002         for (( i=0; i < 340; i++ )) ; do
16003                 touch $DIR/$tdir/d214c/a$i
16004         done
16005
16006         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
16007         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
16008         ls $DIR/d214c || error "ls $DIR/d214c failed"
16009         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
16010         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
16011 }
16012 run_test 214 "hash-indexed directory test - bug 20133"
16013
16014 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
16015 create_lnet_proc_files() {
16016         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
16017 }
16018
16019 # counterpart of create_lnet_proc_files
16020 remove_lnet_proc_files() {
16021         rm -f $TMP/lnet_$1.sys
16022 }
16023
16024 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
16025 # 3rd arg as regexp for body
16026 check_lnet_proc_stats() {
16027         local l=$(cat "$TMP/lnet_$1" |wc -l)
16028         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
16029
16030         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
16031 }
16032
16033 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
16034 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
16035 # optional and can be regexp for 2nd line (lnet.routes case)
16036 check_lnet_proc_entry() {
16037         local blp=2          # blp stands for 'position of 1st line of body'
16038         [ -z "$5" ] || blp=3 # lnet.routes case
16039
16040         local l=$(cat "$TMP/lnet_$1" |wc -l)
16041         # subtracting one from $blp because the body can be empty
16042         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
16043
16044         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
16045                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
16046
16047         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
16048                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
16049
16050         # bail out if any unexpected line happened
16051         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
16052         [ "$?" != 0 ] || error "$2 misformatted"
16053 }
16054
16055 test_215() { # for bugs 18102, 21079, 21517
16056         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16057
16058         local N='(0|[1-9][0-9]*)'       # non-negative numeric
16059         local P='[1-9][0-9]*'           # positive numeric
16060         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
16061         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
16062         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
16063         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
16064
16065         local L1 # regexp for 1st line
16066         local L2 # regexp for 2nd line (optional)
16067         local BR # regexp for the rest (body)
16068
16069         # lnet.stats should look as 11 space-separated non-negative numerics
16070         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
16071         create_lnet_proc_files "stats"
16072         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
16073         remove_lnet_proc_files "stats"
16074
16075         # lnet.routes should look like this:
16076         # Routing disabled/enabled
16077         # net hops priority state router
16078         # where net is a string like tcp0, hops > 0, priority >= 0,
16079         # state is up/down,
16080         # router is a string like 192.168.1.1@tcp2
16081         L1="^Routing (disabled|enabled)$"
16082         L2="^net +hops +priority +state +router$"
16083         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
16084         create_lnet_proc_files "routes"
16085         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
16086         remove_lnet_proc_files "routes"
16087
16088         # lnet.routers should look like this:
16089         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
16090         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
16091         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
16092         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
16093         L1="^ref +rtr_ref +alive +router$"
16094         BR="^$P +$P +(up|down) +$NID$"
16095         create_lnet_proc_files "routers"
16096         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
16097         remove_lnet_proc_files "routers"
16098
16099         # lnet.peers should look like this:
16100         # nid refs state last max rtr min tx min queue
16101         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
16102         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
16103         # numeric (0 or >0 or <0), queue >= 0.
16104         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
16105         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
16106         create_lnet_proc_files "peers"
16107         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
16108         remove_lnet_proc_files "peers"
16109
16110         # lnet.buffers  should look like this:
16111         # pages count credits min
16112         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
16113         L1="^pages +count +credits +min$"
16114         BR="^ +$N +$N +$I +$I$"
16115         create_lnet_proc_files "buffers"
16116         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
16117         remove_lnet_proc_files "buffers"
16118
16119         # lnet.nis should look like this:
16120         # nid status alive refs peer rtr max tx min
16121         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
16122         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
16123         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
16124         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
16125         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
16126         create_lnet_proc_files "nis"
16127         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
16128         remove_lnet_proc_files "nis"
16129
16130         # can we successfully write to lnet.stats?
16131         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
16132 }
16133 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
16134
16135 test_216() { # bug 20317
16136         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16137         remote_ost_nodsh && skip "remote OST with nodsh"
16138
16139         local node
16140         local facets=$(get_facets OST)
16141         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16142
16143         save_lustre_params client "osc.*.contention_seconds" > $p
16144         save_lustre_params $facets \
16145                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
16146         save_lustre_params $facets \
16147                 "ldlm.namespaces.filter-*.contended_locks" >> $p
16148         save_lustre_params $facets \
16149                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
16150         clear_stats osc.*.osc_stats
16151
16152         # agressive lockless i/o settings
16153         do_nodes $(comma_list $(osts_nodes)) \
16154                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
16155                         ldlm.namespaces.filter-*.contended_locks=0 \
16156                         ldlm.namespaces.filter-*.contention_seconds=60"
16157         lctl set_param -n osc.*.contention_seconds=60
16158
16159         $DIRECTIO write $DIR/$tfile 0 10 4096
16160         $CHECKSTAT -s 40960 $DIR/$tfile
16161
16162         # disable lockless i/o
16163         do_nodes $(comma_list $(osts_nodes)) \
16164                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
16165                         ldlm.namespaces.filter-*.contended_locks=32 \
16166                         ldlm.namespaces.filter-*.contention_seconds=0"
16167         lctl set_param -n osc.*.contention_seconds=0
16168         clear_stats osc.*.osc_stats
16169
16170         dd if=/dev/zero of=$DIR/$tfile count=0
16171         $CHECKSTAT -s 0 $DIR/$tfile
16172
16173         restore_lustre_params <$p
16174         rm -f $p
16175         rm $DIR/$tfile
16176 }
16177 run_test 216 "check lockless direct write updates file size and kms correctly"
16178
16179 test_217() { # bug 22430
16180         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16181
16182         local node
16183         local nid
16184
16185         for node in $(nodes_list); do
16186                 nid=$(host_nids_address $node $NETTYPE)
16187                 if [[ $nid = *-* ]] ; then
16188                         echo "lctl ping $(h2nettype $nid)"
16189                         lctl ping $(h2nettype $nid)
16190                 else
16191                         echo "skipping $node (no hyphen detected)"
16192                 fi
16193         done
16194 }
16195 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
16196
16197 test_218() {
16198        # do directio so as not to populate the page cache
16199        log "creating a 10 Mb file"
16200        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
16201        log "starting reads"
16202        dd if=$DIR/$tfile of=/dev/null bs=4096 &
16203        log "truncating the file"
16204        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
16205        log "killing dd"
16206        kill %+ || true # reads might have finished
16207        echo "wait until dd is finished"
16208        wait
16209        log "removing the temporary file"
16210        rm -rf $DIR/$tfile || error "tmp file removal failed"
16211 }
16212 run_test 218 "parallel read and truncate should not deadlock"
16213
16214 test_219() {
16215         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16216
16217         # write one partial page
16218         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
16219         # set no grant so vvp_io_commit_write will do sync write
16220         $LCTL set_param fail_loc=0x411
16221         # write a full page at the end of file
16222         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
16223
16224         $LCTL set_param fail_loc=0
16225         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
16226         $LCTL set_param fail_loc=0x411
16227         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
16228
16229         # LU-4201
16230         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
16231         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
16232 }
16233 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
16234
16235 test_220() { #LU-325
16236         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16237         remote_ost_nodsh && skip "remote OST with nodsh"
16238         remote_mds_nodsh && skip "remote MDS with nodsh"
16239         remote_mgs_nodsh && skip "remote MGS with nodsh"
16240
16241         local OSTIDX=0
16242
16243         # create on MDT0000 so the last_id and next_id are correct
16244         mkdir $DIR/$tdir
16245         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
16246         OST=${OST%_UUID}
16247
16248         # on the mdt's osc
16249         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
16250         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
16251                         osp.$mdtosc_proc1.prealloc_last_id)
16252         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
16253                         osp.$mdtosc_proc1.prealloc_next_id)
16254
16255         $LFS df -i
16256
16257         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
16258         #define OBD_FAIL_OST_ENOINO              0x229
16259         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
16260         create_pool $FSNAME.$TESTNAME || return 1
16261         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
16262
16263         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
16264
16265         MDSOBJS=$((last_id - next_id))
16266         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
16267
16268         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
16269         echo "OST still has $count kbytes free"
16270
16271         echo "create $MDSOBJS files @next_id..."
16272         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
16273
16274         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
16275                         osp.$mdtosc_proc1.prealloc_last_id)
16276         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
16277                         osp.$mdtosc_proc1.prealloc_next_id)
16278
16279         echo "after creation, last_id=$last_id2, next_id=$next_id2"
16280         $LFS df -i
16281
16282         echo "cleanup..."
16283
16284         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
16285         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
16286
16287         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
16288                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
16289         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
16290                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
16291         echo "unlink $MDSOBJS files @$next_id..."
16292         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
16293 }
16294 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
16295
16296 test_221() {
16297         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16298
16299         dd if=`which date` of=$MOUNT/date oflag=sync
16300         chmod +x $MOUNT/date
16301
16302         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
16303         $LCTL set_param fail_loc=0x80001401
16304
16305         $MOUNT/date > /dev/null
16306         rm -f $MOUNT/date
16307 }
16308 run_test 221 "make sure fault and truncate race to not cause OOM"
16309
16310 test_222a () {
16311         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16312
16313         rm -rf $DIR/$tdir
16314         test_mkdir $DIR/$tdir
16315         $LFS setstripe -c 1 -i 0 $DIR/$tdir
16316         createmany -o $DIR/$tdir/$tfile 10
16317         cancel_lru_locks mdc
16318         cancel_lru_locks osc
16319         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
16320         $LCTL set_param fail_loc=0x31a
16321         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
16322         $LCTL set_param fail_loc=0
16323         rm -r $DIR/$tdir
16324 }
16325 run_test 222a "AGL for ls should not trigger CLIO lock failure"
16326
16327 test_222b () {
16328         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16329
16330         rm -rf $DIR/$tdir
16331         test_mkdir $DIR/$tdir
16332         $LFS setstripe -c 1 -i 0 $DIR/$tdir
16333         createmany -o $DIR/$tdir/$tfile 10
16334         cancel_lru_locks mdc
16335         cancel_lru_locks osc
16336         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
16337         $LCTL set_param fail_loc=0x31a
16338         rm -r $DIR/$tdir || error "AGL for rmdir failed"
16339         $LCTL set_param fail_loc=0
16340 }
16341 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
16342
16343 test_223 () {
16344         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16345
16346         rm -rf $DIR/$tdir
16347         test_mkdir $DIR/$tdir
16348         $LFS setstripe -c 1 -i 0 $DIR/$tdir
16349         createmany -o $DIR/$tdir/$tfile 10
16350         cancel_lru_locks mdc
16351         cancel_lru_locks osc
16352         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
16353         $LCTL set_param fail_loc=0x31b
16354         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
16355         $LCTL set_param fail_loc=0
16356         rm -r $DIR/$tdir
16357 }
16358 run_test 223 "osc reenqueue if without AGL lock granted ======================="
16359
16360 test_224a() { # LU-1039, MRP-303
16361         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16362
16363         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
16364         $LCTL set_param fail_loc=0x508
16365         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
16366         $LCTL set_param fail_loc=0
16367         df $DIR
16368 }
16369 run_test 224a "Don't panic on bulk IO failure"
16370
16371 test_224b() { # LU-1039, MRP-303
16372         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16373
16374         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
16375         cancel_lru_locks osc
16376         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
16377         $LCTL set_param fail_loc=0x515
16378         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
16379         $LCTL set_param fail_loc=0
16380         df $DIR
16381 }
16382 run_test 224b "Don't panic on bulk IO failure"
16383
16384 test_224c() { # LU-6441
16385         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16386         remote_mds_nodsh && skip "remote MDS with nodsh"
16387
16388         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16389         save_writethrough $p
16390         set_cache writethrough on
16391
16392         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
16393         local at_max=$($LCTL get_param -n at_max)
16394         local timeout=$($LCTL get_param -n timeout)
16395         local test_at="at_max"
16396         local param_at="$FSNAME.sys.at_max"
16397         local test_timeout="timeout"
16398         local param_timeout="$FSNAME.sys.timeout"
16399
16400         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
16401
16402         set_persistent_param_and_check client "$test_at" "$param_at" 0
16403         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
16404
16405         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
16406         do_facet ost1 "$LCTL set_param fail_loc=0x520"
16407         $LFS setstripe -c 1 -i 0 $DIR/$tfile
16408         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
16409         sync
16410         do_facet ost1 "$LCTL set_param fail_loc=0"
16411
16412         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
16413         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
16414                 $timeout
16415
16416         $LCTL set_param -n $pages_per_rpc
16417         restore_lustre_params < $p
16418         rm -f $p
16419 }
16420 run_test 224c "Don't hang if one of md lost during large bulk RPC"
16421
16422 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
16423 test_225a () {
16424         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16425         if [ -z ${MDSSURVEY} ]; then
16426                 skip_env "mds-survey not found"
16427         fi
16428         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
16429                 skip "Need MDS version at least 2.2.51"
16430
16431         local mds=$(facet_host $SINGLEMDS)
16432         local target=$(do_nodes $mds 'lctl dl' |
16433                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
16434
16435         local cmd1="file_count=1000 thrhi=4"
16436         local cmd2="dir_count=2 layer=mdd stripe_count=0"
16437         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
16438         local cmd="$cmd1 $cmd2 $cmd3"
16439
16440         rm -f ${TMP}/mds_survey*
16441         echo + $cmd
16442         eval $cmd || error "mds-survey with zero-stripe failed"
16443         cat ${TMP}/mds_survey*
16444         rm -f ${TMP}/mds_survey*
16445 }
16446 run_test 225a "Metadata survey sanity with zero-stripe"
16447
16448 test_225b () {
16449         if [ -z ${MDSSURVEY} ]; then
16450                 skip_env "mds-survey not found"
16451         fi
16452         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
16453                 skip "Need MDS version at least 2.2.51"
16454         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16455         remote_mds_nodsh && skip "remote MDS with nodsh"
16456         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
16457                 skip_env "Need to mount OST to test"
16458         fi
16459
16460         local mds=$(facet_host $SINGLEMDS)
16461         local target=$(do_nodes $mds 'lctl dl' |
16462                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
16463
16464         local cmd1="file_count=1000 thrhi=4"
16465         local cmd2="dir_count=2 layer=mdd stripe_count=1"
16466         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
16467         local cmd="$cmd1 $cmd2 $cmd3"
16468
16469         rm -f ${TMP}/mds_survey*
16470         echo + $cmd
16471         eval $cmd || error "mds-survey with stripe_count failed"
16472         cat ${TMP}/mds_survey*
16473         rm -f ${TMP}/mds_survey*
16474 }
16475 run_test 225b "Metadata survey sanity with stripe_count = 1"
16476
16477 mcreate_path2fid () {
16478         local mode=$1
16479         local major=$2
16480         local minor=$3
16481         local name=$4
16482         local desc=$5
16483         local path=$DIR/$tdir/$name
16484         local fid
16485         local rc
16486         local fid_path
16487
16488         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
16489                 error "cannot create $desc"
16490
16491         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
16492         rc=$?
16493         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
16494
16495         fid_path=$($LFS fid2path $MOUNT $fid)
16496         rc=$?
16497         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
16498
16499         [ "$path" == "$fid_path" ] ||
16500                 error "fid2path returned $fid_path, expected $path"
16501
16502         echo "pass with $path and $fid"
16503 }
16504
16505 test_226a () {
16506         rm -rf $DIR/$tdir
16507         mkdir -p $DIR/$tdir
16508
16509         mcreate_path2fid 0010666 0 0 fifo "FIFO"
16510         mcreate_path2fid 0020666 1 3 null "character special file (null)"
16511         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
16512         mcreate_path2fid 0040666 0 0 dir "directory"
16513         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
16514         mcreate_path2fid 0100666 0 0 file "regular file"
16515         mcreate_path2fid 0120666 0 0 link "symbolic link"
16516         mcreate_path2fid 0140666 0 0 sock "socket"
16517 }
16518 run_test 226a "call path2fid and fid2path on files of all type"
16519
16520 test_226b () {
16521         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16522
16523         local MDTIDX=1
16524
16525         rm -rf $DIR/$tdir
16526         mkdir -p $DIR/$tdir
16527         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
16528                 error "create remote directory failed"
16529         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
16530         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
16531                                 "character special file (null)"
16532         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
16533                                 "character special file (no device)"
16534         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
16535         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
16536                                 "block special file (loop)"
16537         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
16538         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
16539         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
16540 }
16541 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
16542
16543 # LU-1299 Executing or running ldd on a truncated executable does not
16544 # cause an out-of-memory condition.
16545 test_227() {
16546         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16547         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
16548
16549         dd if=$(which date) of=$MOUNT/date bs=1k count=1
16550         chmod +x $MOUNT/date
16551
16552         $MOUNT/date > /dev/null
16553         ldd $MOUNT/date > /dev/null
16554         rm -f $MOUNT/date
16555 }
16556 run_test 227 "running truncated executable does not cause OOM"
16557
16558 # LU-1512 try to reuse idle OI blocks
16559 test_228a() {
16560         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16561         remote_mds_nodsh && skip "remote MDS with nodsh"
16562         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
16563
16564         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
16565         local myDIR=$DIR/$tdir
16566
16567         mkdir -p $myDIR
16568         #define OBD_FAIL_SEQ_EXHAUST             0x1002
16569         $LCTL set_param fail_loc=0x80001002
16570         createmany -o $myDIR/t- 10000
16571         $LCTL set_param fail_loc=0
16572         # The guard is current the largest FID holder
16573         touch $myDIR/guard
16574         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
16575                     tr -d '[')
16576         local IDX=$(($SEQ % 64))
16577
16578         do_facet $SINGLEMDS sync
16579         # Make sure journal flushed.
16580         sleep 6
16581         local blk1=$(do_facet $SINGLEMDS \
16582                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16583                      grep Blockcount | awk '{print $4}')
16584
16585         # Remove old files, some OI blocks will become idle.
16586         unlinkmany $myDIR/t- 10000
16587         # Create new files, idle OI blocks should be reused.
16588         createmany -o $myDIR/t- 2000
16589         do_facet $SINGLEMDS sync
16590         # Make sure journal flushed.
16591         sleep 6
16592         local blk2=$(do_facet $SINGLEMDS \
16593                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16594                      grep Blockcount | awk '{print $4}')
16595
16596         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
16597 }
16598 run_test 228a "try to reuse idle OI blocks"
16599
16600 test_228b() {
16601         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16602         remote_mds_nodsh && skip "remote MDS with nodsh"
16603         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
16604
16605         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
16606         local myDIR=$DIR/$tdir
16607
16608         mkdir -p $myDIR
16609         #define OBD_FAIL_SEQ_EXHAUST             0x1002
16610         $LCTL set_param fail_loc=0x80001002
16611         createmany -o $myDIR/t- 10000
16612         $LCTL set_param fail_loc=0
16613         # The guard is current the largest FID holder
16614         touch $myDIR/guard
16615         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
16616                     tr -d '[')
16617         local IDX=$(($SEQ % 64))
16618
16619         do_facet $SINGLEMDS sync
16620         # Make sure journal flushed.
16621         sleep 6
16622         local blk1=$(do_facet $SINGLEMDS \
16623                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16624                      grep Blockcount | awk '{print $4}')
16625
16626         # Remove old files, some OI blocks will become idle.
16627         unlinkmany $myDIR/t- 10000
16628
16629         # stop the MDT
16630         stop $SINGLEMDS || error "Fail to stop MDT."
16631         # remount the MDT
16632         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
16633
16634         df $MOUNT || error "Fail to df."
16635         # Create new files, idle OI blocks should be reused.
16636         createmany -o $myDIR/t- 2000
16637         do_facet $SINGLEMDS sync
16638         # Make sure journal flushed.
16639         sleep 6
16640         local blk2=$(do_facet $SINGLEMDS \
16641                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16642                      grep Blockcount | awk '{print $4}')
16643
16644         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
16645 }
16646 run_test 228b "idle OI blocks can be reused after MDT restart"
16647
16648 #LU-1881
16649 test_228c() {
16650         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16651         remote_mds_nodsh && skip "remote MDS with nodsh"
16652         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
16653
16654         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
16655         local myDIR=$DIR/$tdir
16656
16657         mkdir -p $myDIR
16658         #define OBD_FAIL_SEQ_EXHAUST             0x1002
16659         $LCTL set_param fail_loc=0x80001002
16660         # 20000 files can guarantee there are index nodes in the OI file
16661         createmany -o $myDIR/t- 20000
16662         $LCTL set_param fail_loc=0
16663         # The guard is current the largest FID holder
16664         touch $myDIR/guard
16665         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
16666                     tr -d '[')
16667         local IDX=$(($SEQ % 64))
16668
16669         do_facet $SINGLEMDS sync
16670         # Make sure journal flushed.
16671         sleep 6
16672         local blk1=$(do_facet $SINGLEMDS \
16673                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16674                      grep Blockcount | awk '{print $4}')
16675
16676         # Remove old files, some OI blocks will become idle.
16677         unlinkmany $myDIR/t- 20000
16678         rm -f $myDIR/guard
16679         # The OI file should become empty now
16680
16681         # Create new files, idle OI blocks should be reused.
16682         createmany -o $myDIR/t- 2000
16683         do_facet $SINGLEMDS sync
16684         # Make sure journal flushed.
16685         sleep 6
16686         local blk2=$(do_facet $SINGLEMDS \
16687                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16688                      grep Blockcount | awk '{print $4}')
16689
16690         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
16691 }
16692 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
16693
16694 test_229() { # LU-2482, LU-3448
16695         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16696         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
16697         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
16698                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
16699
16700         rm -f $DIR/$tfile
16701
16702         # Create a file with a released layout and stripe count 2.
16703         $MULTIOP $DIR/$tfile H2c ||
16704                 error "failed to create file with released layout"
16705
16706         $LFS getstripe -v $DIR/$tfile
16707
16708         local pattern=$($LFS getstripe -L $DIR/$tfile)
16709         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
16710
16711         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
16712                 error "getstripe"
16713         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
16714         stat $DIR/$tfile || error "failed to stat released file"
16715
16716         chown $RUNAS_ID $DIR/$tfile ||
16717                 error "chown $RUNAS_ID $DIR/$tfile failed"
16718
16719         chgrp $RUNAS_ID $DIR/$tfile ||
16720                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
16721
16722         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
16723         rm $DIR/$tfile || error "failed to remove released file"
16724 }
16725 run_test 229 "getstripe/stat/rm/attr changes work on released files"
16726
16727 test_230a() {
16728         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16729         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16730         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16731                 skip "Need MDS version at least 2.11.52"
16732
16733         local MDTIDX=1
16734
16735         test_mkdir $DIR/$tdir
16736         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
16737         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
16738         [ $mdt_idx -ne 0 ] &&
16739                 error "create local directory on wrong MDT $mdt_idx"
16740
16741         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
16742                         error "create remote directory failed"
16743         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
16744         [ $mdt_idx -ne $MDTIDX ] &&
16745                 error "create remote directory on wrong MDT $mdt_idx"
16746
16747         createmany -o $DIR/$tdir/test_230/t- 10 ||
16748                 error "create files on remote directory failed"
16749         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
16750         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
16751         rm -r $DIR/$tdir || error "unlink remote directory failed"
16752 }
16753 run_test 230a "Create remote directory and files under the remote directory"
16754
16755 test_230b() {
16756         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16757         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16758         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16759                 skip "Need MDS version at least 2.11.52"
16760
16761         local MDTIDX=1
16762         local mdt_index
16763         local i
16764         local file
16765         local pid
16766         local stripe_count
16767         local migrate_dir=$DIR/$tdir/migrate_dir
16768         local other_dir=$DIR/$tdir/other_dir
16769
16770         test_mkdir $DIR/$tdir
16771         test_mkdir -i0 -c1 $migrate_dir
16772         test_mkdir -i0 -c1 $other_dir
16773         for ((i=0; i<10; i++)); do
16774                 mkdir -p $migrate_dir/dir_${i}
16775                 createmany -o $migrate_dir/dir_${i}/f 10 ||
16776                         error "create files under remote dir failed $i"
16777         done
16778
16779         cp /etc/passwd $migrate_dir/$tfile
16780         cp /etc/passwd $other_dir/$tfile
16781         chattr +SAD $migrate_dir
16782         chattr +SAD $migrate_dir/$tfile
16783
16784         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
16785         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
16786         local old_dir_mode=$(stat -c%f $migrate_dir)
16787         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
16788
16789         mkdir -p $migrate_dir/dir_default_stripe2
16790         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
16791         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
16792
16793         mkdir -p $other_dir
16794         ln $migrate_dir/$tfile $other_dir/luna
16795         ln $migrate_dir/$tfile $migrate_dir/sofia
16796         ln $other_dir/$tfile $migrate_dir/david
16797         ln -s $migrate_dir/$tfile $other_dir/zachary
16798         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
16799         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
16800
16801         local len
16802         local lnktgt
16803
16804         # inline symlink
16805         for len in 58 59 60; do
16806                 lnktgt=$(str_repeat 'l' $len)
16807                 touch $migrate_dir/$lnktgt
16808                 ln -s $lnktgt $migrate_dir/${len}char_ln
16809         done
16810
16811         # PATH_MAX
16812         for len in 4094 4095; do
16813                 lnktgt=$(str_repeat 'l' $len)
16814                 ln -s $lnktgt $migrate_dir/${len}char_ln
16815         done
16816
16817         # NAME_MAX
16818         for len in 254 255; do
16819                 touch $migrate_dir/$(str_repeat 'l' $len)
16820         done
16821
16822         $LFS migrate -m $MDTIDX $migrate_dir ||
16823                 error "fails on migrating remote dir to MDT1"
16824
16825         echo "migratate to MDT1, then checking.."
16826         for ((i = 0; i < 10; i++)); do
16827                 for file in $(find $migrate_dir/dir_${i}); do
16828                         mdt_index=$($LFS getstripe -m $file)
16829                         # broken symlink getstripe will fail
16830                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
16831                                 error "$file is not on MDT${MDTIDX}"
16832                 done
16833         done
16834
16835         # the multiple link file should still in MDT0
16836         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
16837         [ $mdt_index == 0 ] ||
16838                 error "$file is not on MDT${MDTIDX}"
16839
16840         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
16841         [ "$old_dir_flag" = "$new_dir_flag" ] ||
16842                 error " expect $old_dir_flag get $new_dir_flag"
16843
16844         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
16845         [ "$old_file_flag" = "$new_file_flag" ] ||
16846                 error " expect $old_file_flag get $new_file_flag"
16847
16848         local new_dir_mode=$(stat -c%f $migrate_dir)
16849         [ "$old_dir_mode" = "$new_dir_mode" ] ||
16850                 error "expect mode $old_dir_mode get $new_dir_mode"
16851
16852         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
16853         [ "$old_file_mode" = "$new_file_mode" ] ||
16854                 error "expect mode $old_file_mode get $new_file_mode"
16855
16856         diff /etc/passwd $migrate_dir/$tfile ||
16857                 error "$tfile different after migration"
16858
16859         diff /etc/passwd $other_dir/luna ||
16860                 error "luna different after migration"
16861
16862         diff /etc/passwd $migrate_dir/sofia ||
16863                 error "sofia different after migration"
16864
16865         diff /etc/passwd $migrate_dir/david ||
16866                 error "david different after migration"
16867
16868         diff /etc/passwd $other_dir/zachary ||
16869                 error "zachary different after migration"
16870
16871         diff /etc/passwd $migrate_dir/${tfile}_ln ||
16872                 error "${tfile}_ln different after migration"
16873
16874         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
16875                 error "${tfile}_ln_other different after migration"
16876
16877         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
16878         [ $stripe_count = 2 ] ||
16879                 error "dir strpe_count $d != 2 after migration."
16880
16881         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
16882         [ $stripe_count = 2 ] ||
16883                 error "file strpe_count $d != 2 after migration."
16884
16885         #migrate back to MDT0
16886         MDTIDX=0
16887
16888         $LFS migrate -m $MDTIDX $migrate_dir ||
16889                 error "fails on migrating remote dir to MDT0"
16890
16891         echo "migrate back to MDT0, checking.."
16892         for file in $(find $migrate_dir); do
16893                 mdt_index=$($LFS getstripe -m $file)
16894                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
16895                         error "$file is not on MDT${MDTIDX}"
16896         done
16897
16898         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
16899         [ "$old_dir_flag" = "$new_dir_flag" ] ||
16900                 error " expect $old_dir_flag get $new_dir_flag"
16901
16902         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
16903         [ "$old_file_flag" = "$new_file_flag" ] ||
16904                 error " expect $old_file_flag get $new_file_flag"
16905
16906         local new_dir_mode=$(stat -c%f $migrate_dir)
16907         [ "$old_dir_mode" = "$new_dir_mode" ] ||
16908                 error "expect mode $old_dir_mode get $new_dir_mode"
16909
16910         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
16911         [ "$old_file_mode" = "$new_file_mode" ] ||
16912                 error "expect mode $old_file_mode get $new_file_mode"
16913
16914         diff /etc/passwd ${migrate_dir}/$tfile ||
16915                 error "$tfile different after migration"
16916
16917         diff /etc/passwd ${other_dir}/luna ||
16918                 error "luna different after migration"
16919
16920         diff /etc/passwd ${migrate_dir}/sofia ||
16921                 error "sofia different after migration"
16922
16923         diff /etc/passwd ${other_dir}/zachary ||
16924                 error "zachary different after migration"
16925
16926         diff /etc/passwd $migrate_dir/${tfile}_ln ||
16927                 error "${tfile}_ln different after migration"
16928
16929         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
16930                 error "${tfile}_ln_other different after migration"
16931
16932         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
16933         [ $stripe_count = 2 ] ||
16934                 error "dir strpe_count $d != 2 after migration."
16935
16936         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
16937         [ $stripe_count = 2 ] ||
16938                 error "file strpe_count $d != 2 after migration."
16939
16940         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16941 }
16942 run_test 230b "migrate directory"
16943
16944 test_230c() {
16945         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16946         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16947         remote_mds_nodsh && skip "remote MDS with nodsh"
16948         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16949                 skip "Need MDS version at least 2.11.52"
16950
16951         local MDTIDX=1
16952         local total=3
16953         local mdt_index
16954         local file
16955         local migrate_dir=$DIR/$tdir/migrate_dir
16956
16957         #If migrating directory fails in the middle, all entries of
16958         #the directory is still accessiable.
16959         test_mkdir $DIR/$tdir
16960         test_mkdir -i0 -c1 $migrate_dir
16961         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
16962         stat $migrate_dir
16963         createmany -o $migrate_dir/f $total ||
16964                 error "create files under ${migrate_dir} failed"
16965
16966         # fail after migrating top dir, and this will fail only once, so the
16967         # first sub file migration will fail (currently f3), others succeed.
16968         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
16969         do_facet mds1 lctl set_param fail_loc=0x1801
16970         local t=$(ls $migrate_dir | wc -l)
16971         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
16972                 error "migrate should fail"
16973         local u=$(ls $migrate_dir | wc -l)
16974         [ "$u" == "$t" ] || error "$u != $t during migration"
16975
16976         # add new dir/file should succeed
16977         mkdir $migrate_dir/dir ||
16978                 error "mkdir failed under migrating directory"
16979         touch $migrate_dir/file ||
16980                 error "create file failed under migrating directory"
16981
16982         # add file with existing name should fail
16983         for file in $migrate_dir/f*; do
16984                 stat $file > /dev/null || error "stat $file failed"
16985                 $OPENFILE -f O_CREAT:O_EXCL $file &&
16986                         error "open(O_CREAT|O_EXCL) $file should fail"
16987                 $MULTIOP $file m && error "create $file should fail"
16988                 touch $DIR/$tdir/remote_dir/$tfile ||
16989                         error "touch $tfile failed"
16990                 ln $DIR/$tdir/remote_dir/$tfile $file &&
16991                         error "link $file should fail"
16992                 mdt_index=$($LFS getstripe -m $file)
16993                 if [ $mdt_index == 0 ]; then
16994                         # file failed to migrate is not allowed to rename to
16995                         mv $DIR/$tdir/remote_dir/$tfile $file &&
16996                                 error "rename to $file should fail"
16997                 else
16998                         mv $DIR/$tdir/remote_dir/$tfile $file ||
16999                                 error "rename to $file failed"
17000                 fi
17001                 echo hello >> $file || error "write $file failed"
17002         done
17003
17004         # resume migration with different options should fail
17005         $LFS migrate -m 0 $migrate_dir &&
17006                 error "migrate -m 0 $migrate_dir should fail"
17007
17008         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
17009                 error "migrate -c 2 $migrate_dir should fail"
17010
17011         # resume migration should succeed
17012         $LFS migrate -m $MDTIDX $migrate_dir ||
17013                 error "migrate $migrate_dir failed"
17014
17015         echo "Finish migration, then checking.."
17016         for file in $(find $migrate_dir); do
17017                 mdt_index=$($LFS getstripe -m $file)
17018                 [ $mdt_index == $MDTIDX ] ||
17019                         error "$file is not on MDT${MDTIDX}"
17020         done
17021
17022         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17023 }
17024 run_test 230c "check directory accessiblity if migration failed"
17025
17026 test_230d() {
17027         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17028         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17029         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17030                 skip "Need MDS version at least 2.11.52"
17031         # LU-11235
17032         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
17033
17034         local migrate_dir=$DIR/$tdir/migrate_dir
17035         local old_index
17036         local new_index
17037         local old_count
17038         local new_count
17039         local new_hash
17040         local mdt_index
17041         local i
17042         local j
17043
17044         old_index=$((RANDOM % MDSCOUNT))
17045         old_count=$((MDSCOUNT - old_index))
17046         new_index=$((RANDOM % MDSCOUNT))
17047         new_count=$((MDSCOUNT - new_index))
17048         new_hash=1 # for all_char
17049
17050         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
17051         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
17052
17053         test_mkdir $DIR/$tdir
17054         test_mkdir -i $old_index -c $old_count $migrate_dir
17055
17056         for ((i=0; i<100; i++)); do
17057                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
17058                 createmany -o $migrate_dir/dir_${i}/f 100 ||
17059                         error "create files under remote dir failed $i"
17060         done
17061
17062         echo -n "Migrate from MDT$old_index "
17063         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
17064         echo -n "to MDT$new_index"
17065         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
17066         echo
17067
17068         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
17069         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
17070                 error "migrate remote dir error"
17071
17072         echo "Finish migration, then checking.."
17073         for file in $(find $migrate_dir); do
17074                 mdt_index=$($LFS getstripe -m $file)
17075                 if [ $mdt_index -lt $new_index ] ||
17076                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
17077                         error "$file is on MDT$mdt_index"
17078                 fi
17079         done
17080
17081         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17082 }
17083 run_test 230d "check migrate big directory"
17084
17085 test_230e() {
17086         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17087         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17088         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17089                 skip "Need MDS version at least 2.11.52"
17090
17091         local i
17092         local j
17093         local a_fid
17094         local b_fid
17095
17096         mkdir -p $DIR/$tdir
17097         mkdir $DIR/$tdir/migrate_dir
17098         mkdir $DIR/$tdir/other_dir
17099         touch $DIR/$tdir/migrate_dir/a
17100         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
17101         ls $DIR/$tdir/other_dir
17102
17103         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
17104                 error "migrate dir fails"
17105
17106         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
17107         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
17108
17109         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17110         [ $mdt_index == 0 ] || error "a is not on MDT0"
17111
17112         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
17113                 error "migrate dir fails"
17114
17115         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
17116         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
17117
17118         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17119         [ $mdt_index == 1 ] || error "a is not on MDT1"
17120
17121         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
17122         [ $mdt_index == 1 ] || error "b is not on MDT1"
17123
17124         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
17125         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
17126
17127         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
17128
17129         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17130 }
17131 run_test 230e "migrate mulitple local link files"
17132
17133 test_230f() {
17134         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17135         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17136         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17137                 skip "Need MDS version at least 2.11.52"
17138
17139         local a_fid
17140         local ln_fid
17141
17142         mkdir -p $DIR/$tdir
17143         mkdir $DIR/$tdir/migrate_dir
17144         $LFS mkdir -i1 $DIR/$tdir/other_dir
17145         touch $DIR/$tdir/migrate_dir/a
17146         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
17147         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
17148         ls $DIR/$tdir/other_dir
17149
17150         # a should be migrated to MDT1, since no other links on MDT0
17151         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
17152                 error "#1 migrate dir fails"
17153         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
17154         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
17155         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17156         [ $mdt_index == 1 ] || error "a is not on MDT1"
17157
17158         # a should stay on MDT1, because it is a mulitple link file
17159         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
17160                 error "#2 migrate dir fails"
17161         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17162         [ $mdt_index == 1 ] || error "a is not on MDT1"
17163
17164         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
17165                 error "#3 migrate dir fails"
17166
17167         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
17168         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
17169         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
17170
17171         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
17172         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
17173
17174         # a should be migrated to MDT0, since no other links on MDT1
17175         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
17176                 error "#4 migrate dir fails"
17177         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17178         [ $mdt_index == 0 ] || error "a is not on MDT0"
17179
17180         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17181 }
17182 run_test 230f "migrate mulitple remote link files"
17183
17184 test_230g() {
17185         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17186         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17187         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17188                 skip "Need MDS version at least 2.11.52"
17189
17190         mkdir -p $DIR/$tdir/migrate_dir
17191
17192         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
17193                 error "migrating dir to non-exist MDT succeeds"
17194         true
17195 }
17196 run_test 230g "migrate dir to non-exist MDT"
17197
17198 test_230h() {
17199         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17200         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17201         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17202                 skip "Need MDS version at least 2.11.52"
17203
17204         local mdt_index
17205
17206         mkdir -p $DIR/$tdir/migrate_dir
17207
17208         $LFS migrate -m1 $DIR &&
17209                 error "migrating mountpoint1 should fail"
17210
17211         $LFS migrate -m1 $DIR/$tdir/.. &&
17212                 error "migrating mountpoint2 should fail"
17213
17214         # same as mv
17215         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
17216                 error "migrating $tdir/migrate_dir/.. should fail"
17217
17218         true
17219 }
17220 run_test 230h "migrate .. and root"
17221
17222 test_230i() {
17223         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17224         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17225         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17226                 skip "Need MDS version at least 2.11.52"
17227
17228         mkdir -p $DIR/$tdir/migrate_dir
17229
17230         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
17231                 error "migration fails with a tailing slash"
17232
17233         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
17234                 error "migration fails with two tailing slashes"
17235 }
17236 run_test 230i "lfs migrate -m tolerates trailing slashes"
17237
17238 test_230j() {
17239         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
17240         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17241                 skip "Need MDS version at least 2.11.52"
17242
17243         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
17244         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
17245                 error "create $tfile failed"
17246         cat /etc/passwd > $DIR/$tdir/$tfile
17247
17248         $LFS migrate -m 1 $DIR/$tdir
17249
17250         cmp /etc/passwd $DIR/$tdir/$tfile ||
17251                 error "DoM file mismatch after migration"
17252 }
17253 run_test 230j "DoM file data not changed after dir migration"
17254
17255 test_230k() {
17256         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
17257         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
17258                 skip "Need MDS version at least 2.11.56"
17259
17260         local total=20
17261         local files_on_starting_mdt=0
17262
17263         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
17264         $LFS getdirstripe $DIR/$tdir
17265         for i in $(seq $total); do
17266                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
17267                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
17268                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
17269         done
17270
17271         echo "$files_on_starting_mdt files on MDT0"
17272
17273         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
17274         $LFS getdirstripe $DIR/$tdir
17275
17276         files_on_starting_mdt=0
17277         for i in $(seq $total); do
17278                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
17279                         error "file $tfile.$i mismatch after migration"
17280                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
17281                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
17282         done
17283
17284         echo "$files_on_starting_mdt files on MDT1 after migration"
17285         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
17286
17287         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
17288         $LFS getdirstripe $DIR/$tdir
17289
17290         files_on_starting_mdt=0
17291         for i in $(seq $total); do
17292                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
17293                         error "file $tfile.$i mismatch after 2nd migration"
17294                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
17295                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
17296         done
17297
17298         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
17299         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
17300
17301         true
17302 }
17303 run_test 230k "file data not changed after dir migration"
17304
17305 test_230l() {
17306         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
17307         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
17308                 skip "Need MDS version at least 2.11.56"
17309
17310         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
17311         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
17312                 error "create files under remote dir failed $i"
17313         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
17314 }
17315 run_test 230l "readdir between MDTs won't crash"
17316
17317 test_230m() {
17318         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
17319         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
17320                 skip "Need MDS version at least 2.11.56"
17321
17322         local MDTIDX=1
17323         local mig_dir=$DIR/$tdir/migrate_dir
17324         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
17325         local shortstr="b"
17326         local val
17327
17328         echo "Creating files and dirs with xattrs"
17329         test_mkdir $DIR/$tdir
17330         test_mkdir -i0 -c1 $mig_dir
17331         mkdir $mig_dir/dir
17332         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
17333                 error "cannot set xattr attr1 on dir"
17334         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
17335                 error "cannot set xattr attr2 on dir"
17336         touch $mig_dir/dir/f0
17337         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
17338                 error "cannot set xattr attr1 on file"
17339         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
17340                 error "cannot set xattr attr2 on file"
17341         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
17342         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
17343         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
17344         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
17345         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
17346         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
17347         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
17348         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
17349         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
17350
17351         echo "Migrating to MDT1"
17352         $LFS migrate -m $MDTIDX $mig_dir ||
17353                 error "fails on migrating dir to MDT1"
17354
17355         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
17356         echo "Checking xattrs"
17357         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
17358         [ "$val" = $longstr ] ||
17359                 error "expecting xattr1 $longstr on dir, found $val"
17360         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
17361         [ "$val" = $shortstr ] ||
17362                 error "expecting xattr2 $shortstr on dir, found $val"
17363         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
17364         [ "$val" = $longstr ] ||
17365                 error "expecting xattr1 $longstr on file, found $val"
17366         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
17367         [ "$val" = $shortstr ] ||
17368                 error "expecting xattr2 $shortstr on file, found $val"
17369 }
17370 run_test 230m "xattrs not changed after dir migration"
17371
17372 test_231a()
17373 {
17374         # For simplicity this test assumes that max_pages_per_rpc
17375         # is the same across all OSCs
17376         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
17377         local bulk_size=$((max_pages * PAGE_SIZE))
17378         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
17379                                        head -n 1)
17380
17381         mkdir -p $DIR/$tdir
17382         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
17383                 error "failed to set stripe with -S ${brw_size}M option"
17384
17385         # clear the OSC stats
17386         $LCTL set_param osc.*.stats=0 &>/dev/null
17387         stop_writeback
17388
17389         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
17390         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
17391                 oflag=direct &>/dev/null || error "dd failed"
17392
17393         sync; sleep 1; sync # just to be safe
17394         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
17395         if [ x$nrpcs != "x1" ]; then
17396                 $LCTL get_param osc.*.stats
17397                 error "found $nrpcs ost_write RPCs, not 1 as expected"
17398         fi
17399
17400         start_writeback
17401         # Drop the OSC cache, otherwise we will read from it
17402         cancel_lru_locks osc
17403
17404         # clear the OSC stats
17405         $LCTL set_param osc.*.stats=0 &>/dev/null
17406
17407         # Client reads $bulk_size.
17408         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
17409                 iflag=direct &>/dev/null || error "dd failed"
17410
17411         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
17412         if [ x$nrpcs != "x1" ]; then
17413                 $LCTL get_param osc.*.stats
17414                 error "found $nrpcs ost_read RPCs, not 1 as expected"
17415         fi
17416 }
17417 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
17418
17419 test_231b() {
17420         mkdir -p $DIR/$tdir
17421         local i
17422         for i in {0..1023}; do
17423                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
17424                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
17425                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
17426         done
17427         sync
17428 }
17429 run_test 231b "must not assert on fully utilized OST request buffer"
17430
17431 test_232a() {
17432         mkdir -p $DIR/$tdir
17433         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
17434
17435         #define OBD_FAIL_LDLM_OST_LVB            0x31c
17436         do_facet ost1 $LCTL set_param fail_loc=0x31c
17437
17438         # ignore dd failure
17439         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
17440
17441         do_facet ost1 $LCTL set_param fail_loc=0
17442         umount_client $MOUNT || error "umount failed"
17443         mount_client $MOUNT || error "mount failed"
17444         stop ost1 || error "cannot stop ost1"
17445         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
17446 }
17447 run_test 232a "failed lock should not block umount"
17448
17449 test_232b() {
17450         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
17451                 skip "Need MDS version at least 2.10.58"
17452
17453         mkdir -p $DIR/$tdir
17454         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
17455         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
17456         sync
17457         cancel_lru_locks osc
17458
17459         #define OBD_FAIL_LDLM_OST_LVB            0x31c
17460         do_facet ost1 $LCTL set_param fail_loc=0x31c
17461
17462         # ignore failure
17463         $LFS data_version $DIR/$tdir/$tfile || true
17464
17465         do_facet ost1 $LCTL set_param fail_loc=0
17466         umount_client $MOUNT || error "umount failed"
17467         mount_client $MOUNT || error "mount failed"
17468         stop ost1 || error "cannot stop ost1"
17469         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
17470 }
17471 run_test 232b "failed data version lock should not block umount"
17472
17473 test_233a() {
17474         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
17475                 skip "Need MDS version at least 2.3.64"
17476         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
17477
17478         local fid=$($LFS path2fid $MOUNT)
17479
17480         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
17481                 error "cannot access $MOUNT using its FID '$fid'"
17482 }
17483 run_test 233a "checking that OBF of the FS root succeeds"
17484
17485 test_233b() {
17486         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
17487                 skip "Need MDS version at least 2.5.90"
17488         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
17489
17490         local fid=$($LFS path2fid $MOUNT/.lustre)
17491
17492         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
17493                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
17494
17495         fid=$($LFS path2fid $MOUNT/.lustre/fid)
17496         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
17497                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
17498 }
17499 run_test 233b "checking that OBF of the FS .lustre succeeds"
17500
17501 test_234() {
17502         local p="$TMP/sanityN-$TESTNAME.parameters"
17503         save_lustre_params client "llite.*.xattr_cache" > $p
17504         lctl set_param llite.*.xattr_cache 1 ||
17505                 skip_env "xattr cache is not supported"
17506
17507         mkdir -p $DIR/$tdir || error "mkdir failed"
17508         touch $DIR/$tdir/$tfile || error "touch failed"
17509         # OBD_FAIL_LLITE_XATTR_ENOMEM
17510         $LCTL set_param fail_loc=0x1405
17511         getfattr -n user.attr $DIR/$tdir/$tfile &&
17512                 error "getfattr should have failed with ENOMEM"
17513         $LCTL set_param fail_loc=0x0
17514         rm -rf $DIR/$tdir
17515
17516         restore_lustre_params < $p
17517         rm -f $p
17518 }
17519 run_test 234 "xattr cache should not crash on ENOMEM"
17520
17521 test_235() {
17522         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
17523                 skip "Need MDS version at least 2.4.52"
17524
17525         flock_deadlock $DIR/$tfile
17526         local RC=$?
17527         case $RC in
17528                 0)
17529                 ;;
17530                 124) error "process hangs on a deadlock"
17531                 ;;
17532                 *) error "error executing flock_deadlock $DIR/$tfile"
17533                 ;;
17534         esac
17535 }
17536 run_test 235 "LU-1715: flock deadlock detection does not work properly"
17537
17538 #LU-2935
17539 test_236() {
17540         check_swap_layouts_support
17541
17542         local ref1=/etc/passwd
17543         local ref2=/etc/group
17544         local file1=$DIR/$tdir/f1
17545         local file2=$DIR/$tdir/f2
17546
17547         test_mkdir -c1 $DIR/$tdir
17548         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
17549         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
17550         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
17551         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
17552         local fd=$(free_fd)
17553         local cmd="exec $fd<>$file2"
17554         eval $cmd
17555         rm $file2
17556         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
17557                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
17558         cmd="exec $fd>&-"
17559         eval $cmd
17560         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
17561
17562         #cleanup
17563         rm -rf $DIR/$tdir
17564 }
17565 run_test 236 "Layout swap on open unlinked file"
17566
17567 # LU-4659 linkea consistency
17568 test_238() {
17569         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
17570                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
17571                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
17572                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
17573
17574         touch $DIR/$tfile
17575         ln $DIR/$tfile $DIR/$tfile.lnk
17576         touch $DIR/$tfile.new
17577         mv $DIR/$tfile.new $DIR/$tfile
17578         local fid1=$($LFS path2fid $DIR/$tfile)
17579         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
17580         local path1=$($LFS fid2path $FSNAME "$fid1")
17581         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
17582         local path2=$($LFS fid2path $FSNAME "$fid2")
17583         [ $tfile.lnk == $path2 ] ||
17584                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
17585         rm -f $DIR/$tfile*
17586 }
17587 run_test 238 "Verify linkea consistency"
17588
17589 test_239A() { # was test_239
17590         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
17591                 skip "Need MDS version at least 2.5.60"
17592
17593         local list=$(comma_list $(mdts_nodes))
17594
17595         mkdir -p $DIR/$tdir
17596         createmany -o $DIR/$tdir/f- 5000
17597         unlinkmany $DIR/$tdir/f- 5000
17598         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
17599                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
17600         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
17601                         osp.*MDT*.sync_in_flight" | calc_sum)
17602         [ "$changes" -eq 0 ] || error "$changes not synced"
17603 }
17604 run_test 239A "osp_sync test"
17605
17606 test_239a() { #LU-5297
17607         remote_mds_nodsh && skip "remote MDS with nodsh"
17608
17609         touch $DIR/$tfile
17610         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
17611         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
17612         chgrp $RUNAS_GID $DIR/$tfile
17613         wait_delete_completed
17614 }
17615 run_test 239a "process invalid osp sync record correctly"
17616
17617 test_239b() { #LU-5297
17618         remote_mds_nodsh && skip "remote MDS with nodsh"
17619
17620         touch $DIR/$tfile1
17621         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
17622         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
17623         chgrp $RUNAS_GID $DIR/$tfile1
17624         wait_delete_completed
17625         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
17626         touch $DIR/$tfile2
17627         chgrp $RUNAS_GID $DIR/$tfile2
17628         wait_delete_completed
17629 }
17630 run_test 239b "process osp sync record with ENOMEM error correctly"
17631
17632 test_240() {
17633         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17634         remote_mds_nodsh && skip "remote MDS with nodsh"
17635
17636         mkdir -p $DIR/$tdir
17637
17638         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
17639                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
17640         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
17641                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
17642
17643         umount_client $MOUNT || error "umount failed"
17644         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
17645         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
17646         mount_client $MOUNT || error "failed to mount client"
17647
17648         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
17649         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
17650 }
17651 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
17652
17653 test_241_bio() {
17654         local count=$1
17655         local bsize=$2
17656
17657         for LOOP in $(seq $count); do
17658                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
17659                 cancel_lru_locks $OSC || true
17660         done
17661 }
17662
17663 test_241_dio() {
17664         local count=$1
17665         local bsize=$2
17666
17667         for LOOP in $(seq $1); do
17668                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
17669                         2>/dev/null
17670         done
17671 }
17672
17673 test_241a() { # was test_241
17674         local bsize=$PAGE_SIZE
17675
17676         (( bsize < 40960 )) && bsize=40960
17677         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
17678         ls -la $DIR/$tfile
17679         cancel_lru_locks $OSC
17680         test_241_bio 1000 $bsize &
17681         PID=$!
17682         test_241_dio 1000 $bsize
17683         wait $PID
17684 }
17685 run_test 241a "bio vs dio"
17686
17687 test_241b() {
17688         local bsize=$PAGE_SIZE
17689
17690         (( bsize < 40960 )) && bsize=40960
17691         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
17692         ls -la $DIR/$tfile
17693         test_241_dio 1000 $bsize &
17694         PID=$!
17695         test_241_dio 1000 $bsize
17696         wait $PID
17697 }
17698 run_test 241b "dio vs dio"
17699
17700 test_242() {
17701         remote_mds_nodsh && skip "remote MDS with nodsh"
17702
17703         mkdir -p $DIR/$tdir
17704         touch $DIR/$tdir/$tfile
17705
17706         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
17707         do_facet mds1 lctl set_param fail_loc=0x105
17708         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
17709
17710         do_facet mds1 lctl set_param fail_loc=0
17711         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
17712 }
17713 run_test 242 "mdt_readpage failure should not cause directory unreadable"
17714
17715 test_243()
17716 {
17717         test_mkdir $DIR/$tdir
17718         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
17719 }
17720 run_test 243 "various group lock tests"
17721
17722 test_244a()
17723 {
17724         test_mkdir $DIR/$tdir
17725         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
17726         sendfile_grouplock $DIR/$tdir/$tfile || \
17727                 error "sendfile+grouplock failed"
17728         rm -rf $DIR/$tdir
17729 }
17730 run_test 244a "sendfile with group lock tests"
17731
17732 test_244b()
17733 {
17734         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
17735
17736         local threads=50
17737         local size=$((1024*1024))
17738
17739         test_mkdir $DIR/$tdir
17740         for i in $(seq 1 $threads); do
17741                 local file=$DIR/$tdir/file_$((i / 10))
17742                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
17743                 local pids[$i]=$!
17744         done
17745         for i in $(seq 1 $threads); do
17746                 wait ${pids[$i]}
17747         done
17748 }
17749 run_test 244b "multi-threaded write with group lock"
17750
17751 test_245() {
17752         local flagname="multi_mod_rpcs"
17753         local connect_data_name="max_mod_rpcs"
17754         local out
17755
17756         # check if multiple modify RPCs flag is set
17757         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
17758                 grep "connect_flags:")
17759         echo "$out"
17760
17761         echo "$out" | grep -qw $flagname
17762         if [ $? -ne 0 ]; then
17763                 echo "connect flag $flagname is not set"
17764                 return
17765         fi
17766
17767         # check if multiple modify RPCs data is set
17768         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
17769         echo "$out"
17770
17771         echo "$out" | grep -qw $connect_data_name ||
17772                 error "import should have connect data $connect_data_name"
17773 }
17774 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
17775
17776 cleanup_247() {
17777         local submount=$1
17778
17779         trap 0
17780         umount_client $submount
17781         rmdir $submount
17782 }
17783
17784 test_247a() {
17785         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
17786                 grep -q subtree ||
17787                 skip_env "Fileset feature is not supported"
17788
17789         local submount=${MOUNT}_$tdir
17790
17791         mkdir $MOUNT/$tdir
17792         mkdir -p $submount || error "mkdir $submount failed"
17793         FILESET="$FILESET/$tdir" mount_client $submount ||
17794                 error "mount $submount failed"
17795         trap "cleanup_247 $submount" EXIT
17796         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
17797         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
17798                 error "read $MOUNT/$tdir/$tfile failed"
17799         cleanup_247 $submount
17800 }
17801 run_test 247a "mount subdir as fileset"
17802
17803 test_247b() {
17804         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
17805                 skip_env "Fileset feature is not supported"
17806
17807         local submount=${MOUNT}_$tdir
17808
17809         rm -rf $MOUNT/$tdir
17810         mkdir -p $submount || error "mkdir $submount failed"
17811         SKIP_FILESET=1
17812         FILESET="$FILESET/$tdir" mount_client $submount &&
17813                 error "mount $submount should fail"
17814         rmdir $submount
17815 }
17816 run_test 247b "mount subdir that dose not exist"
17817
17818 test_247c() {
17819         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
17820                 skip_env "Fileset feature is not supported"
17821
17822         local submount=${MOUNT}_$tdir
17823
17824         mkdir -p $MOUNT/$tdir/dir1
17825         mkdir -p $submount || error "mkdir $submount failed"
17826         trap "cleanup_247 $submount" EXIT
17827         FILESET="$FILESET/$tdir" mount_client $submount ||
17828                 error "mount $submount failed"
17829         local fid=$($LFS path2fid $MOUNT/)
17830         $LFS fid2path $submount $fid && error "fid2path should fail"
17831         cleanup_247 $submount
17832 }
17833 run_test 247c "running fid2path outside root"
17834
17835 test_247d() {
17836         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
17837                 skip "Fileset feature is not supported"
17838
17839         local submount=${MOUNT}_$tdir
17840
17841         mkdir -p $MOUNT/$tdir/dir1
17842         mkdir -p $submount || error "mkdir $submount failed"
17843         FILESET="$FILESET/$tdir" mount_client $submount ||
17844                 error "mount $submount failed"
17845         trap "cleanup_247 $submount" EXIT
17846         local fid=$($LFS path2fid $submount/dir1)
17847         $LFS fid2path $submount $fid || error "fid2path should succeed"
17848         cleanup_247 $submount
17849 }
17850 run_test 247d "running fid2path inside root"
17851
17852 # LU-8037
17853 test_247e() {
17854         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
17855                 grep -q subtree ||
17856                 skip "Fileset feature is not supported"
17857
17858         local submount=${MOUNT}_$tdir
17859
17860         mkdir $MOUNT/$tdir
17861         mkdir -p $submount || error "mkdir $submount failed"
17862         FILESET="$FILESET/.." mount_client $submount &&
17863                 error "mount $submount should fail"
17864         rmdir $submount
17865 }
17866 run_test 247e "mount .. as fileset"
17867
17868 test_248a() {
17869         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
17870         [ -z "$fast_read_sav" ] && skip "no fast read support"
17871
17872         # create a large file for fast read verification
17873         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
17874
17875         # make sure the file is created correctly
17876         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
17877                 { rm -f $DIR/$tfile; skip "file creation error"; }
17878
17879         echo "Test 1: verify that fast read is 4 times faster on cache read"
17880
17881         # small read with fast read enabled
17882         $LCTL set_param -n llite.*.fast_read=1
17883         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
17884                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
17885                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
17886         # small read with fast read disabled
17887         $LCTL set_param -n llite.*.fast_read=0
17888         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
17889                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
17890                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
17891
17892         # verify that fast read is 4 times faster for cache read
17893         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
17894                 error_not_in_vm "fast read was not 4 times faster: " \
17895                            "$t_fast vs $t_slow"
17896
17897         echo "Test 2: verify the performance between big and small read"
17898         $LCTL set_param -n llite.*.fast_read=1
17899
17900         # 1k non-cache read
17901         cancel_lru_locks osc
17902         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
17903                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
17904                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
17905
17906         # 1M non-cache read
17907         cancel_lru_locks osc
17908         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
17909                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
17910                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
17911
17912         # verify that big IO is not 4 times faster than small IO
17913         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
17914                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
17915
17916         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
17917         rm -f $DIR/$tfile
17918 }
17919 run_test 248a "fast read verification"
17920
17921 test_248b() {
17922         # Default short_io_bytes=16384, try both smaller and larger sizes.
17923         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
17924         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
17925         echo "bs=53248 count=113 normal buffered write"
17926         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
17927                 error "dd of initial data file failed"
17928         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
17929
17930         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
17931         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
17932                 error "dd with sync normal writes failed"
17933         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
17934
17935         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
17936         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
17937                 error "dd with sync small writes failed"
17938         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
17939
17940         cancel_lru_locks osc
17941
17942         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
17943         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
17944         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
17945         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
17946                 iflag=direct || error "dd with O_DIRECT small read failed"
17947         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
17948         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
17949                 error "compare $TMP/$tfile.1 failed"
17950
17951         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
17952         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
17953
17954         # just to see what the maximum tunable value is, and test parsing
17955         echo "test invalid parameter 2MB"
17956         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
17957                 error "too-large short_io_bytes allowed"
17958         echo "test maximum parameter 512KB"
17959         # if we can set a larger short_io_bytes, run test regardless of version
17960         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
17961                 # older clients may not allow setting it this large, that's OK
17962                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
17963                         skip "Need at least client version 2.13.50"
17964                 error "medium short_io_bytes failed"
17965         fi
17966         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
17967         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
17968
17969         echo "test large parameter 64KB"
17970         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
17971         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
17972
17973         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
17974         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
17975                 error "dd with sync large writes failed"
17976         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
17977
17978         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
17979         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
17980         num=$((113 * 4096 / PAGE_SIZE))
17981         echo "bs=$size count=$num oflag=direct large write $tfile.3"
17982         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
17983                 error "dd with O_DIRECT large writes failed"
17984         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
17985                 error "compare $DIR/$tfile.3 failed"
17986
17987         cancel_lru_locks osc
17988
17989         echo "bs=$size count=$num iflag=direct large read $tfile.2"
17990         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
17991                 error "dd with O_DIRECT large read failed"
17992         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
17993                 error "compare $TMP/$tfile.2 failed"
17994
17995         echo "bs=$size count=$num iflag=direct large read $tfile.3"
17996         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
17997                 error "dd with O_DIRECT large read failed"
17998         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
17999                 error "compare $TMP/$tfile.3 failed"
18000 }
18001 run_test 248b "test short_io read and write for both small and large sizes"
18002
18003 test_249() { # LU-7890
18004         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
18005                 skip "Need at least version 2.8.54"
18006
18007         rm -f $DIR/$tfile
18008         $LFS setstripe -c 1 $DIR/$tfile
18009         # Offset 2T == 4k * 512M
18010         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
18011                 error "dd to 2T offset failed"
18012 }
18013 run_test 249 "Write above 2T file size"
18014
18015 test_250() {
18016         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
18017          && skip "no 16TB file size limit on ZFS"
18018
18019         $LFS setstripe -c 1 $DIR/$tfile
18020         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
18021         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
18022         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
18023         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
18024                 conv=notrunc,fsync && error "append succeeded"
18025         return 0
18026 }
18027 run_test 250 "Write above 16T limit"
18028
18029 test_251() {
18030         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
18031
18032         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
18033         #Skip once - writing the first stripe will succeed
18034         $LCTL set_param fail_loc=0xa0001407 fail_val=1
18035         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
18036                 error "short write happened"
18037
18038         $LCTL set_param fail_loc=0xa0001407 fail_val=1
18039         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
18040                 error "short read happened"
18041
18042         rm -f $DIR/$tfile
18043 }
18044 run_test 251 "Handling short read and write correctly"
18045
18046 test_252() {
18047         remote_mds_nodsh && skip "remote MDS with nodsh"
18048         remote_ost_nodsh && skip "remote OST with nodsh"
18049         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
18050                 skip_env "ldiskfs only test"
18051         fi
18052
18053         local tgt
18054         local dev
18055         local out
18056         local uuid
18057         local num
18058         local gen
18059
18060         # check lr_reader on OST0000
18061         tgt=ost1
18062         dev=$(facet_device $tgt)
18063         out=$(do_facet $tgt $LR_READER $dev)
18064         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
18065         echo "$out"
18066         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
18067         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
18068                 error "Invalid uuid returned by $LR_READER on target $tgt"
18069         echo -e "uuid returned by $LR_READER is '$uuid'\n"
18070
18071         # check lr_reader -c on MDT0000
18072         tgt=mds1
18073         dev=$(facet_device $tgt)
18074         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
18075                 skip "$LR_READER does not support additional options"
18076         fi
18077         out=$(do_facet $tgt $LR_READER -c $dev)
18078         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
18079         echo "$out"
18080         num=$(echo "$out" | grep -c "mdtlov")
18081         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
18082                 error "Invalid number of mdtlov clients returned by $LR_READER"
18083         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
18084
18085         # check lr_reader -cr on MDT0000
18086         out=$(do_facet $tgt $LR_READER -cr $dev)
18087         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
18088         echo "$out"
18089         echo "$out" | grep -q "^reply_data:$" ||
18090                 error "$LR_READER should have returned 'reply_data' section"
18091         num=$(echo "$out" | grep -c "client_generation")
18092         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
18093 }
18094 run_test 252 "check lr_reader tool"
18095
18096 test_253() {
18097         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18098         remote_mds_nodsh && skip "remote MDS with nodsh"
18099         remote_mgs_nodsh && skip "remote MGS with nodsh"
18100
18101         local ostidx=0
18102         local rc=0
18103         local ost_name=$(ostname_from_index $ostidx)
18104
18105         # on the mdt's osc
18106         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
18107         do_facet $SINGLEMDS $LCTL get_param -n \
18108                 osp.$mdtosc_proc1.reserved_mb_high ||
18109                 skip  "remote MDS does not support reserved_mb_high"
18110
18111         rm -rf $DIR/$tdir
18112         wait_mds_ost_sync
18113         wait_delete_completed
18114         mkdir $DIR/$tdir
18115
18116         pool_add $TESTNAME || error "Pool creation failed"
18117         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
18118
18119         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
18120                 error "Setstripe failed"
18121
18122         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
18123
18124         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
18125                     grep "watermarks")
18126         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
18127
18128         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
18129                         osp.$mdtosc_proc1.prealloc_status)
18130         echo "prealloc_status $oa_status"
18131
18132         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
18133                 error "File creation should fail"
18134
18135         #object allocation was stopped, but we still able to append files
18136         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
18137                 oflag=append || error "Append failed"
18138
18139         rm -f $DIR/$tdir/$tfile.0
18140
18141         # For this test, we want to delete the files we created to go out of
18142         # space but leave the watermark, so we remain nearly out of space
18143         ost_watermarks_enospc_delete_files $tfile $ostidx
18144
18145         wait_delete_completed
18146
18147         sleep_maxage
18148
18149         for i in $(seq 10 12); do
18150                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
18151                         2>/dev/null || error "File creation failed after rm"
18152         done
18153
18154         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
18155                         osp.$mdtosc_proc1.prealloc_status)
18156         echo "prealloc_status $oa_status"
18157
18158         if (( oa_status != 0 )); then
18159                 error "Object allocation still disable after rm"
18160         fi
18161 }
18162 run_test 253 "Check object allocation limit"
18163
18164 test_254() {
18165         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18166         remote_mds_nodsh && skip "remote MDS with nodsh"
18167         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
18168                 skip "MDS does not support changelog_size"
18169
18170         local cl_user
18171         local MDT0=$(facet_svc $SINGLEMDS)
18172
18173         changelog_register || error "changelog_register failed"
18174
18175         changelog_clear 0 || error "changelog_clear failed"
18176
18177         local size1=$(do_facet $SINGLEMDS \
18178                       $LCTL get_param -n mdd.$MDT0.changelog_size)
18179         echo "Changelog size $size1"
18180
18181         rm -rf $DIR/$tdir
18182         $LFS mkdir -i 0 $DIR/$tdir
18183         # change something
18184         mkdir -p $DIR/$tdir/pics/2008/zachy
18185         touch $DIR/$tdir/pics/2008/zachy/timestamp
18186         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
18187         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
18188         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
18189         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
18190         rm $DIR/$tdir/pics/desktop.jpg
18191
18192         local size2=$(do_facet $SINGLEMDS \
18193                       $LCTL get_param -n mdd.$MDT0.changelog_size)
18194         echo "Changelog size after work $size2"
18195
18196         (( $size2 > $size1 )) ||
18197                 error "new Changelog size=$size2 less than old size=$size1"
18198 }
18199 run_test 254 "Check changelog size"
18200
18201 ladvise_no_type()
18202 {
18203         local type=$1
18204         local file=$2
18205
18206         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
18207                 awk -F: '{print $2}' | grep $type > /dev/null
18208         if [ $? -ne 0 ]; then
18209                 return 0
18210         fi
18211         return 1
18212 }
18213
18214 ladvise_no_ioctl()
18215 {
18216         local file=$1
18217
18218         lfs ladvise -a willread $file > /dev/null 2>&1
18219         if [ $? -eq 0 ]; then
18220                 return 1
18221         fi
18222
18223         lfs ladvise -a willread $file 2>&1 |
18224                 grep "Inappropriate ioctl for device" > /dev/null
18225         if [ $? -eq 0 ]; then
18226                 return 0
18227         fi
18228         return 1
18229 }
18230
18231 percent() {
18232         bc <<<"scale=2; ($1 - $2) * 100 / $2"
18233 }
18234
18235 # run a random read IO workload
18236 # usage: random_read_iops <filename> <filesize> <iosize>
18237 random_read_iops() {
18238         local file=$1
18239         local fsize=$2
18240         local iosize=${3:-4096}
18241
18242         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
18243                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
18244 }
18245
18246 drop_file_oss_cache() {
18247         local file="$1"
18248         local nodes="$2"
18249
18250         $LFS ladvise -a dontneed $file 2>/dev/null ||
18251                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
18252 }
18253
18254 ladvise_willread_performance()
18255 {
18256         local repeat=10
18257         local average_origin=0
18258         local average_cache=0
18259         local average_ladvise=0
18260
18261         for ((i = 1; i <= $repeat; i++)); do
18262                 echo "Iter $i/$repeat: reading without willread hint"
18263                 cancel_lru_locks osc
18264                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
18265                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
18266                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
18267                 average_origin=$(bc <<<"$average_origin + $speed_origin")
18268
18269                 cancel_lru_locks osc
18270                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
18271                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
18272                 average_cache=$(bc <<<"$average_cache + $speed_cache")
18273
18274                 cancel_lru_locks osc
18275                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
18276                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
18277                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
18278                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
18279                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
18280         done
18281         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
18282         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
18283         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
18284
18285         speedup_cache=$(percent $average_cache $average_origin)
18286         speedup_ladvise=$(percent $average_ladvise $average_origin)
18287
18288         echo "Average uncached read: $average_origin"
18289         echo "Average speedup with OSS cached read: " \
18290                 "$average_cache = +$speedup_cache%"
18291         echo "Average speedup with ladvise willread: " \
18292                 "$average_ladvise = +$speedup_ladvise%"
18293
18294         local lowest_speedup=20
18295         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
18296                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
18297                         "got $average_cache%. Skipping ladvise willread check."
18298                 return 0
18299         fi
18300
18301         # the test won't work on ZFS until it supports 'ladvise dontneed', but
18302         # it is still good to run until then to exercise 'ladvise willread'
18303         ! $LFS ladvise -a dontneed $DIR/$tfile &&
18304                 [ "$ost1_FSTYPE" = "zfs" ] &&
18305                 echo "osd-zfs does not support dontneed or drop_caches" &&
18306                 return 0
18307
18308         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
18309         [ ${average_ladvise%.*} -gt $lowest_speedup ] ||
18310                 error_not_in_vm "Speedup with willread is less than " \
18311                         "$lowest_speedup%, got $average_ladvise%"
18312 }
18313
18314 test_255a() {
18315         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
18316                 skip "lustre < 2.8.54 does not support ladvise "
18317         remote_ost_nodsh && skip "remote OST with nodsh"
18318
18319         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
18320
18321         ladvise_no_type willread $DIR/$tfile &&
18322                 skip "willread ladvise is not supported"
18323
18324         ladvise_no_ioctl $DIR/$tfile &&
18325                 skip "ladvise ioctl is not supported"
18326
18327         local size_mb=100
18328         local size=$((size_mb * 1048576))
18329         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
18330                 error "dd to $DIR/$tfile failed"
18331
18332         lfs ladvise -a willread $DIR/$tfile ||
18333                 error "Ladvise failed with no range argument"
18334
18335         lfs ladvise -a willread -s 0 $DIR/$tfile ||
18336                 error "Ladvise failed with no -l or -e argument"
18337
18338         lfs ladvise -a willread -e 1 $DIR/$tfile ||
18339                 error "Ladvise failed with only -e argument"
18340
18341         lfs ladvise -a willread -l 1 $DIR/$tfile ||
18342                 error "Ladvise failed with only -l argument"
18343
18344         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
18345                 error "End offset should not be smaller than start offset"
18346
18347         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
18348                 error "End offset should not be equal to start offset"
18349
18350         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
18351                 error "Ladvise failed with overflowing -s argument"
18352
18353         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
18354                 error "Ladvise failed with overflowing -e argument"
18355
18356         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
18357                 error "Ladvise failed with overflowing -l argument"
18358
18359         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
18360                 error "Ladvise succeeded with conflicting -l and -e arguments"
18361
18362         echo "Synchronous ladvise should wait"
18363         local delay=4
18364 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
18365         do_nodes $(comma_list $(osts_nodes)) \
18366                 $LCTL set_param fail_val=$delay fail_loc=0x237
18367
18368         local start_ts=$SECONDS
18369         lfs ladvise -a willread $DIR/$tfile ||
18370                 error "Ladvise failed with no range argument"
18371         local end_ts=$SECONDS
18372         local inteval_ts=$((end_ts - start_ts))
18373
18374         if [ $inteval_ts -lt $(($delay - 1)) ]; then
18375                 error "Synchronous advice didn't wait reply"
18376         fi
18377
18378         echo "Asynchronous ladvise shouldn't wait"
18379         local start_ts=$SECONDS
18380         lfs ladvise -a willread -b $DIR/$tfile ||
18381                 error "Ladvise failed with no range argument"
18382         local end_ts=$SECONDS
18383         local inteval_ts=$((end_ts - start_ts))
18384
18385         if [ $inteval_ts -gt $(($delay / 2)) ]; then
18386                 error "Asynchronous advice blocked"
18387         fi
18388
18389         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
18390         ladvise_willread_performance
18391 }
18392 run_test 255a "check 'lfs ladvise -a willread'"
18393
18394 facet_meminfo() {
18395         local facet=$1
18396         local info=$2
18397
18398         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
18399 }
18400
18401 test_255b() {
18402         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
18403                 skip "lustre < 2.8.54 does not support ladvise "
18404         remote_ost_nodsh && skip "remote OST with nodsh"
18405
18406         lfs setstripe -c 1 -i 0 $DIR/$tfile
18407
18408         ladvise_no_type dontneed $DIR/$tfile &&
18409                 skip "dontneed ladvise is not supported"
18410
18411         ladvise_no_ioctl $DIR/$tfile &&
18412                 skip "ladvise ioctl is not supported"
18413
18414         ! $LFS ladvise -a dontneed $DIR/$tfile &&
18415                 [ "$ost1_FSTYPE" = "zfs" ] &&
18416                 skip "zfs-osd does not support 'ladvise dontneed'"
18417
18418         local size_mb=100
18419         local size=$((size_mb * 1048576))
18420         # In order to prevent disturbance of other processes, only check 3/4
18421         # of the memory usage
18422         local kibibytes=$((size_mb * 1024 * 3 / 4))
18423
18424         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
18425                 error "dd to $DIR/$tfile failed"
18426
18427         #force write to complete before dropping OST cache & checking memory
18428         sync
18429
18430         local total=$(facet_meminfo ost1 MemTotal)
18431         echo "Total memory: $total KiB"
18432
18433         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
18434         local before_read=$(facet_meminfo ost1 Cached)
18435         echo "Cache used before read: $before_read KiB"
18436
18437         lfs ladvise -a willread $DIR/$tfile ||
18438                 error "Ladvise willread failed"
18439         local after_read=$(facet_meminfo ost1 Cached)
18440         echo "Cache used after read: $after_read KiB"
18441
18442         lfs ladvise -a dontneed $DIR/$tfile ||
18443                 error "Ladvise dontneed again failed"
18444         local no_read=$(facet_meminfo ost1 Cached)
18445         echo "Cache used after dontneed ladvise: $no_read KiB"
18446
18447         if [ $total -lt $((before_read + kibibytes)) ]; then
18448                 echo "Memory is too small, abort checking"
18449                 return 0
18450         fi
18451
18452         if [ $((before_read + kibibytes)) -gt $after_read ]; then
18453                 error "Ladvise willread should use more memory" \
18454                         "than $kibibytes KiB"
18455         fi
18456
18457         if [ $((no_read + kibibytes)) -gt $after_read ]; then
18458                 error "Ladvise dontneed should release more memory" \
18459                         "than $kibibytes KiB"
18460         fi
18461 }
18462 run_test 255b "check 'lfs ladvise -a dontneed'"
18463
18464 test_255c() {
18465         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
18466                 skip "lustre < 2.10.50 does not support lockahead"
18467
18468         local count
18469         local new_count
18470         local difference
18471         local i
18472         local rc
18473
18474         test_mkdir -p $DIR/$tdir
18475         $LFS setstripe -i 0 -c 1 $DIR/$tdir
18476
18477         #test 10 returns only success/failure
18478         i=10
18479         lockahead_test -d $DIR/$tdir -t $i -f $tfile
18480         rc=$?
18481         if [ $rc -eq 255 ]; then
18482                 error "Ladvise test${i} failed, ${rc}"
18483         fi
18484
18485         #test 11 counts lock enqueue requests, all others count new locks
18486         i=11
18487         count=$(do_facet ost1 \
18488                 $LCTL get_param -n ost.OSS.ost.stats)
18489         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
18490
18491         lockahead_test -d $DIR/$tdir -t $i -f $tfile
18492         rc=$?
18493         if [ $rc -eq 255 ]; then
18494                 error "Ladvise test${i} failed, ${rc}"
18495         fi
18496
18497         new_count=$(do_facet ost1 \
18498                 $LCTL get_param -n ost.OSS.ost.stats)
18499         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
18500                    awk '{ print $2 }')
18501
18502         difference="$((new_count - count))"
18503         if [ $difference -ne $rc ]; then
18504                 error "Ladvise test${i}, bad enqueue count, returned " \
18505                       "${rc}, actual ${difference}"
18506         fi
18507
18508         for i in $(seq 12 21); do
18509                 # If we do not do this, we run the risk of having too many
18510                 # locks and starting lock cancellation while we are checking
18511                 # lock counts.
18512                 cancel_lru_locks osc
18513
18514                 count=$($LCTL get_param -n \
18515                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
18516
18517                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
18518                 rc=$?
18519                 if [ $rc -eq 255 ]; then
18520                         error "Ladvise test ${i} failed, ${rc}"
18521                 fi
18522
18523                 new_count=$($LCTL get_param -n \
18524                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
18525                 difference="$((new_count - count))"
18526
18527                 # Test 15 output is divided by 100 to map down to valid return
18528                 if [ $i -eq 15 ]; then
18529                         rc="$((rc * 100))"
18530                 fi
18531
18532                 if [ $difference -ne $rc ]; then
18533                         error "Ladvise test ${i}, bad lock count, returned " \
18534                               "${rc}, actual ${difference}"
18535                 fi
18536         done
18537
18538         #test 22 returns only success/failure
18539         i=22
18540         lockahead_test -d $DIR/$tdir -t $i -f $tfile
18541         rc=$?
18542         if [ $rc -eq 255 ]; then
18543                 error "Ladvise test${i} failed, ${rc}"
18544         fi
18545 }
18546 run_test 255c "suite of ladvise lockahead tests"
18547
18548 test_256() {
18549         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18550         remote_mds_nodsh && skip "remote MDS with nodsh"
18551         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
18552         changelog_users $SINGLEMDS | grep "^cl" &&
18553                 skip "active changelog user"
18554
18555         local cl_user
18556         local cat_sl
18557         local mdt_dev
18558
18559         mdt_dev=$(mdsdevname 1)
18560         echo $mdt_dev
18561
18562         changelog_register || error "changelog_register failed"
18563
18564         rm -rf $DIR/$tdir
18565         mkdir -p $DIR/$tdir
18566
18567         changelog_clear 0 || error "changelog_clear failed"
18568
18569         # change something
18570         touch $DIR/$tdir/{1..10}
18571
18572         # stop the MDT
18573         stop $SINGLEMDS || error "Fail to stop MDT"
18574
18575         # remount the MDT
18576
18577         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
18578
18579         #after mount new plainllog is used
18580         touch $DIR/$tdir/{11..19}
18581         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
18582         stack_trap "rm -f $tmpfile"
18583         cat_sl=$(do_facet $SINGLEMDS "sync; \
18584                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
18585                  llog_reader $tmpfile | grep -c type=1064553b")
18586         do_facet $SINGLEMDS llog_reader $tmpfile
18587
18588         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
18589
18590         changelog_clear 0 || error "changelog_clear failed"
18591
18592         cat_sl=$(do_facet $SINGLEMDS "sync; \
18593                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
18594                  llog_reader $tmpfile | grep -c type=1064553b")
18595
18596         if (( cat_sl == 2 )); then
18597                 error "Empty plain llog was not deleted from changelog catalog"
18598         elif (( cat_sl != 1 )); then
18599                 error "Active plain llog shouldn't be deleted from catalog"
18600         fi
18601 }
18602 run_test 256 "Check llog delete for empty and not full state"
18603
18604 test_257() {
18605         remote_mds_nodsh && skip "remote MDS with nodsh"
18606         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
18607                 skip "Need MDS version at least 2.8.55"
18608
18609         test_mkdir $DIR/$tdir
18610
18611         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
18612                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
18613         stat $DIR/$tdir
18614
18615 #define OBD_FAIL_MDS_XATTR_REP                  0x161
18616         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
18617         local facet=mds$((mdtidx + 1))
18618         set_nodes_failloc $(facet_active_host $facet) 0x80000161
18619         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
18620
18621         stop $facet || error "stop MDS failed"
18622         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
18623                 error "start MDS fail"
18624         wait_recovery_complete $facet
18625 }
18626 run_test 257 "xattr locks are not lost"
18627
18628 # Verify we take the i_mutex when security requires it
18629 test_258a() {
18630 #define OBD_FAIL_IMUTEX_SEC 0x141c
18631         $LCTL set_param fail_loc=0x141c
18632         touch $DIR/$tfile
18633         chmod u+s $DIR/$tfile
18634         chmod a+rwx $DIR/$tfile
18635         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
18636         RC=$?
18637         if [ $RC -ne 0 ]; then
18638                 error "error, failed to take i_mutex, rc=$?"
18639         fi
18640         rm -f $DIR/$tfile
18641 }
18642 run_test 258a "verify i_mutex security behavior when suid attributes is set"
18643
18644 # Verify we do NOT take the i_mutex in the normal case
18645 test_258b() {
18646 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
18647         $LCTL set_param fail_loc=0x141d
18648         touch $DIR/$tfile
18649         chmod a+rwx $DIR
18650         chmod a+rw $DIR/$tfile
18651         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
18652         RC=$?
18653         if [ $RC -ne 0 ]; then
18654                 error "error, took i_mutex unnecessarily, rc=$?"
18655         fi
18656         rm -f $DIR/$tfile
18657
18658 }
18659 run_test 258b "verify i_mutex security behavior"
18660
18661 test_259() {
18662         local file=$DIR/$tfile
18663         local before
18664         local after
18665
18666         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
18667
18668         stack_trap "rm -f $file" EXIT
18669
18670         wait_delete_completed
18671         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
18672         echo "before: $before"
18673
18674         $LFS setstripe -i 0 -c 1 $file
18675         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
18676         sync_all_data
18677         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
18678         echo "after write: $after"
18679
18680 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
18681         do_facet ost1 $LCTL set_param fail_loc=0x2301
18682         $TRUNCATE $file 0
18683         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
18684         echo "after truncate: $after"
18685
18686         stop ost1
18687         do_facet ost1 $LCTL set_param fail_loc=0
18688         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18689         sleep 2
18690         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
18691         echo "after restart: $after"
18692         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
18693                 error "missing truncate?"
18694
18695         return 0
18696 }
18697 run_test 259 "crash at delayed truncate"
18698
18699 test_260() {
18700 #define OBD_FAIL_MDC_CLOSE               0x806
18701         $LCTL set_param fail_loc=0x80000806
18702         touch $DIR/$tfile
18703
18704 }
18705 run_test 260 "Check mdc_close fail"
18706
18707 ### Data-on-MDT sanity tests ###
18708 test_270a() {
18709         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18710                 skip "Need MDS version at least 2.10.55 for DoM"
18711
18712         # create DoM file
18713         local dom=$DIR/$tdir/dom_file
18714         local tmp=$DIR/$tdir/tmp_file
18715
18716         mkdir -p $DIR/$tdir
18717
18718         # basic checks for DoM component creation
18719         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
18720                 error "Can set MDT layout to non-first entry"
18721
18722         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
18723                 error "Can define multiple entries as MDT layout"
18724
18725         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
18726
18727         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
18728         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
18729         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
18730
18731         local mdtidx=$($LFS getstripe -m $dom)
18732         local mdtname=MDT$(printf %04x $mdtidx)
18733         local facet=mds$((mdtidx + 1))
18734         local space_check=1
18735
18736         # Skip free space checks with ZFS
18737         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
18738
18739         # write
18740         sync
18741         local size_tmp=$((65536 * 3))
18742         local mdtfree1=$(do_facet $facet \
18743                          lctl get_param -n osd*.*$mdtname.kbytesfree)
18744
18745         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
18746         # check also direct IO along write
18747         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
18748         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
18749         sync
18750         cmp $tmp $dom || error "file data is different"
18751         [ $(stat -c%s $dom) == $size_tmp ] ||
18752                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
18753         if [ $space_check == 1 ]; then
18754                 local mdtfree2=$(do_facet $facet \
18755                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
18756
18757                 # increase in usage from by $size_tmp
18758                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
18759                         error "MDT free space wrong after write: " \
18760                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
18761         fi
18762
18763         # truncate
18764         local size_dom=10000
18765
18766         $TRUNCATE $dom $size_dom
18767         [ $(stat -c%s $dom) == $size_dom ] ||
18768                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
18769         if [ $space_check == 1 ]; then
18770                 mdtfree1=$(do_facet $facet \
18771                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18772                 # decrease in usage from $size_tmp to new $size_dom
18773                 [ $(($mdtfree1 - $mdtfree2)) -ge \
18774                   $(((size_tmp - size_dom) / 1024)) ] ||
18775                         error "MDT free space is wrong after truncate: " \
18776                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
18777         fi
18778
18779         # append
18780         cat $tmp >> $dom
18781         sync
18782         size_dom=$((size_dom + size_tmp))
18783         [ $(stat -c%s $dom) == $size_dom ] ||
18784                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
18785         if [ $space_check == 1 ]; then
18786                 mdtfree2=$(do_facet $facet \
18787                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18788                 # increase in usage by $size_tmp from previous
18789                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
18790                         error "MDT free space is wrong after append: " \
18791                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
18792         fi
18793
18794         # delete
18795         rm $dom
18796         if [ $space_check == 1 ]; then
18797                 mdtfree1=$(do_facet $facet \
18798                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18799                 # decrease in usage by $size_dom from previous
18800                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
18801                         error "MDT free space is wrong after removal: " \
18802                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
18803         fi
18804
18805         # combined striping
18806         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
18807                 error "Can't create DoM + OST striping"
18808
18809         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
18810         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
18811         # check also direct IO along write
18812         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
18813         sync
18814         cmp $tmp $dom || error "file data is different"
18815         [ $(stat -c%s $dom) == $size_tmp ] ||
18816                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
18817         rm $dom $tmp
18818
18819         return 0
18820 }
18821 run_test 270a "DoM: basic functionality tests"
18822
18823 test_270b() {
18824         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18825                 skip "Need MDS version at least 2.10.55"
18826
18827         local dom=$DIR/$tdir/dom_file
18828         local max_size=1048576
18829
18830         mkdir -p $DIR/$tdir
18831         $LFS setstripe -E $max_size -L mdt $dom
18832
18833         # truncate over the limit
18834         $TRUNCATE $dom $(($max_size + 1)) &&
18835                 error "successful truncate over the maximum size"
18836         # write over the limit
18837         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
18838                 error "successful write over the maximum size"
18839         # append over the limit
18840         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
18841         echo "12345" >> $dom && error "successful append over the maximum size"
18842         rm $dom
18843
18844         return 0
18845 }
18846 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
18847
18848 test_270c() {
18849         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18850                 skip "Need MDS version at least 2.10.55"
18851
18852         mkdir -p $DIR/$tdir
18853         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18854
18855         # check files inherit DoM EA
18856         touch $DIR/$tdir/first
18857         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
18858                 error "bad pattern"
18859         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
18860                 error "bad stripe count"
18861         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
18862                 error "bad stripe size"
18863
18864         # check directory inherits DoM EA and uses it as default
18865         mkdir $DIR/$tdir/subdir
18866         touch $DIR/$tdir/subdir/second
18867         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
18868                 error "bad pattern in sub-directory"
18869         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
18870                 error "bad stripe count in sub-directory"
18871         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
18872                 error "bad stripe size in sub-directory"
18873         return 0
18874 }
18875 run_test 270c "DoM: DoM EA inheritance tests"
18876
18877 test_270d() {
18878         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18879                 skip "Need MDS version at least 2.10.55"
18880
18881         mkdir -p $DIR/$tdir
18882         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18883
18884         # inherit default DoM striping
18885         mkdir $DIR/$tdir/subdir
18886         touch $DIR/$tdir/subdir/f1
18887
18888         # change default directory striping
18889         $LFS setstripe -c 1 $DIR/$tdir/subdir
18890         touch $DIR/$tdir/subdir/f2
18891         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
18892                 error "wrong default striping in file 2"
18893         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
18894                 error "bad pattern in file 2"
18895         return 0
18896 }
18897 run_test 270d "DoM: change striping from DoM to RAID0"
18898
18899 test_270e() {
18900         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18901                 skip "Need MDS version at least 2.10.55"
18902
18903         mkdir -p $DIR/$tdir/dom
18904         mkdir -p $DIR/$tdir/norm
18905         DOMFILES=20
18906         NORMFILES=10
18907         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
18908         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
18909
18910         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
18911         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
18912
18913         # find DoM files by layout
18914         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
18915         [ $NUM -eq  $DOMFILES ] ||
18916                 error "lfs find -L: found $NUM, expected $DOMFILES"
18917         echo "Test 1: lfs find 20 DOM files by layout: OK"
18918
18919         # there should be 1 dir with default DOM striping
18920         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
18921         [ $NUM -eq  1 ] ||
18922                 error "lfs find -L: found $NUM, expected 1 dir"
18923         echo "Test 2: lfs find 1 DOM dir by layout: OK"
18924
18925         # find DoM files by stripe size
18926         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
18927         [ $NUM -eq  $DOMFILES ] ||
18928                 error "lfs find -S: found $NUM, expected $DOMFILES"
18929         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
18930
18931         # find files by stripe offset except DoM files
18932         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
18933         [ $NUM -eq  $NORMFILES ] ||
18934                 error "lfs find -i: found $NUM, expected $NORMFILES"
18935         echo "Test 5: lfs find no DOM files by stripe index: OK"
18936         return 0
18937 }
18938 run_test 270e "DoM: lfs find with DoM files test"
18939
18940 test_270f() {
18941         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18942                 skip "Need MDS version at least 2.10.55"
18943
18944         local mdtname=${FSNAME}-MDT0000-mdtlov
18945         local dom=$DIR/$tdir/dom_file
18946         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
18947                                                 lod.$mdtname.dom_stripesize)
18948         local dom_limit=131072
18949
18950         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
18951         local dom_current=$(do_facet mds1 $LCTL get_param -n \
18952                                                 lod.$mdtname.dom_stripesize)
18953         [ ${dom_limit} -eq ${dom_current} ] ||
18954                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
18955
18956         $LFS mkdir -i 0 -c 1 $DIR/$tdir
18957         $LFS setstripe -d $DIR/$tdir
18958         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
18959                 error "Can't set directory default striping"
18960
18961         # exceed maximum stripe size
18962         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
18963                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
18964         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
18965                 error "Able to create DoM component size more than LOD limit"
18966
18967         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
18968         dom_current=$(do_facet mds1 $LCTL get_param -n \
18969                                                 lod.$mdtname.dom_stripesize)
18970         [ 0 -eq ${dom_current} ] ||
18971                 error "Can't set zero DoM stripe limit"
18972         rm $dom
18973
18974         # attempt to create DoM file on server with disabled DoM should
18975         # remove DoM entry from layout and be succeed
18976         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
18977                 error "Can't create DoM file (DoM is disabled)"
18978         [ $($LFS getstripe -L $dom) == "mdt" ] &&
18979                 error "File has DoM component while DoM is disabled"
18980         rm $dom
18981
18982         # attempt to create DoM file with only DoM stripe should return error
18983         $LFS setstripe -E $dom_limit -L mdt $dom &&
18984                 error "Able to create DoM-only file while DoM is disabled"
18985
18986         # too low values to be aligned with smallest stripe size 64K
18987         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
18988         dom_current=$(do_facet mds1 $LCTL get_param -n \
18989                                                 lod.$mdtname.dom_stripesize)
18990         [ 30000 -eq ${dom_current} ] &&
18991                 error "Can set too small DoM stripe limit"
18992
18993         # 64K is a minimal stripe size in Lustre, expect limit of that size
18994         [ 65536 -eq ${dom_current} ] ||
18995                 error "Limit is not set to 64K but ${dom_current}"
18996
18997         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
18998         dom_current=$(do_facet mds1 $LCTL get_param -n \
18999                                                 lod.$mdtname.dom_stripesize)
19000         echo $dom_current
19001         [ 2147483648 -eq ${dom_current} ] &&
19002                 error "Can set too large DoM stripe limit"
19003
19004         do_facet mds1 $LCTL set_param -n \
19005                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
19006         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
19007                 error "Can't create DoM component size after limit change"
19008         do_facet mds1 $LCTL set_param -n \
19009                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
19010         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
19011                 error "Can't create DoM file after limit decrease"
19012         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
19013                 error "Can create big DoM component after limit decrease"
19014         touch ${dom}_def ||
19015                 error "Can't create file with old default layout"
19016
19017         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
19018         return 0
19019 }
19020 run_test 270f "DoM: maximum DoM stripe size checks"
19021
19022 test_271a() {
19023         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19024                 skip "Need MDS version at least 2.10.55"
19025
19026         local dom=$DIR/$tdir/dom
19027
19028         mkdir -p $DIR/$tdir
19029
19030         $LFS setstripe -E 1024K -L mdt $dom
19031
19032         lctl set_param -n mdc.*.stats=clear
19033         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
19034         cat $dom > /dev/null
19035         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
19036         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
19037         ls $dom
19038         rm -f $dom
19039 }
19040 run_test 271a "DoM: data is cached for read after write"
19041
19042 test_271b() {
19043         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19044                 skip "Need MDS version at least 2.10.55"
19045
19046         local dom=$DIR/$tdir/dom
19047
19048         mkdir -p $DIR/$tdir
19049
19050         $LFS setstripe -E 1024K -L mdt -E EOF $dom
19051
19052         lctl set_param -n mdc.*.stats=clear
19053         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
19054         cancel_lru_locks mdc
19055         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
19056         # second stat to check size is cached on client
19057         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
19058         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
19059         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
19060         rm -f $dom
19061 }
19062 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
19063
19064 test_271ba() {
19065         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19066                 skip "Need MDS version at least 2.10.55"
19067
19068         local dom=$DIR/$tdir/dom
19069
19070         mkdir -p $DIR/$tdir
19071
19072         $LFS setstripe -E 1024K -L mdt -E EOF $dom
19073
19074         lctl set_param -n mdc.*.stats=clear
19075         lctl set_param -n osc.*.stats=clear
19076         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
19077         cancel_lru_locks mdc
19078         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
19079         # second stat to check size is cached on client
19080         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
19081         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
19082         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
19083         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
19084         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
19085         rm -f $dom
19086 }
19087 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
19088
19089
19090 get_mdc_stats() {
19091         local mdtidx=$1
19092         local param=$2
19093         local mdt=MDT$(printf %04x $mdtidx)
19094
19095         if [ -z $param ]; then
19096                 lctl get_param -n mdc.*$mdt*.stats
19097         else
19098                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
19099         fi
19100 }
19101
19102 test_271c() {
19103         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19104                 skip "Need MDS version at least 2.10.55"
19105
19106         local dom=$DIR/$tdir/dom
19107
19108         mkdir -p $DIR/$tdir
19109
19110         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
19111
19112         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
19113         local facet=mds$((mdtidx + 1))
19114
19115         cancel_lru_locks mdc
19116         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
19117         createmany -o $dom 1000
19118         lctl set_param -n mdc.*.stats=clear
19119         smalliomany -w $dom 1000 200
19120         get_mdc_stats $mdtidx
19121         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
19122         # Each file has 1 open, 1 IO enqueues, total 2000
19123         # but now we have also +1 getxattr for security.capability, total 3000
19124         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
19125         unlinkmany $dom 1000
19126
19127         cancel_lru_locks mdc
19128         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
19129         createmany -o $dom 1000
19130         lctl set_param -n mdc.*.stats=clear
19131         smalliomany -w $dom 1000 200
19132         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
19133         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
19134         # for OPEN and IO lock.
19135         [ $((enq - enq_2)) -ge 1000 ] ||
19136                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
19137         unlinkmany $dom 1000
19138         return 0
19139 }
19140 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
19141
19142 cleanup_271def_tests() {
19143         trap 0
19144         rm -f $1
19145 }
19146
19147 test_271d() {
19148         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
19149                 skip "Need MDS version at least 2.10.57"
19150
19151         local dom=$DIR/$tdir/dom
19152         local tmp=$TMP/$tfile
19153         trap "cleanup_271def_tests $tmp" EXIT
19154
19155         mkdir -p $DIR/$tdir
19156
19157         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
19158
19159         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
19160
19161         cancel_lru_locks mdc
19162         dd if=/dev/urandom of=$tmp bs=1000 count=1
19163         dd if=$tmp of=$dom bs=1000 count=1
19164         cancel_lru_locks mdc
19165
19166         cat /etc/hosts >> $tmp
19167         lctl set_param -n mdc.*.stats=clear
19168
19169         # append data to the same file it should update local page
19170         echo "Append to the same page"
19171         cat /etc/hosts >> $dom
19172         local num=$(get_mdc_stats $mdtidx ost_read)
19173         local ra=$(get_mdc_stats $mdtidx req_active)
19174         local rw=$(get_mdc_stats $mdtidx req_waittime)
19175
19176         [ -z $num ] || error "$num READ RPC occured"
19177         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
19178         echo "... DONE"
19179
19180         # compare content
19181         cmp $tmp $dom || error "file miscompare"
19182
19183         cancel_lru_locks mdc
19184         lctl set_param -n mdc.*.stats=clear
19185
19186         echo "Open and read file"
19187         cat $dom > /dev/null
19188         local num=$(get_mdc_stats $mdtidx ost_read)
19189         local ra=$(get_mdc_stats $mdtidx req_active)
19190         local rw=$(get_mdc_stats $mdtidx req_waittime)
19191
19192         [ -z $num ] || error "$num READ RPC occured"
19193         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
19194         echo "... DONE"
19195
19196         # compare content
19197         cmp $tmp $dom || error "file miscompare"
19198
19199         return 0
19200 }
19201 run_test 271d "DoM: read on open (1K file in reply buffer)"
19202
19203 test_271f() {
19204         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
19205                 skip "Need MDS version at least 2.10.57"
19206
19207         local dom=$DIR/$tdir/dom
19208         local tmp=$TMP/$tfile
19209         trap "cleanup_271def_tests $tmp" EXIT
19210
19211         mkdir -p $DIR/$tdir
19212
19213         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
19214
19215         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
19216
19217         cancel_lru_locks mdc
19218         dd if=/dev/urandom of=$tmp bs=265000 count=1
19219         dd if=$tmp of=$dom bs=265000 count=1
19220         cancel_lru_locks mdc
19221         cat /etc/hosts >> $tmp
19222         lctl set_param -n mdc.*.stats=clear
19223
19224         echo "Append to the same page"
19225         cat /etc/hosts >> $dom
19226         local num=$(get_mdc_stats $mdtidx ost_read)
19227         local ra=$(get_mdc_stats $mdtidx req_active)
19228         local rw=$(get_mdc_stats $mdtidx req_waittime)
19229
19230         [ -z $num ] || error "$num READ RPC occured"
19231         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
19232         echo "... DONE"
19233
19234         # compare content
19235         cmp $tmp $dom || error "file miscompare"
19236
19237         cancel_lru_locks mdc
19238         lctl set_param -n mdc.*.stats=clear
19239
19240         echo "Open and read file"
19241         cat $dom > /dev/null
19242         local num=$(get_mdc_stats $mdtidx ost_read)
19243         local ra=$(get_mdc_stats $mdtidx req_active)
19244         local rw=$(get_mdc_stats $mdtidx req_waittime)
19245
19246         [ -z $num ] && num=0
19247         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
19248         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
19249         echo "... DONE"
19250
19251         # compare content
19252         cmp $tmp $dom || error "file miscompare"
19253
19254         return 0
19255 }
19256 run_test 271f "DoM: read on open (200K file and read tail)"
19257
19258 test_271g() {
19259         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
19260                 skip "Skipping due to old client or server version"
19261
19262         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
19263         # to get layout
19264         $CHECKSTAT -t file $DIR1/$tfile
19265
19266         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
19267         MULTIOP_PID=$!
19268         sleep 1
19269         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
19270         $LCTL set_param fail_loc=0x80000314
19271         rm $DIR1/$tfile || error "Unlink fails"
19272         RC=$?
19273         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
19274         [ $RC -eq 0 ] || error "Failed write to stale object"
19275 }
19276 run_test 271g "Discard DoM data vs client flush race"
19277
19278 test_272a() {
19279         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
19280                 skip "Need MDS version at least 2.11.50"
19281
19282         local dom=$DIR/$tdir/dom
19283         mkdir -p $DIR/$tdir
19284
19285         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
19286         dd if=/dev/urandom of=$dom bs=512K count=1 ||
19287                 error "failed to write data into $dom"
19288         local old_md5=$(md5sum $dom)
19289
19290         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
19291                 error "failed to migrate to the same DoM component"
19292
19293         local new_md5=$(md5sum $dom)
19294
19295         [ "$old_md5" == "$new_md5" ] ||
19296                 error "md5sum differ: $old_md5, $new_md5"
19297
19298         [ $($LFS getstripe -c $dom) -eq 2 ] ||
19299                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
19300 }
19301 run_test 272a "DoM migration: new layout with the same DOM component"
19302
19303 test_272b() {
19304         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
19305                 skip "Need MDS version at least 2.11.50"
19306
19307         local dom=$DIR/$tdir/dom
19308         mkdir -p $DIR/$tdir
19309         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
19310
19311         local mdtidx=$($LFS getstripe -m $dom)
19312         local mdtname=MDT$(printf %04x $mdtidx)
19313         local facet=mds$((mdtidx + 1))
19314
19315         local mdtfree1=$(do_facet $facet \
19316                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19317         dd if=/dev/urandom of=$dom bs=2M count=1 ||
19318                 error "failed to write data into $dom"
19319         local old_md5=$(md5sum $dom)
19320         cancel_lru_locks mdc
19321         local mdtfree1=$(do_facet $facet \
19322                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19323
19324         $LFS migrate -c2 $dom ||
19325                 error "failed to migrate to the new composite layout"
19326         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
19327                 error "MDT stripe was not removed"
19328
19329         cancel_lru_locks mdc
19330         local new_md5=$(md5sum $dom)
19331         [ "$old_md5" == "$new_md5" ] ||
19332                 error "$old_md5 != $new_md5"
19333
19334         # Skip free space checks with ZFS
19335         if [ "$(facet_fstype $facet)" != "zfs" ]; then
19336                 local mdtfree2=$(do_facet $facet \
19337                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19338                 [ $mdtfree2 -gt $mdtfree1 ] ||
19339                         error "MDT space is not freed after migration"
19340         fi
19341         return 0
19342 }
19343 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
19344
19345 test_272c() {
19346         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
19347                 skip "Need MDS version at least 2.11.50"
19348
19349         local dom=$DIR/$tdir/$tfile
19350         mkdir -p $DIR/$tdir
19351         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
19352
19353         local mdtidx=$($LFS getstripe -m $dom)
19354         local mdtname=MDT$(printf %04x $mdtidx)
19355         local facet=mds$((mdtidx + 1))
19356
19357         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
19358                 error "failed to write data into $dom"
19359         local old_md5=$(md5sum $dom)
19360         cancel_lru_locks mdc
19361         local mdtfree1=$(do_facet $facet \
19362                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19363
19364         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
19365                 error "failed to migrate to the new composite layout"
19366         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
19367                 error "MDT stripe was not removed"
19368
19369         cancel_lru_locks mdc
19370         local new_md5=$(md5sum $dom)
19371         [ "$old_md5" == "$new_md5" ] ||
19372                 error "$old_md5 != $new_md5"
19373
19374         # Skip free space checks with ZFS
19375         if [ "$(facet_fstype $facet)" != "zfs" ]; then
19376                 local mdtfree2=$(do_facet $facet \
19377                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19378                 [ $mdtfree2 -gt $mdtfree1 ] ||
19379                         error "MDS space is not freed after migration"
19380         fi
19381         return 0
19382 }
19383 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
19384
19385 test_272d() {
19386         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
19387                 skip "Need MDS version at least 2.12.55"
19388
19389         local dom=$DIR/$tdir/$tfile
19390         mkdir -p $DIR/$tdir
19391         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
19392
19393         local mdtidx=$($LFS getstripe -m $dom)
19394         local mdtname=MDT$(printf %04x $mdtidx)
19395         local facet=mds$((mdtidx + 1))
19396
19397         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
19398                 error "failed to write data into $dom"
19399         local old_md5=$(md5sum $dom)
19400         cancel_lru_locks mdc
19401         local mdtfree1=$(do_facet $facet \
19402                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19403
19404         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
19405                 error "failed mirroring to the new composite layout"
19406         $LFS mirror resync $dom ||
19407                 error "failed mirror resync"
19408         $LFS mirror split --mirror-id 1 -d $dom ||
19409                 error "failed mirror split"
19410
19411         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
19412                 error "MDT stripe was not removed"
19413
19414         cancel_lru_locks mdc
19415         local new_md5=$(md5sum $dom)
19416         [ "$old_md5" == "$new_md5" ] ||
19417                 error "$old_md5 != $new_md5"
19418
19419         # Skip free space checks with ZFS
19420         if [ "$(facet_fstype $facet)" != "zfs" ]; then
19421                 local mdtfree2=$(do_facet $facet \
19422                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19423                 [ $mdtfree2 -gt $mdtfree1 ] ||
19424                         error "MDS space is not freed after DOM mirror deletion"
19425         fi
19426         return 0
19427 }
19428 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
19429
19430 test_272e() {
19431         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
19432                 skip "Need MDS version at least 2.12.55"
19433
19434         local dom=$DIR/$tdir/$tfile
19435         mkdir -p $DIR/$tdir
19436         $LFS setstripe -c 2 $dom
19437
19438         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
19439                 error "failed to write data into $dom"
19440         local old_md5=$(md5sum $dom)
19441         cancel_lru_locks mdc
19442
19443         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
19444                 error "failed mirroring to the DOM layout"
19445         $LFS mirror resync $dom ||
19446                 error "failed mirror resync"
19447         $LFS mirror split --mirror-id 1 -d $dom ||
19448                 error "failed mirror split"
19449
19450         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
19451                 error "MDT stripe was not removed"
19452
19453         cancel_lru_locks mdc
19454         local new_md5=$(md5sum $dom)
19455         [ "$old_md5" == "$new_md5" ] ||
19456                 error "$old_md5 != $new_md5"
19457
19458         return 0
19459 }
19460 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
19461
19462 test_272f() {
19463         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
19464                 skip "Need MDS version at least 2.12.55"
19465
19466         local dom=$DIR/$tdir/$tfile
19467         mkdir -p $DIR/$tdir
19468         $LFS setstripe -c 2 $dom
19469
19470         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
19471                 error "failed to write data into $dom"
19472         local old_md5=$(md5sum $dom)
19473         cancel_lru_locks mdc
19474
19475         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
19476                 error "failed migrating to the DOM file"
19477
19478         cancel_lru_locks mdc
19479         local new_md5=$(md5sum $dom)
19480         [ "$old_md5" != "$new_md5" ] &&
19481                 error "$old_md5 != $new_md5"
19482
19483         return 0
19484 }
19485 run_test 272f "DoM migration: OST-striped file to DOM file"
19486
19487 test_273a() {
19488         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
19489                 skip "Need MDS version at least 2.11.50"
19490
19491         # Layout swap cannot be done if either file has DOM component,
19492         # this will never be supported, migration should be used instead
19493
19494         local dom=$DIR/$tdir/$tfile
19495         mkdir -p $DIR/$tdir
19496
19497         $LFS setstripe -c2 ${dom}_plain
19498         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
19499         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
19500                 error "can swap layout with DoM component"
19501         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
19502                 error "can swap layout with DoM component"
19503
19504         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
19505         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
19506                 error "can swap layout with DoM component"
19507         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
19508                 error "can swap layout with DoM component"
19509         return 0
19510 }
19511 run_test 273a "DoM: layout swapping should fail with DOM"
19512
19513 test_275() {
19514         remote_ost_nodsh && skip "remote OST with nodsh"
19515         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
19516                 skip "Need OST version >= 2.10.57"
19517
19518         local file=$DIR/$tfile
19519         local oss
19520
19521         oss=$(comma_list $(osts_nodes))
19522
19523         dd if=/dev/urandom of=$file bs=1M count=2 ||
19524                 error "failed to create a file"
19525         cancel_lru_locks osc
19526
19527         #lock 1
19528         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
19529                 error "failed to read a file"
19530
19531 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
19532         $LCTL set_param fail_loc=0x8000031f
19533
19534         cancel_lru_locks osc &
19535         sleep 1
19536
19537 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
19538         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
19539         #IO takes another lock, but matches the PENDING one
19540         #and places it to the IO RPC
19541         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
19542                 error "failed to read a file with PENDING lock"
19543 }
19544 run_test 275 "Read on a canceled duplicate lock"
19545
19546 test_276() {
19547         remote_ost_nodsh && skip "remote OST with nodsh"
19548         local pid
19549
19550         do_facet ost1 "(while true; do \
19551                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
19552                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
19553         pid=$!
19554
19555         for LOOP in $(seq 20); do
19556                 stop ost1
19557                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
19558         done
19559         kill -9 $pid
19560         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
19561                 rm $TMP/sanity_276_pid"
19562 }
19563 run_test 276 "Race between mount and obd_statfs"
19564
19565 test_277() {
19566         $LCTL set_param ldlm.namespaces.*.lru_size=0
19567         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
19568         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
19569                         grep ^used_mb | awk '{print $2}')
19570         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
19571         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
19572                 oflag=direct conv=notrunc
19573         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
19574                         grep ^used_mb | awk '{print $2}')
19575         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
19576 }
19577 run_test 277 "Direct IO shall drop page cache"
19578
19579 test_278() {
19580         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
19581         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
19582         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
19583                 skip "needs the same host for mdt1 mdt2" && return
19584
19585         local pid1
19586         local pid2
19587
19588 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
19589         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
19590         stop mds2 &
19591         pid2=$!
19592
19593         stop mds1
19594
19595         echo "Starting MDTs"
19596         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
19597         wait $pid2
19598 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
19599 #will return NULL
19600         do_facet mds2 $LCTL set_param fail_loc=0
19601
19602         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
19603         wait_recovery_complete mds2
19604 }
19605 run_test 278 "Race starting MDS between MDTs stop/start"
19606
19607 test_280() {
19608         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
19609                 skip "Need MGS version at least 2.13.52"
19610         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19611         combined_mgs_mds || skip "needs combined MGS/MDT"
19612
19613         umount_client $MOUNT
19614 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
19615         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
19616
19617         mount_client $MOUNT &
19618         sleep 1
19619         stop mgs || error "stop mgs failed"
19620         #for a race mgs would crash
19621         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
19622         mount_client $MOUNT || error "mount client failed"
19623 }
19624 run_test 280 "Race between MGS umount and client llog processing"
19625
19626 cleanup_test_300() {
19627         trap 0
19628         umask $SAVE_UMASK
19629 }
19630 test_striped_dir() {
19631         local mdt_index=$1
19632         local stripe_count
19633         local stripe_index
19634
19635         mkdir -p $DIR/$tdir
19636
19637         SAVE_UMASK=$(umask)
19638         trap cleanup_test_300 RETURN EXIT
19639
19640         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
19641                                                 $DIR/$tdir/striped_dir ||
19642                 error "set striped dir error"
19643
19644         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
19645         [ "$mode" = "755" ] || error "expect 755 got $mode"
19646
19647         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
19648                 error "getdirstripe failed"
19649         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
19650         if [ "$stripe_count" != "2" ]; then
19651                 error "1:stripe_count is $stripe_count, expect 2"
19652         fi
19653         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
19654         if [ "$stripe_count" != "2" ]; then
19655                 error "2:stripe_count is $stripe_count, expect 2"
19656         fi
19657
19658         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
19659         if [ "$stripe_index" != "$mdt_index" ]; then
19660                 error "stripe_index is $stripe_index, expect $mdt_index"
19661         fi
19662
19663         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
19664                 error "nlink error after create striped dir"
19665
19666         mkdir $DIR/$tdir/striped_dir/a
19667         mkdir $DIR/$tdir/striped_dir/b
19668
19669         stat $DIR/$tdir/striped_dir/a ||
19670                 error "create dir under striped dir failed"
19671         stat $DIR/$tdir/striped_dir/b ||
19672                 error "create dir under striped dir failed"
19673
19674         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
19675                 error "nlink error after mkdir"
19676
19677         rmdir $DIR/$tdir/striped_dir/a
19678         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
19679                 error "nlink error after rmdir"
19680
19681         rmdir $DIR/$tdir/striped_dir/b
19682         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
19683                 error "nlink error after rmdir"
19684
19685         chattr +i $DIR/$tdir/striped_dir
19686         createmany -o $DIR/$tdir/striped_dir/f 10 &&
19687                 error "immutable flags not working under striped dir!"
19688         chattr -i $DIR/$tdir/striped_dir
19689
19690         rmdir $DIR/$tdir/striped_dir ||
19691                 error "rmdir striped dir error"
19692
19693         cleanup_test_300
19694
19695         true
19696 }
19697
19698 test_300a() {
19699         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
19700                 skip "skipped for lustre < 2.7.0"
19701         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19702         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19703
19704         test_striped_dir 0 || error "failed on striped dir on MDT0"
19705         test_striped_dir 1 || error "failed on striped dir on MDT0"
19706 }
19707 run_test 300a "basic striped dir sanity test"
19708
19709 test_300b() {
19710         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
19711                 skip "skipped for lustre < 2.7.0"
19712         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19713         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19714
19715         local i
19716         local mtime1
19717         local mtime2
19718         local mtime3
19719
19720         test_mkdir $DIR/$tdir || error "mkdir fail"
19721         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
19722                 error "set striped dir error"
19723         for i in {0..9}; do
19724                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
19725                 sleep 1
19726                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
19727                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
19728                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
19729                 sleep 1
19730                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
19731                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
19732                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
19733         done
19734         true
19735 }
19736 run_test 300b "check ctime/mtime for striped dir"
19737
19738 test_300c() {
19739         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
19740                 skip "skipped for lustre < 2.7.0"
19741         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19742         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19743
19744         local file_count
19745
19746         mkdir -p $DIR/$tdir
19747         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
19748                 error "set striped dir error"
19749
19750         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
19751                 error "chown striped dir failed"
19752
19753         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
19754                 error "create 5k files failed"
19755
19756         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
19757
19758         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
19759
19760         rm -rf $DIR/$tdir
19761 }
19762 run_test 300c "chown && check ls under striped directory"
19763
19764 test_300d() {
19765         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
19766                 skip "skipped for lustre < 2.7.0"
19767         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19768         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19769
19770         local stripe_count
19771         local file
19772
19773         mkdir -p $DIR/$tdir
19774         $LFS setstripe -c 2 $DIR/$tdir
19775
19776         #local striped directory
19777         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
19778                 error "set striped dir error"
19779         #look at the directories for debug purposes
19780         ls -l $DIR/$tdir
19781         $LFS getdirstripe $DIR/$tdir
19782         ls -l $DIR/$tdir/striped_dir
19783         $LFS getdirstripe $DIR/$tdir/striped_dir
19784         createmany -o $DIR/$tdir/striped_dir/f 10 ||
19785                 error "create 10 files failed"
19786
19787         #remote striped directory
19788         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
19789                 error "set striped dir error"
19790         #look at the directories for debug purposes
19791         ls -l $DIR/$tdir
19792         $LFS getdirstripe $DIR/$tdir
19793         ls -l $DIR/$tdir/remote_striped_dir
19794         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
19795         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
19796                 error "create 10 files failed"
19797
19798         for file in $(find $DIR/$tdir); do
19799                 stripe_count=$($LFS getstripe -c $file)
19800                 [ $stripe_count -eq 2 ] ||
19801                         error "wrong stripe $stripe_count for $file"
19802         done
19803
19804         rm -rf $DIR/$tdir
19805 }
19806 run_test 300d "check default stripe under striped directory"
19807
19808 test_300e() {
19809         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19810                 skip "Need MDS version at least 2.7.55"
19811         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19812         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19813
19814         local stripe_count
19815         local file
19816
19817         mkdir -p $DIR/$tdir
19818
19819         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
19820                 error "set striped dir error"
19821
19822         touch $DIR/$tdir/striped_dir/a
19823         touch $DIR/$tdir/striped_dir/b
19824         touch $DIR/$tdir/striped_dir/c
19825
19826         mkdir $DIR/$tdir/striped_dir/dir_a
19827         mkdir $DIR/$tdir/striped_dir/dir_b
19828         mkdir $DIR/$tdir/striped_dir/dir_c
19829
19830         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
19831                 error "set striped adir under striped dir error"
19832
19833         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
19834                 error "set striped bdir under striped dir error"
19835
19836         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
19837                 error "set striped cdir under striped dir error"
19838
19839         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
19840                 error "rename dir under striped dir fails"
19841
19842         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
19843                 error "rename dir under different stripes fails"
19844
19845         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
19846                 error "rename file under striped dir should succeed"
19847
19848         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
19849                 error "rename dir under striped dir should succeed"
19850
19851         rm -rf $DIR/$tdir
19852 }
19853 run_test 300e "check rename under striped directory"
19854
19855 test_300f() {
19856         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19857         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19858         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19859                 skip "Need MDS version at least 2.7.55"
19860
19861         local stripe_count
19862         local file
19863
19864         rm -rf $DIR/$tdir
19865         mkdir -p $DIR/$tdir
19866
19867         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
19868                 error "set striped dir error"
19869
19870         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
19871                 error "set striped dir error"
19872
19873         touch $DIR/$tdir/striped_dir/a
19874         mkdir $DIR/$tdir/striped_dir/dir_a
19875         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
19876                 error "create striped dir under striped dir fails"
19877
19878         touch $DIR/$tdir/striped_dir1/b
19879         mkdir $DIR/$tdir/striped_dir1/dir_b
19880         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
19881                 error "create striped dir under striped dir fails"
19882
19883         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
19884                 error "rename dir under different striped dir should fail"
19885
19886         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
19887                 error "rename striped dir under diff striped dir should fail"
19888
19889         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
19890                 error "rename file under diff striped dirs fails"
19891
19892         rm -rf $DIR/$tdir
19893 }
19894 run_test 300f "check rename cross striped directory"
19895
19896 test_300_check_default_striped_dir()
19897 {
19898         local dirname=$1
19899         local default_count=$2
19900         local default_index=$3
19901         local stripe_count
19902         local stripe_index
19903         local dir_stripe_index
19904         local dir
19905
19906         echo "checking $dirname $default_count $default_index"
19907         $LFS setdirstripe -D -c $default_count -i $default_index \
19908                                 -t all_char $DIR/$tdir/$dirname ||
19909                 error "set default stripe on striped dir error"
19910         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
19911         [ $stripe_count -eq $default_count ] ||
19912                 error "expect $default_count get $stripe_count for $dirname"
19913
19914         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
19915         [ $stripe_index -eq $default_index ] ||
19916                 error "expect $default_index get $stripe_index for $dirname"
19917
19918         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
19919                                                 error "create dirs failed"
19920
19921         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
19922         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
19923         for dir in $(find $DIR/$tdir/$dirname/*); do
19924                 stripe_count=$($LFS getdirstripe -c $dir)
19925                 [ $stripe_count -eq $default_count ] ||
19926                 [ $stripe_count -eq 0 ] || [ $default_count -eq 1 ] ||
19927                 error "stripe count $default_count != $stripe_count for $dir"
19928
19929                 stripe_index=$($LFS getdirstripe -i $dir)
19930                 [ $default_index -eq -1 ] ||
19931                         [ $stripe_index -eq $default_index ] ||
19932                         error "$stripe_index != $default_index for $dir"
19933
19934                 #check default stripe
19935                 stripe_count=$($LFS getdirstripe -D -c $dir)
19936                 [ $stripe_count -eq $default_count ] ||
19937                 error "default count $default_count != $stripe_count for $dir"
19938
19939                 stripe_index=$($LFS getdirstripe -D -i $dir)
19940                 [ $stripe_index -eq $default_index ] ||
19941                 error "default index $default_index != $stripe_index for $dir"
19942         done
19943         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
19944 }
19945
19946 test_300g() {
19947         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19948         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19949                 skip "Need MDS version at least 2.7.55"
19950
19951         local dir
19952         local stripe_count
19953         local stripe_index
19954
19955         mkdir $DIR/$tdir
19956         mkdir $DIR/$tdir/normal_dir
19957
19958         #Checking when client cache stripe index
19959         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
19960         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
19961                 error "create striped_dir failed"
19962
19963         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
19964                 error "create dir0 fails"
19965         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
19966         [ $stripe_index -eq 0 ] ||
19967                 error "dir0 expect index 0 got $stripe_index"
19968
19969         mkdir $DIR/$tdir/striped_dir/dir1 ||
19970                 error "create dir1 fails"
19971         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
19972         [ $stripe_index -eq 1 ] ||
19973                 error "dir1 expect index 1 got $stripe_index"
19974
19975         #check default stripe count/stripe index
19976         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
19977         test_300_check_default_striped_dir normal_dir 1 0
19978         test_300_check_default_striped_dir normal_dir 2 1
19979         test_300_check_default_striped_dir normal_dir 2 -1
19980
19981         #delete default stripe information
19982         echo "delete default stripeEA"
19983         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
19984                 error "set default stripe on striped dir error"
19985
19986         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
19987         for dir in $(find $DIR/$tdir/normal_dir/*); do
19988                 stripe_count=$($LFS getdirstripe -c $dir)
19989                 [ $stripe_count -eq 0 ] ||
19990                         error "expect 1 get $stripe_count for $dir"
19991                 stripe_index=$($LFS getdirstripe -i $dir)
19992                 [ $stripe_index -eq 0 ] ||
19993                         error "expect 0 get $stripe_index for $dir"
19994         done
19995 }
19996 run_test 300g "check default striped directory for normal directory"
19997
19998 test_300h() {
19999         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20000         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20001                 skip "Need MDS version at least 2.7.55"
20002
20003         local dir
20004         local stripe_count
20005
20006         mkdir $DIR/$tdir
20007         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
20008                 error "set striped dir error"
20009
20010         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
20011         test_300_check_default_striped_dir striped_dir 1 0
20012         test_300_check_default_striped_dir striped_dir 2 1
20013         test_300_check_default_striped_dir striped_dir 2 -1
20014
20015         #delete default stripe information
20016         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
20017                 error "set default stripe on striped dir error"
20018
20019         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
20020         for dir in $(find $DIR/$tdir/striped_dir/*); do
20021                 stripe_count=$($LFS getdirstripe -c $dir)
20022                 [ $stripe_count -eq 0 ] ||
20023                         error "expect 1 get $stripe_count for $dir"
20024         done
20025 }
20026 run_test 300h "check default striped directory for striped directory"
20027
20028 test_300i() {
20029         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20030         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20031         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20032                 skip "Need MDS version at least 2.7.55"
20033
20034         local stripe_count
20035         local file
20036
20037         mkdir $DIR/$tdir
20038
20039         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
20040                 error "set striped dir error"
20041
20042         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
20043                 error "create files under striped dir failed"
20044
20045         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
20046                 error "set striped hashdir error"
20047
20048         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
20049                 error "create dir0 under hash dir failed"
20050         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
20051                 error "create dir1 under hash dir failed"
20052
20053         # unfortunately, we need to umount to clear dir layout cache for now
20054         # once we fully implement dir layout, we can drop this
20055         umount_client $MOUNT || error "umount failed"
20056         mount_client $MOUNT || error "mount failed"
20057
20058         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
20059         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
20060         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
20061
20062         #set the stripe to be unknown hash type
20063         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
20064         $LCTL set_param fail_loc=0x1901
20065         for ((i = 0; i < 10; i++)); do
20066                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
20067                         error "stat f-$i failed"
20068                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
20069         done
20070
20071         touch $DIR/$tdir/striped_dir/f0 &&
20072                 error "create under striped dir with unknown hash should fail"
20073
20074         $LCTL set_param fail_loc=0
20075
20076         umount_client $MOUNT || error "umount failed"
20077         mount_client $MOUNT || error "mount failed"
20078
20079         return 0
20080 }
20081 run_test 300i "client handle unknown hash type striped directory"
20082
20083 test_300j() {
20084         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20085         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20086         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20087                 skip "Need MDS version at least 2.7.55"
20088
20089         local stripe_count
20090         local file
20091
20092         mkdir $DIR/$tdir
20093
20094         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
20095         $LCTL set_param fail_loc=0x1702
20096         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
20097                 error "set striped dir error"
20098
20099         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
20100                 error "create files under striped dir failed"
20101
20102         $LCTL set_param fail_loc=0
20103
20104         rm -rf $DIR/$tdir || error "unlink striped dir fails"
20105
20106         return 0
20107 }
20108 run_test 300j "test large update record"
20109
20110 test_300k() {
20111         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20112         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20113         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20114                 skip "Need MDS version at least 2.7.55"
20115
20116         # this test needs a huge transaction
20117         local kb
20118         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
20119              osd*.$FSNAME-MDT0000.kbytestotal")
20120         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
20121
20122         local stripe_count
20123         local file
20124
20125         mkdir $DIR/$tdir
20126
20127         #define OBD_FAIL_LARGE_STRIPE   0x1703
20128         $LCTL set_param fail_loc=0x1703
20129         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
20130                 error "set striped dir error"
20131         $LCTL set_param fail_loc=0
20132
20133         $LFS getdirstripe $DIR/$tdir/striped_dir ||
20134                 error "getstripeddir fails"
20135         rm -rf $DIR/$tdir/striped_dir ||
20136                 error "unlink striped dir fails"
20137
20138         return 0
20139 }
20140 run_test 300k "test large striped directory"
20141
20142 test_300l() {
20143         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20144         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20145         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20146                 skip "Need MDS version at least 2.7.55"
20147
20148         local stripe_index
20149
20150         test_mkdir -p $DIR/$tdir/striped_dir
20151         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
20152                         error "chown $RUNAS_ID failed"
20153         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
20154                 error "set default striped dir failed"
20155
20156         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
20157         $LCTL set_param fail_loc=0x80000158
20158         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
20159
20160         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
20161         [ $stripe_index -eq 1 ] ||
20162                 error "expect 1 get $stripe_index for $dir"
20163 }
20164 run_test 300l "non-root user to create dir under striped dir with stale layout"
20165
20166 test_300m() {
20167         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20168         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
20169         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20170                 skip "Need MDS version at least 2.7.55"
20171
20172         mkdir -p $DIR/$tdir/striped_dir
20173         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
20174                 error "set default stripes dir error"
20175
20176         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
20177
20178         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
20179         [ $stripe_count -eq 0 ] ||
20180                         error "expect 0 get $stripe_count for a"
20181
20182         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
20183                 error "set default stripes dir error"
20184
20185         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
20186
20187         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
20188         [ $stripe_count -eq 0 ] ||
20189                         error "expect 0 get $stripe_count for b"
20190
20191         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
20192                 error "set default stripes dir error"
20193
20194         mkdir $DIR/$tdir/striped_dir/c &&
20195                 error "default stripe_index is invalid, mkdir c should fails"
20196
20197         rm -rf $DIR/$tdir || error "rmdir fails"
20198 }
20199 run_test 300m "setstriped directory on single MDT FS"
20200
20201 cleanup_300n() {
20202         local list=$(comma_list $(mdts_nodes))
20203
20204         trap 0
20205         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
20206 }
20207
20208 test_300n() {
20209         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20210         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20211         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20212                 skip "Need MDS version at least 2.7.55"
20213         remote_mds_nodsh && skip "remote MDS with nodsh"
20214
20215         local stripe_index
20216         local list=$(comma_list $(mdts_nodes))
20217
20218         trap cleanup_300n RETURN EXIT
20219         mkdir -p $DIR/$tdir
20220         chmod 777 $DIR/$tdir
20221         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
20222                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
20223                 error "create striped dir succeeds with gid=0"
20224
20225         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
20226         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
20227                 error "create striped dir fails with gid=-1"
20228
20229         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
20230         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
20231                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
20232                 error "set default striped dir succeeds with gid=0"
20233
20234
20235         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
20236         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
20237                 error "set default striped dir fails with gid=-1"
20238
20239
20240         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
20241         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
20242                                         error "create test_dir fails"
20243         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
20244                                         error "create test_dir1 fails"
20245         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
20246                                         error "create test_dir2 fails"
20247         cleanup_300n
20248 }
20249 run_test 300n "non-root user to create dir under striped dir with default EA"
20250
20251 test_300o() {
20252         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20253         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20254         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20255                 skip "Need MDS version at least 2.7.55"
20256
20257         local numfree1
20258         local numfree2
20259
20260         mkdir -p $DIR/$tdir
20261
20262         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
20263         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
20264         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
20265                 skip "not enough free inodes $numfree1 $numfree2"
20266         fi
20267
20268         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
20269         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
20270         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
20271                 skip "not enough free space $numfree1 $numfree2"
20272         fi
20273
20274         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
20275                 error "setdirstripe fails"
20276
20277         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
20278                 error "create dirs fails"
20279
20280         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
20281         ls $DIR/$tdir/striped_dir > /dev/null ||
20282                 error "ls striped dir fails"
20283         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
20284                 error "unlink big striped dir fails"
20285 }
20286 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
20287
20288 test_300p() {
20289         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20290         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20291         remote_mds_nodsh && skip "remote MDS with nodsh"
20292
20293         mkdir -p $DIR/$tdir
20294
20295         #define OBD_FAIL_OUT_ENOSPC     0x1704
20296         do_facet mds2 lctl set_param fail_loc=0x80001704
20297         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
20298                  && error "create striped directory should fail"
20299
20300         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
20301
20302         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
20303         true
20304 }
20305 run_test 300p "create striped directory without space"
20306
20307 test_300q() {
20308         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20309         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20310
20311         local fd=$(free_fd)
20312         local cmd="exec $fd<$tdir"
20313         cd $DIR
20314         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
20315         eval $cmd
20316         cmd="exec $fd<&-"
20317         trap "eval $cmd" EXIT
20318         cd $tdir || error "cd $tdir fails"
20319         rmdir  ../$tdir || error "rmdir $tdir fails"
20320         mkdir local_dir && error "create dir succeeds"
20321         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
20322         eval $cmd
20323         return 0
20324 }
20325 run_test 300q "create remote directory under orphan directory"
20326
20327 test_300r() {
20328         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20329                 skip "Need MDS version at least 2.7.55" && return
20330         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
20331
20332         mkdir $DIR/$tdir
20333
20334         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
20335                 error "set striped dir error"
20336
20337         $LFS getdirstripe $DIR/$tdir/striped_dir ||
20338                 error "getstripeddir fails"
20339
20340         local stripe_count
20341         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
20342                       awk '/lmv_stripe_count:/ { print $2 }')
20343
20344         [ $MDSCOUNT -ne $stripe_count ] &&
20345                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
20346
20347         rm -rf $DIR/$tdir/striped_dir ||
20348                 error "unlink striped dir fails"
20349 }
20350 run_test 300r "test -1 striped directory"
20351
20352 prepare_remote_file() {
20353         mkdir $DIR/$tdir/src_dir ||
20354                 error "create remote source failed"
20355
20356         cp /etc/hosts $DIR/$tdir/src_dir/a ||
20357                  error "cp to remote source failed"
20358         touch $DIR/$tdir/src_dir/a
20359
20360         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
20361                 error "create remote target dir failed"
20362
20363         touch $DIR/$tdir/tgt_dir/b
20364
20365         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
20366                 error "rename dir cross MDT failed!"
20367
20368         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
20369                 error "src_child still exists after rename"
20370
20371         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
20372                 error "missing file(a) after rename"
20373
20374         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
20375                 error "diff after rename"
20376 }
20377
20378 test_310a() {
20379         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
20380         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20381
20382         local remote_file=$DIR/$tdir/tgt_dir/b
20383
20384         mkdir -p $DIR/$tdir
20385
20386         prepare_remote_file || error "prepare remote file failed"
20387
20388         #open-unlink file
20389         $OPENUNLINK $remote_file $remote_file ||
20390                 error "openunlink $remote_file failed"
20391         $CHECKSTAT -a $remote_file || error "$remote_file exists"
20392 }
20393 run_test 310a "open unlink remote file"
20394
20395 test_310b() {
20396         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
20397         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20398
20399         local remote_file=$DIR/$tdir/tgt_dir/b
20400
20401         mkdir -p $DIR/$tdir
20402
20403         prepare_remote_file || error "prepare remote file failed"
20404
20405         ln $remote_file $DIR/$tfile || error "link failed for remote file"
20406         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
20407         $CHECKSTAT -t file $remote_file || error "check file failed"
20408 }
20409 run_test 310b "unlink remote file with multiple links while open"
20410
20411 test_310c() {
20412         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20413         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
20414
20415         local remote_file=$DIR/$tdir/tgt_dir/b
20416
20417         mkdir -p $DIR/$tdir
20418
20419         prepare_remote_file || error "prepare remote file failed"
20420
20421         ln $remote_file $DIR/$tfile || error "link failed for remote file"
20422         multiop_bg_pause $remote_file O_uc ||
20423                         error "mulitop failed for remote file"
20424         MULTIPID=$!
20425         $MULTIOP $DIR/$tfile Ouc
20426         kill -USR1 $MULTIPID
20427         wait $MULTIPID
20428 }
20429 run_test 310c "open-unlink remote file with multiple links"
20430
20431 #LU-4825
20432 test_311() {
20433         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20434         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
20435         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
20436                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
20437         remote_mds_nodsh && skip "remote MDS with nodsh"
20438
20439         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
20440         local mdts=$(comma_list $(mdts_nodes))
20441
20442         mkdir -p $DIR/$tdir
20443         $LFS setstripe -i 0 -c 1 $DIR/$tdir
20444         createmany -o $DIR/$tdir/$tfile. 1000
20445
20446         # statfs data is not real time, let's just calculate it
20447         old_iused=$((old_iused + 1000))
20448
20449         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
20450                         osp.*OST0000*MDT0000.create_count")
20451         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
20452                                 osp.*OST0000*MDT0000.max_create_count")
20453         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
20454
20455         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
20456         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
20457         [ $index -ne 0 ] || error "$tfile stripe index is 0"
20458
20459         unlinkmany $DIR/$tdir/$tfile. 1000
20460
20461         do_nodes $mdts "$LCTL set_param -n \
20462                         osp.*OST0000*.max_create_count=$max_count"
20463         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
20464                 do_nodes $mdts "$LCTL set_param -n \
20465                                 osp.*OST0000*.create_count=$count"
20466         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
20467                         grep "=0" && error "create_count is zero"
20468
20469         local new_iused
20470         for i in $(seq 120); do
20471                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
20472                 # system may be too busy to destroy all objs in time, use
20473                 # a somewhat small value to not fail autotest
20474                 [ $((old_iused - new_iused)) -gt 400 ] && break
20475                 sleep 1
20476         done
20477
20478         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
20479         [ $((old_iused - new_iused)) -gt 400 ] ||
20480                 error "objs not destroyed after unlink"
20481 }
20482 run_test 311 "disable OSP precreate, and unlink should destroy objs"
20483
20484 zfs_oid_to_objid()
20485 {
20486         local ost=$1
20487         local objid=$2
20488
20489         local vdevdir=$(dirname $(facet_vdevice $ost))
20490         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
20491         local zfs_zapid=$(do_facet $ost $cmd |
20492                           grep -w "/O/0/d$((objid%32))" -C 5 |
20493                           awk '/Object/{getline; print $1}')
20494         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
20495                           awk "/$objid = /"'{printf $3}')
20496
20497         echo $zfs_objid
20498 }
20499
20500 zfs_object_blksz() {
20501         local ost=$1
20502         local objid=$2
20503
20504         local vdevdir=$(dirname $(facet_vdevice $ost))
20505         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
20506         local blksz=$(do_facet $ost $cmd $objid |
20507                       awk '/dblk/{getline; printf $4}')
20508
20509         case "${blksz: -1}" in
20510                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
20511                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
20512                 *) ;;
20513         esac
20514
20515         echo $blksz
20516 }
20517
20518 test_312() { # LU-4856
20519         remote_ost_nodsh && skip "remote OST with nodsh"
20520         [ "$ost1_FSTYPE" = "zfs" ] ||
20521                 skip_env "the test only applies to zfs"
20522
20523         local max_blksz=$(do_facet ost1 \
20524                           $ZFS get -p recordsize $(facet_device ost1) |
20525                           awk '!/VALUE/{print $3}')
20526
20527         # to make life a little bit easier
20528         $LFS mkdir -c 1 -i 0 $DIR/$tdir
20529         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20530
20531         local tf=$DIR/$tdir/$tfile
20532         touch $tf
20533         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
20534
20535         # Get ZFS object id
20536         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
20537         # block size change by sequential overwrite
20538         local bs
20539
20540         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
20541                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
20542
20543                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
20544                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
20545         done
20546         rm -f $tf
20547
20548         # block size change by sequential append write
20549         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
20550         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
20551         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
20552         local count
20553
20554         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
20555                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
20556                         oflag=sync conv=notrunc
20557
20558                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
20559                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
20560                         error "blksz error, actual $blksz, " \
20561                                 "expected: 2 * $count * $PAGE_SIZE"
20562         done
20563         rm -f $tf
20564
20565         # random write
20566         touch $tf
20567         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
20568         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
20569
20570         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
20571         blksz=$(zfs_object_blksz ost1 $zfs_objid)
20572         [ $blksz -eq $PAGE_SIZE ] ||
20573                 error "blksz error: $blksz, expected: $PAGE_SIZE"
20574
20575         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
20576         blksz=$(zfs_object_blksz ost1 $zfs_objid)
20577         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
20578
20579         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
20580         blksz=$(zfs_object_blksz ost1 $zfs_objid)
20581         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
20582 }
20583 run_test 312 "make sure ZFS adjusts its block size by write pattern"
20584
20585 test_313() {
20586         remote_ost_nodsh && skip "remote OST with nodsh"
20587
20588         local file=$DIR/$tfile
20589
20590         rm -f $file
20591         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
20592
20593         # define OBD_FAIL_TGT_RCVD_EIO           0x720
20594         do_facet ost1 "$LCTL set_param fail_loc=0x720"
20595         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
20596                 error "write should failed"
20597         do_facet ost1 "$LCTL set_param fail_loc=0"
20598         rm -f $file
20599 }
20600 run_test 313 "io should fail after last_rcvd update fail"
20601
20602 test_314() {
20603         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
20604
20605         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
20606         do_facet ost1 "$LCTL set_param fail_loc=0x720"
20607         rm -f $DIR/$tfile
20608         wait_delete_completed
20609         do_facet ost1 "$LCTL set_param fail_loc=0"
20610 }
20611 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
20612
20613 test_315() { # LU-618
20614         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
20615
20616         local file=$DIR/$tfile
20617         rm -f $file
20618
20619         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
20620                 error "multiop file write failed"
20621         $MULTIOP $file oO_RDONLY:r4063232_c &
20622         PID=$!
20623
20624         sleep 2
20625
20626         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
20627         kill -USR1 $PID
20628
20629         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
20630         rm -f $file
20631 }
20632 run_test 315 "read should be accounted"
20633
20634 test_316() {
20635         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20636         large_xattr_enabled || skip_env "ea_inode feature disabled"
20637
20638         rm -rf $DIR/$tdir/d
20639         mkdir -p $DIR/$tdir/d
20640         chown nobody $DIR/$tdir/d
20641         touch $DIR/$tdir/d/file
20642
20643         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
20644 }
20645 run_test 316 "lfs mv"
20646
20647 test_317() {
20648         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
20649                 skip "Need MDS version at least 2.11.53"
20650         if [ "$ost1_FSTYPE" == "zfs" ]; then
20651                 skip "LU-10370: no implementation for ZFS"
20652         fi
20653
20654         local trunc_sz
20655         local grant_blk_size
20656
20657         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
20658                         awk '/grant_block_size:/ { print $2; exit; }')
20659         #
20660         # Create File of size 5M. Truncate it to below size's and verify
20661         # blocks count.
20662         #
20663         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
20664                 error "Create file $DIR/$tfile failed"
20665         stack_trap "rm -f $DIR/$tfile" EXIT
20666
20667         for trunc_sz in 2097152 4097 4000 509 0; do
20668                 $TRUNCATE $DIR/$tfile $trunc_sz ||
20669                         error "truncate $tfile to $trunc_sz failed"
20670                 local sz=$(stat --format=%s $DIR/$tfile)
20671                 local blk=$(stat --format=%b $DIR/$tfile)
20672                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
20673                                      grant_blk_size) * 8))
20674
20675                 if [[ $blk -ne $trunc_blk ]]; then
20676                         $(which stat) $DIR/$tfile
20677                         error "Expected Block $trunc_blk got $blk for $tfile"
20678                 fi
20679
20680                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
20681                         error "Expected Size $trunc_sz got $sz for $tfile"
20682         done
20683
20684         #
20685         # sparse file test
20686         # Create file with a hole and write actual two blocks. Block count
20687         # must be 16.
20688         #
20689         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
20690                 conv=fsync || error "Create file : $DIR/$tfile"
20691
20692         # Calculate the final truncate size.
20693         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
20694
20695         #
20696         # truncate to size $trunc_sz bytes. Strip the last block
20697         # The block count must drop to 8
20698         #
20699         $TRUNCATE $DIR/$tfile $trunc_sz ||
20700                 error "truncate $tfile to $trunc_sz failed"
20701
20702         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
20703         sz=$(stat --format=%s $DIR/$tfile)
20704         blk=$(stat --format=%b $DIR/$tfile)
20705
20706         if [[ $blk -ne $trunc_bsz ]]; then
20707                 $(which stat) $DIR/$tfile
20708                 error "Expected Block $trunc_bsz got $blk for $tfile"
20709         fi
20710
20711         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
20712                 error "Expected Size $trunc_sz got $sz for $tfile"
20713 }
20714 run_test 317 "Verify blocks get correctly update after truncate"
20715
20716 test_318() {
20717         local old_max_active=$($LCTL get_param -n \
20718                             llite.*.max_read_ahead_async_active 2>/dev/null)
20719
20720         $LCTL set_param llite.*.max_read_ahead_async_active=256
20721         local max_active=$($LCTL get_param -n \
20722                            llite.*.max_read_ahead_async_active 2>/dev/null)
20723         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
20724
20725         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
20726                 error "set max_read_ahead_async_active should succeed"
20727
20728         $LCTL set_param llite.*.max_read_ahead_async_active=512
20729         max_active=$($LCTL get_param -n \
20730                      llite.*.max_read_ahead_async_active 2>/dev/null)
20731         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
20732
20733         # restore @max_active
20734         [ $old_max_active -ne 0 ] && $LCTL set_param \
20735                 llite.*.max_read_ahead_async_active=$old_max_active
20736
20737         local old_threshold=$($LCTL get_param -n \
20738                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
20739         local max_per_file_mb=$($LCTL get_param -n \
20740                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
20741
20742         local invalid=$(($max_per_file_mb + 1))
20743         $LCTL set_param \
20744                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
20745                         && error "set $invalid should fail"
20746
20747         local valid=$(($invalid - 1))
20748         $LCTL set_param \
20749                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
20750                         error "set $valid should succeed"
20751         local threshold=$($LCTL get_param -n \
20752                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
20753         [ $threshold -eq $valid ] || error \
20754                 "expect threshold $valid got $threshold"
20755         $LCTL set_param \
20756                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
20757 }
20758 run_test 318 "Verify async readahead tunables"
20759
20760 test_319() {
20761         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
20762
20763         local before=$(date +%s)
20764         local evict
20765         local mdir=$DIR/$tdir
20766         local file=$mdir/xxx
20767
20768         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
20769         touch $file
20770
20771 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
20772         $LCTL set_param fail_val=5 fail_loc=0x8000032c
20773         $LFS mv -m1 $file &
20774
20775         sleep 1
20776         dd if=$file of=/dev/null
20777         wait
20778         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
20779           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
20780
20781         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
20782 }
20783 run_test 319 "lost lease lock on migrate error"
20784
20785 test_398a() { # LU-4198
20786         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20787         $LCTL set_param ldlm.namespaces.*.lru_size=clear
20788
20789         # request a new lock on client
20790         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
20791
20792         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
20793         local lock_count=$($LCTL get_param -n \
20794                            ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
20795         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
20796
20797         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
20798
20799         # no lock cached, should use lockless IO and not enqueue new lock
20800         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
20801         lock_count=$($LCTL get_param -n \
20802                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
20803         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
20804 }
20805 run_test 398a "direct IO should cancel lock otherwise lockless"
20806
20807 test_398b() { # LU-4198
20808         which fio || skip_env "no fio installed"
20809         $LFS setstripe -c -1 $DIR/$tfile
20810
20811         local size=12
20812         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
20813
20814         local njobs=4
20815         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
20816         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
20817                 --numjobs=$njobs --fallocate=none \
20818                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
20819                 --filename=$DIR/$tfile &
20820         bg_pid=$!
20821
20822         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
20823         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
20824                 --numjobs=$njobs --fallocate=none \
20825                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
20826                 --filename=$DIR/$tfile || true
20827         wait $bg_pid
20828
20829         rm -rf $DIR/$tfile
20830 }
20831 run_test 398b "DIO and buffer IO race"
20832
20833 test_398c() { # LU-4198
20834         which fio || skip_env "no fio installed"
20835
20836         saved_debug=$($LCTL get_param -n debug)
20837         $LCTL set_param debug=0
20838
20839         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
20840         ((size /= 1024)) # by megabytes
20841         ((size /= 2)) # write half of the OST at most
20842         [ $size -gt 40 ] && size=40 #reduce test time anyway
20843
20844         $LFS setstripe -c 1 $DIR/$tfile
20845
20846         # it seems like ldiskfs reserves more space than necessary if the
20847         # writing blocks are not mapped, so it extends the file firstly
20848         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
20849         cancel_lru_locks osc
20850
20851         # clear and verify rpc_stats later
20852         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
20853
20854         local njobs=4
20855         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
20856         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
20857                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
20858                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
20859                 --filename=$DIR/$tfile
20860         [ $? -eq 0 ] || error "fio write error"
20861
20862         [ $($LCTL get_param -n \
20863          ldlm.namespaces.${FSNAME}-OST0000-osc-ffff*.lock_count) -eq 0 ] ||
20864                 error "Locks were requested while doing AIO"
20865
20866         # get the percentage of 1-page I/O
20867         pct=$($LCTL get_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats |
20868                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
20869                 awk '{print $7}')
20870         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
20871
20872         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
20873         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
20874                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
20875                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
20876                 --filename=$DIR/$tfile
20877         [ $? -eq 0 ] || error "fio mixed read write error"
20878
20879         rm -rf $DIR/$tfile
20880         $LCTL set_param debug="$saved_debug"
20881 }
20882 run_test 398c "run fio to test AIO"
20883
20884 test_fake_rw() {
20885         local read_write=$1
20886         if [ "$read_write" = "write" ]; then
20887                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
20888         elif [ "$read_write" = "read" ]; then
20889                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
20890         else
20891                 error "argument error"
20892         fi
20893
20894         # turn off debug for performance testing
20895         local saved_debug=$($LCTL get_param -n debug)
20896         $LCTL set_param debug=0
20897
20898         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20899
20900         # get ost1 size - $FSNAME-OST0000
20901         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
20902         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
20903         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
20904
20905         if [ "$read_write" = "read" ]; then
20906                 truncate -s $(expr 1048576 \* $blocks) $DIR/$tfile
20907         fi
20908
20909         local start_time=$(date +%s.%N)
20910         $dd_cmd bs=1M count=$blocks oflag=sync ||
20911                 error "real dd $read_write error"
20912         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
20913
20914         if [ "$read_write" = "write" ]; then
20915                 rm -f $DIR/$tfile
20916         fi
20917
20918         # define OBD_FAIL_OST_FAKE_RW           0x238
20919         do_facet ost1 $LCTL set_param fail_loc=0x238
20920
20921         local start_time=$(date +%s.%N)
20922         $dd_cmd bs=1M count=$blocks oflag=sync ||
20923                 error "fake dd $read_write error"
20924         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
20925
20926         if [ "$read_write" = "write" ]; then
20927                 # verify file size
20928                 cancel_lru_locks osc
20929                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
20930                         error "$tfile size not $blocks MB"
20931         fi
20932         do_facet ost1 $LCTL set_param fail_loc=0
20933
20934         echo "fake $read_write $duration_fake vs. normal $read_write" \
20935                 "$duration in seconds"
20936         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
20937                 error_not_in_vm "fake write is slower"
20938
20939         $LCTL set_param -n debug="$saved_debug"
20940         rm -f $DIR/$tfile
20941 }
20942 test_399a() { # LU-7655 for OST fake write
20943         remote_ost_nodsh && skip "remote OST with nodsh"
20944
20945         test_fake_rw write
20946 }
20947 run_test 399a "fake write should not be slower than normal write"
20948
20949 test_399b() { # LU-8726 for OST fake read
20950         remote_ost_nodsh && skip "remote OST with nodsh"
20951         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
20952                 skip_env "ldiskfs only test"
20953         fi
20954
20955         test_fake_rw read
20956 }
20957 run_test 399b "fake read should not be slower than normal read"
20958
20959 test_400a() { # LU-1606, was conf-sanity test_74
20960         if ! which $CC > /dev/null 2>&1; then
20961                 skip_env "$CC is not installed"
20962         fi
20963
20964         local extra_flags=''
20965         local out=$TMP/$tfile
20966         local prefix=/usr/include/lustre
20967         local prog
20968
20969         # Oleg removes c files in his test rig so test if any c files exist
20970         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
20971                 skip_env "Needed c test files are missing"
20972
20973         if ! [[ -d $prefix ]]; then
20974                 # Assume we're running in tree and fixup the include path.
20975                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
20976                 extra_flags+=" -L$LUSTRE/utils/.lib"
20977         fi
20978
20979         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
20980                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
20981                         error "client api broken"
20982         done
20983         rm -f $out
20984 }
20985 run_test 400a "Lustre client api program can compile and link"
20986
20987 test_400b() { # LU-1606, LU-5011
20988         local header
20989         local out=$TMP/$tfile
20990         local prefix=/usr/include/linux/lustre
20991
20992         # We use a hard coded prefix so that this test will not fail
20993         # when run in tree. There are headers in lustre/include/lustre/
20994         # that are not packaged (like lustre_idl.h) and have more
20995         # complicated include dependencies (like config.h and lnet/types.h).
20996         # Since this test about correct packaging we just skip them when
20997         # they don't exist (see below) rather than try to fixup cppflags.
20998
20999         if ! which $CC > /dev/null 2>&1; then
21000                 skip_env "$CC is not installed"
21001         fi
21002
21003         for header in $prefix/*.h; do
21004                 if ! [[ -f "$header" ]]; then
21005                         continue
21006                 fi
21007
21008                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
21009                         continue # lustre_ioctl.h is internal header
21010                 fi
21011
21012                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
21013                         error "cannot compile '$header'"
21014         done
21015         rm -f $out
21016 }
21017 run_test 400b "packaged headers can be compiled"
21018
21019 test_401a() { #LU-7437
21020         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
21021         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
21022
21023         #count the number of parameters by "list_param -R"
21024         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
21025         #count the number of parameters by listing proc files
21026         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
21027         echo "proc_dirs='$proc_dirs'"
21028         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
21029         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
21030                       sort -u | wc -l)
21031
21032         [ $params -eq $procs ] ||
21033                 error "found $params parameters vs. $procs proc files"
21034
21035         # test the list_param -D option only returns directories
21036         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
21037         #count the number of parameters by listing proc directories
21038         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
21039                 sort -u | wc -l)
21040
21041         [ $params -eq $procs ] ||
21042                 error "found $params parameters vs. $procs proc files"
21043 }
21044 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
21045
21046 test_401b() {
21047         local save=$($LCTL get_param -n jobid_var)
21048         local tmp=testing
21049
21050         $LCTL set_param foo=bar jobid_var=$tmp bar=baz &&
21051                 error "no error returned when setting bad parameters"
21052
21053         local jobid_new=$($LCTL get_param -n foe jobid_var baz)
21054         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
21055
21056         $LCTL set_param -n fog=bam jobid_var=$save bat=fog
21057         local jobid_old=$($LCTL get_param -n foe jobid_var bag)
21058         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
21059 }
21060 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
21061
21062 test_401c() {
21063         local jobid_var_old=$($LCTL get_param -n jobid_var)
21064         local jobid_var_new
21065
21066         $LCTL set_param jobid_var= &&
21067                 error "no error returned for 'set_param a='"
21068
21069         jobid_var_new=$($LCTL get_param -n jobid_var)
21070         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
21071                 error "jobid_var was changed by setting without value"
21072
21073         $LCTL set_param jobid_var &&
21074                 error "no error returned for 'set_param a'"
21075
21076         jobid_var_new=$($LCTL get_param -n jobid_var)
21077         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
21078                 error "jobid_var was changed by setting without value"
21079 }
21080 run_test 401c "Verify 'lctl set_param' without value fails in either format."
21081
21082 test_401d() {
21083         local jobid_var_old=$($LCTL get_param -n jobid_var)
21084         local jobid_var_new
21085         local new_value="foo=bar"
21086
21087         $LCTL set_param jobid_var=$new_value ||
21088                 error "'set_param a=b' did not accept a value containing '='"
21089
21090         jobid_var_new=$($LCTL get_param -n jobid_var)
21091         [[ "$jobid_var_new" == "$new_value" ]] ||
21092                 error "'set_param a=b' failed on a value containing '='"
21093
21094         # Reset the jobid_var to test the other format
21095         $LCTL set_param jobid_var=$jobid_var_old
21096         jobid_var_new=$($LCTL get_param -n jobid_var)
21097         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
21098                 error "failed to reset jobid_var"
21099
21100         $LCTL set_param jobid_var $new_value ||
21101                 error "'set_param a b' did not accept a value containing '='"
21102
21103         jobid_var_new=$($LCTL get_param -n jobid_var)
21104         [[ "$jobid_var_new" == "$new_value" ]] ||
21105                 error "'set_param a b' failed on a value containing '='"
21106
21107         $LCTL set_param jobid_var $jobid_var_old
21108         jobid_var_new=$($LCTL get_param -n jobid_var)
21109         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
21110                 error "failed to reset jobid_var"
21111 }
21112 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
21113
21114 test_402() {
21115         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
21116         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
21117                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
21118         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
21119                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
21120                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
21121         remote_mds_nodsh && skip "remote MDS with nodsh"
21122
21123         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
21124 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
21125         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
21126         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
21127                 echo "Touch failed - OK"
21128 }
21129 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
21130
21131 test_403() {
21132         local file1=$DIR/$tfile.1
21133         local file2=$DIR/$tfile.2
21134         local tfile=$TMP/$tfile
21135
21136         rm -f $file1 $file2 $tfile
21137
21138         touch $file1
21139         ln $file1 $file2
21140
21141         # 30 sec OBD_TIMEOUT in ll_getattr()
21142         # right before populating st_nlink
21143         $LCTL set_param fail_loc=0x80001409
21144         stat -c %h $file1 > $tfile &
21145
21146         # create an alias, drop all locks and reclaim the dentry
21147         < $file2
21148         cancel_lru_locks mdc
21149         cancel_lru_locks osc
21150         sysctl -w vm.drop_caches=2
21151
21152         wait
21153
21154         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
21155
21156         rm -f $tfile $file1 $file2
21157 }
21158 run_test 403 "i_nlink should not drop to zero due to aliasing"
21159
21160 test_404() { # LU-6601
21161         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
21162                 skip "Need server version newer than 2.8.52"
21163         remote_mds_nodsh && skip "remote MDS with nodsh"
21164
21165         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
21166                 awk '/osp .*-osc-MDT/ { print $4}')
21167
21168         local osp
21169         for osp in $mosps; do
21170                 echo "Deactivate: " $osp
21171                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
21172                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
21173                         awk -vp=$osp '$4 == p { print $2 }')
21174                 [ $stat = IN ] || {
21175                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
21176                         error "deactivate error"
21177                 }
21178                 echo "Activate: " $osp
21179                 do_facet $SINGLEMDS $LCTL --device %$osp activate
21180                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
21181                         awk -vp=$osp '$4 == p { print $2 }')
21182                 [ $stat = UP ] || {
21183                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
21184                         error "activate error"
21185                 }
21186         done
21187 }
21188 run_test 404 "validate manual {de}activated works properly for OSPs"
21189
21190 test_405() {
21191         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
21192         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
21193                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
21194                         skip "Layout swap lock is not supported"
21195
21196         check_swap_layouts_support
21197
21198         test_mkdir $DIR/$tdir
21199         swap_lock_test -d $DIR/$tdir ||
21200                 error "One layout swap locked test failed"
21201 }
21202 run_test 405 "Various layout swap lock tests"
21203
21204 test_406() {
21205         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21206         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
21207         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
21208         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21209         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
21210                 skip "Need MDS version at least 2.8.50"
21211
21212         local def_stripe_size=$($LFS getstripe -S $MOUNT)
21213         local test_pool=$TESTNAME
21214
21215         pool_add $test_pool || error "pool_add failed"
21216         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
21217                 error "pool_add_targets failed"
21218
21219         save_layout_restore_at_exit $MOUNT
21220
21221         # parent set default stripe count only, child will stripe from both
21222         # parent and fs default
21223         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
21224                 error "setstripe $MOUNT failed"
21225         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
21226         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
21227         for i in $(seq 10); do
21228                 local f=$DIR/$tdir/$tfile.$i
21229                 touch $f || error "touch failed"
21230                 local count=$($LFS getstripe -c $f)
21231                 [ $count -eq $OSTCOUNT ] ||
21232                         error "$f stripe count $count != $OSTCOUNT"
21233                 local offset=$($LFS getstripe -i $f)
21234                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
21235                 local size=$($LFS getstripe -S $f)
21236                 [ $size -eq $((def_stripe_size * 2)) ] ||
21237                         error "$f stripe size $size != $((def_stripe_size * 2))"
21238                 local pool=$($LFS getstripe -p $f)
21239                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
21240         done
21241
21242         # change fs default striping, delete parent default striping, now child
21243         # will stripe from new fs default striping only
21244         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
21245                 error "change $MOUNT default stripe failed"
21246         $LFS setstripe -c 0 $DIR/$tdir ||
21247                 error "delete $tdir default stripe failed"
21248         for i in $(seq 11 20); do
21249                 local f=$DIR/$tdir/$tfile.$i
21250                 touch $f || error "touch $f failed"
21251                 local count=$($LFS getstripe -c $f)
21252                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
21253                 local offset=$($LFS getstripe -i $f)
21254                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
21255                 local size=$($LFS getstripe -S $f)
21256                 [ $size -eq $def_stripe_size ] ||
21257                         error "$f stripe size $size != $def_stripe_size"
21258                 local pool=$($LFS getstripe -p $f)
21259                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
21260         done
21261
21262         unlinkmany $DIR/$tdir/$tfile. 1 20
21263
21264         local f=$DIR/$tdir/$tfile
21265         pool_remove_all_targets $test_pool $f
21266         pool_remove $test_pool $f
21267 }
21268 run_test 406 "DNE support fs default striping"
21269
21270 test_407() {
21271         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21272         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
21273                 skip "Need MDS version at least 2.8.55"
21274         remote_mds_nodsh && skip "remote MDS with nodsh"
21275
21276         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
21277                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
21278         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
21279                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
21280         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
21281
21282         #define OBD_FAIL_DT_TXN_STOP    0x2019
21283         for idx in $(seq $MDSCOUNT); do
21284                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
21285         done
21286         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
21287         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
21288                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
21289         true
21290 }
21291 run_test 407 "transaction fail should cause operation fail"
21292
21293 test_408() {
21294         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
21295
21296         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
21297         lctl set_param fail_loc=0x8000040a
21298         # let ll_prepare_partial_page() fail
21299         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
21300
21301         rm -f $DIR/$tfile
21302
21303         # create at least 100 unused inodes so that
21304         # shrink_icache_memory(0) should not return 0
21305         touch $DIR/$tfile-{0..100}
21306         rm -f $DIR/$tfile-{0..100}
21307         sync
21308
21309         echo 2 > /proc/sys/vm/drop_caches
21310 }
21311 run_test 408 "drop_caches should not hang due to page leaks"
21312
21313 test_409()
21314 {
21315         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21316
21317         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
21318         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
21319         touch $DIR/$tdir/guard || error "(2) Fail to create"
21320
21321         local PREFIX=$(str_repeat 'A' 128)
21322         echo "Create 1K hard links start at $(date)"
21323         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
21324                 error "(3) Fail to hard link"
21325
21326         echo "Links count should be right although linkEA overflow"
21327         stat $DIR/$tdir/guard || error "(4) Fail to stat"
21328         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
21329         [ $linkcount -eq 1001 ] ||
21330                 error "(5) Unexpected hard links count: $linkcount"
21331
21332         echo "List all links start at $(date)"
21333         ls -l $DIR/$tdir/foo > /dev/null ||
21334                 error "(6) Fail to list $DIR/$tdir/foo"
21335
21336         echo "Unlink hard links start at $(date)"
21337         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
21338                 error "(7) Fail to unlink"
21339         echo "Unlink hard links finished at $(date)"
21340 }
21341 run_test 409 "Large amount of cross-MDTs hard links on the same file"
21342
21343 test_410()
21344 {
21345         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
21346                 skip "Need client version at least 2.9.59"
21347
21348         # Create a file, and stat it from the kernel
21349         local testfile=$DIR/$tfile
21350         touch $testfile
21351
21352         local run_id=$RANDOM
21353         local my_ino=$(stat --format "%i" $testfile)
21354
21355         # Try to insert the module. This will always fail as the
21356         # module is designed to not be inserted.
21357         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
21358             &> /dev/null
21359
21360         # Anything but success is a test failure
21361         dmesg | grep -q \
21362             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
21363             error "no inode match"
21364 }
21365 run_test 410 "Test inode number returned from kernel thread"
21366
21367 cleanup_test411_cgroup() {
21368         trap 0
21369         rmdir "$1"
21370 }
21371
21372 test_411() {
21373         local cg_basedir=/sys/fs/cgroup/memory
21374         # LU-9966
21375         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
21376                 skip "no setup for cgroup"
21377
21378         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
21379                 error "test file creation failed"
21380         cancel_lru_locks osc
21381
21382         # Create a very small memory cgroup to force a slab allocation error
21383         local cgdir=$cg_basedir/osc_slab_alloc
21384         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
21385         trap "cleanup_test411_cgroup $cgdir" EXIT
21386         echo 2M > $cgdir/memory.kmem.limit_in_bytes
21387         echo 1M > $cgdir/memory.limit_in_bytes
21388
21389         # Should not LBUG, just be killed by oom-killer
21390         # dd will return 0 even allocation failure in some environment.
21391         # So don't check return value
21392         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
21393         cleanup_test411_cgroup $cgdir
21394
21395         return 0
21396 }
21397 run_test 411 "Slab allocation error with cgroup does not LBUG"
21398
21399 test_412() {
21400         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21401         if [ $MDS1_VERSION -lt $(version_code 2.10.55) ]; then
21402                 skip "Need server version at least 2.10.55"
21403         fi
21404
21405         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
21406                 error "mkdir failed"
21407         $LFS getdirstripe $DIR/$tdir
21408         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
21409         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
21410                 error "expect $((MDSCOUT - 1)) get $stripe_index"
21411         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
21412         [ $stripe_count -eq 2 ] ||
21413                 error "expect 2 get $stripe_count"
21414 }
21415 run_test 412 "mkdir on specific MDTs"
21416
21417 test_qos_mkdir() {
21418         local mkdir_cmd=$1
21419         local stripe_count=$2
21420         local mdts=$(comma_list $(mdts_nodes))
21421
21422         local testdir
21423         local lmv_qos_prio_free
21424         local lmv_qos_threshold_rr
21425         local lmv_qos_maxage
21426         local lod_qos_prio_free
21427         local lod_qos_threshold_rr
21428         local lod_qos_maxage
21429         local count
21430         local i
21431
21432         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
21433         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
21434         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
21435                 head -n1)
21436         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
21437         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
21438         stack_trap "$LCTL set_param \
21439                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null" EXIT
21440         stack_trap "$LCTL set_param \
21441                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
21442         stack_trap "$LCTL set_param \
21443                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" EXIT
21444
21445         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
21446                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
21447         lod_qos_prio_free=${lod_qos_prio_free%%%}
21448         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
21449                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
21450         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
21451         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
21452                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
21453         stack_trap "do_nodes $mdts $LCTL set_param \
21454                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null" EXIT
21455         stack_trap "do_nodes $mdts $LCTL set_param \
21456                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null" \
21457                 EXIT
21458         stack_trap "do_nodes $mdts $LCTL set_param \
21459                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" EXIT
21460
21461         echo
21462         echo "Mkdir (stripe_count $stripe_count) roundrobin:"
21463
21464         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
21465         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
21466
21467         testdir=$DIR/$tdir-s$stripe_count/rr
21468
21469         for i in $(seq $((100 * MDSCOUNT))); do
21470                 eval $mkdir_cmd $testdir/subdir$i ||
21471                         error "$mkdir_cmd subdir$i failed"
21472         done
21473
21474         for i in $(seq $MDSCOUNT); do
21475                 count=$($LFS getdirstripe -i $testdir/* |
21476                                 grep ^$((i - 1))$ | wc -l)
21477                 echo "$count directories created on MDT$((i - 1))"
21478                 [ $count -eq 100 ] || error "subdirs are not evenly distributed"
21479
21480                 if [ $stripe_count -gt 1 ]; then
21481                         count=$($LFS getdirstripe $testdir/* |
21482                                 grep -P "^\s+$((i - 1))\t" | wc -l)
21483                         echo "$count stripes created on MDT$((i - 1))"
21484                         # deviation should < 5% of average
21485                         [ $count -lt $((95 * stripe_count)) ] ||
21486                         [ $count -gt $((105 * stripe_count)) ] &&
21487                                 error "stripes are not evenly distributed"
21488                 fi
21489         done
21490
21491         $LCTL set_param lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null
21492         do_nodes $mdts $LCTL set_param \
21493                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null
21494
21495         echo
21496         echo "Check for uneven MDTs: "
21497
21498         local ffree
21499         local bavail
21500         local max
21501         local min
21502         local max_index
21503         local min_index
21504         local tmp
21505
21506         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
21507         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
21508         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
21509
21510         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
21511         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
21512         max_index=0
21513         min_index=0
21514         for ((i = 1; i < ${#ffree[@]}; i++)); do
21515                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
21516                 if [ $tmp -gt $max ]; then
21517                         max=$tmp
21518                         max_index=$i
21519                 fi
21520                 if [ $tmp -lt $min ]; then
21521                         min=$tmp
21522                         min_index=$i
21523                 fi
21524         done
21525
21526         [ ${ffree[min_index]} -eq 0 ] &&
21527                 skip "no free files in MDT$min_index"
21528         [ ${ffree[min_index]} -gt 100000000 ] &&
21529                 skip "too much free files in MDT$min_index"
21530
21531         # Check if we need to generate uneven MDTs
21532         local threshold=50
21533         local diff=$(((max - min) * 100 / min))
21534         local value="$(generate_string 1024)"
21535
21536         while [ $diff -lt $threshold ]; do
21537                 # generate uneven MDTs, create till $threshold% diff
21538                 echo -n "weight diff=$diff% must be > $threshold% ..."
21539                 count=$((${ffree[min_index]} / 10))
21540                 # 50 sec per 10000 files in vm
21541                 [ $count -gt 40000 ] && [ "$SLOW" = "no" ] &&
21542                         skip "$count files to create"
21543                 echo "Fill MDT$min_index with $count files"
21544                 [ -d $DIR/$tdir-MDT$min_index ] ||
21545                         $LFS mkdir -i $min_index $DIR/$tdir-MDT$min_index ||
21546                         error "mkdir $tdir-MDT$min_index failed"
21547                 for i in $(seq $count); do
21548                         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE \
21549                                 $DIR/$tdir-MDT$min_index/f$j_$i > /dev/null ||
21550                                 error "create f$j_$i failed"
21551                         setfattr -n user.413b -v $value \
21552                                 $DIR/$tdir-MDT$min_index/f$j_$i ||
21553                                 error "setfattr f$j_$i failed"
21554                 done
21555
21556                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
21557                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
21558                 max=$(((${ffree[max_index]} >> 8) * \
21559                         (${bavail[max_index]} * bsize >> 16)))
21560                 min=$(((${ffree[min_index]} >> 8) * \
21561                         (${bavail[min_index]} * bsize >> 16)))
21562                 diff=$(((max - min) * 100 / min))
21563         done
21564
21565         echo "MDT filesfree available: ${ffree[@]}"
21566         echo "MDT blocks available: ${bavail[@]}"
21567         echo "weight diff=$diff%"
21568
21569         echo
21570         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
21571
21572         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
21573         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
21574         # decrease statfs age, so that it can be updated in time
21575         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
21576         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
21577
21578         sleep 1
21579
21580         testdir=$DIR/$tdir-s$stripe_count/qos
21581
21582         for i in $(seq $((100 * MDSCOUNT))); do
21583                 eval $mkdir_cmd $testdir/subdir$i ||
21584                         error "$mkdir_cmd subdir$i failed"
21585         done
21586
21587         for i in $(seq $MDSCOUNT); do
21588                 count=$($LFS getdirstripe -i $testdir/* | grep ^$((i - 1))$ |
21589                         wc -l)
21590                 echo "$count directories created on MDT$((i - 1))"
21591
21592                 if [ $stripe_count -gt 1 ]; then
21593                         count=$($LFS getdirstripe $testdir/* |
21594                                 grep -P "^\s+$((i - 1))\t" | wc -l)
21595                         echo "$count stripes created on MDT$((i - 1))"
21596                 fi
21597         done
21598
21599         max=$($LFS getdirstripe -i $testdir/* | grep ^$max_index$ | wc -l)
21600         min=$($LFS getdirstripe -i $testdir/* | grep ^$min_index$ | wc -l)
21601
21602         # D-value should > 10% of averge
21603         [ $((max - min)) -lt 10 ] &&
21604                 error "subdirs shouldn't be evenly distributed"
21605
21606         # ditto
21607         if [ $stripe_count -gt 1 ]; then
21608                 max=$($LFS getdirstripe $testdir/* |
21609                         grep -P "^\s+$max_index\t" | wc -l)
21610                 min=$($LFS getdirstripe $testdir/* |
21611                         grep -P "^\s+$min_index\t" | wc -l)
21612                 [ $((max - min)) -le $((10 * stripe_count)) ] &&
21613                         error "stripes shouldn't be evenly distributed"|| true
21614         fi
21615 }
21616
21617 test_413a() {
21618         [ $MDSCOUNT -lt 2 ] &&
21619                 skip "We need at least 2 MDTs for this test"
21620
21621         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
21622                 skip "Need server version at least 2.12.52"
21623
21624         local stripe_count
21625
21626         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
21627                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
21628                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
21629                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
21630                 test_qos_mkdir "$LFS mkdir -c $stripe_count" $stripe_count
21631         done
21632 }
21633 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
21634
21635 test_413b() {
21636         [ $MDSCOUNT -lt 2 ] &&
21637                 skip "We need at least 2 MDTs for this test"
21638
21639         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
21640                 skip "Need server version at least 2.12.52"
21641
21642         local stripe_count
21643
21644         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
21645                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
21646                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
21647                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
21648                 $LFS setdirstripe -D -c $stripe_count \
21649                         $DIR/$tdir-s$stripe_count/rr ||
21650                         error "setdirstripe failed"
21651                 $LFS setdirstripe -D -c $stripe_count \
21652                         $DIR/$tdir-s$stripe_count/qos ||
21653                         error "setdirstripe failed"
21654                 test_qos_mkdir "mkdir" $stripe_count
21655         done
21656 }
21657 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
21658
21659 test_414() {
21660 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
21661         $LCTL set_param fail_loc=0x80000521
21662         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
21663         rm -f $DIR/$tfile
21664 }
21665 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
21666
21667 test_415() {
21668         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21669         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21670                 skip "Need server version at least 2.11.52"
21671
21672         # LU-11102
21673         local total
21674         local setattr_pid
21675         local start_time
21676         local end_time
21677         local duration
21678
21679         total=500
21680         # this test may be slow on ZFS
21681         [ "$mds1_FSTYPE" == "zfs" ] && total=100
21682
21683         # though this test is designed for striped directory, let's test normal
21684         # directory too since lock is always saved as CoS lock.
21685         test_mkdir $DIR/$tdir || error "mkdir $tdir"
21686         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
21687
21688         (
21689                 while true; do
21690                         touch $DIR/$tdir
21691                 done
21692         ) &
21693         setattr_pid=$!
21694
21695         start_time=$(date +%s)
21696         for i in $(seq $total); do
21697                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
21698                         > /dev/null
21699         done
21700         end_time=$(date +%s)
21701         duration=$((end_time - start_time))
21702
21703         kill -9 $setattr_pid
21704
21705         echo "rename $total files took $duration sec"
21706         [ $duration -lt 100 ] || error "rename took $duration sec"
21707 }
21708 run_test 415 "lock revoke is not missing"
21709
21710 test_416() {
21711         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
21712                 skip "Need server version at least 2.11.55"
21713
21714         # define OBD_FAIL_OSD_TXN_START    0x19a
21715         do_facet mds1 lctl set_param fail_loc=0x19a
21716
21717         lfs mkdir -c $MDSCOUNT $DIR/$tdir
21718
21719         true
21720 }
21721 run_test 416 "transaction start failure won't cause system hung"
21722
21723 cleanup_417() {
21724         trap 0
21725         do_nodes $(comma_list $(mdts_nodes)) \
21726                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
21727         do_nodes $(comma_list $(mdts_nodes)) \
21728                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
21729         do_nodes $(comma_list $(mdts_nodes)) \
21730                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
21731 }
21732
21733 test_417() {
21734         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21735         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
21736                 skip "Need MDS version at least 2.11.56"
21737
21738         trap cleanup_417 RETURN EXIT
21739
21740         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
21741         do_nodes $(comma_list $(mdts_nodes)) \
21742                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
21743         $LFS migrate -m 0 $DIR/$tdir.1 &&
21744                 error "migrate dir $tdir.1 should fail"
21745
21746         do_nodes $(comma_list $(mdts_nodes)) \
21747                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
21748         $LFS mkdir -i 1 $DIR/$tdir.2 &&
21749                 error "create remote dir $tdir.2 should fail"
21750
21751         do_nodes $(comma_list $(mdts_nodes)) \
21752                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
21753         $LFS mkdir -c 2 $DIR/$tdir.3 &&
21754                 error "create striped dir $tdir.3 should fail"
21755         true
21756 }
21757 run_test 417 "disable remote dir, striped dir and dir migration"
21758
21759 # Checks that the outputs of df [-i] and lfs df [-i] match
21760 #
21761 # usage: check_lfs_df <blocks | inodes> <mountpoint>
21762 check_lfs_df() {
21763         local dir=$2
21764         local inodes
21765         local df_out
21766         local lfs_df_out
21767         local count
21768         local passed=false
21769
21770         # blocks or inodes
21771         [ "$1" == "blocks" ] && inodes= || inodes="-i"
21772
21773         for count in {1..100}; do
21774                 cancel_lru_locks
21775                 sync; sleep 0.2
21776
21777                 # read the lines of interest
21778                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
21779                         error "df $inodes $dir | tail -n +2 failed"
21780                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
21781                         error "lfs df $inodes $dir | grep summary: failed"
21782
21783                 # skip first substrings of each output as they are different
21784                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
21785                 # compare the two outputs
21786                 passed=true
21787                 for i in {1..5}; do
21788                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
21789                 done
21790                 $passed && break
21791         done
21792
21793         if ! $passed; then
21794                 df -P $inodes $dir
21795                 echo
21796                 lfs df $inodes $dir
21797                 error "df and lfs df $1 output mismatch: "      \
21798                       "df ${inodes}: ${df_out[*]}, "            \
21799                       "lfs df ${inodes}: ${lfs_df_out[*]}"
21800         fi
21801 }
21802
21803 test_418() {
21804         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21805
21806         local dir=$DIR/$tdir
21807         local numfiles=$((RANDOM % 4096 + 2))
21808         local numblocks=$((RANDOM % 256 + 1))
21809
21810         wait_delete_completed
21811         test_mkdir $dir
21812
21813         # check block output
21814         check_lfs_df blocks $dir
21815         # check inode output
21816         check_lfs_df inodes $dir
21817
21818         # create a single file and retest
21819         echo "Creating a single file and testing"
21820         createmany -o $dir/$tfile- 1 &>/dev/null ||
21821                 error "creating 1 file in $dir failed"
21822         check_lfs_df blocks $dir
21823         check_lfs_df inodes $dir
21824
21825         # create a random number of files
21826         echo "Creating $((numfiles - 1)) files and testing"
21827         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
21828                 error "creating $((numfiles - 1)) files in $dir failed"
21829
21830         # write a random number of blocks to the first test file
21831         echo "Writing $numblocks 4K blocks and testing"
21832         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
21833                 count=$numblocks &>/dev/null ||
21834                 error "dd to $dir/${tfile}-0 failed"
21835
21836         # retest
21837         check_lfs_df blocks $dir
21838         check_lfs_df inodes $dir
21839
21840         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
21841                 error "unlinking $numfiles files in $dir failed"
21842 }
21843 run_test 418 "df and lfs df outputs match"
21844
21845 test_419()
21846 {
21847         local dir=$DIR/$tdir
21848
21849         mkdir -p $dir
21850         touch $dir/file
21851
21852         cancel_lru_locks mdc
21853
21854         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
21855         $LCTL set_param fail_loc=0x1410
21856         cat $dir/file
21857         $LCTL set_param fail_loc=0
21858         rm -rf $dir
21859 }
21860 run_test 419 "Verify open file by name doesn't crash kernel"
21861
21862 test_420()
21863 {
21864         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
21865                 skip "Need MDS version at least 2.12.53"
21866
21867         local SAVE_UMASK=$(umask)
21868         local dir=$DIR/$tdir
21869         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
21870
21871         mkdir -p $dir
21872         umask 0000
21873         mkdir -m03777 $dir/testdir
21874         ls -dn $dir/testdir
21875         # Need to remove trailing '.' when SELinux is enabled
21876         local dirperms=$(ls -dn $dir/testdir |
21877                          awk '{ sub(/\.$/, "", $1); print $1}')
21878         [ $dirperms == "drwxrwsrwt" ] ||
21879                 error "incorrect perms on $dir/testdir"
21880
21881         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
21882                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
21883         ls -n $dir/testdir/testfile
21884         local fileperms=$(ls -n $dir/testdir/testfile |
21885                           awk '{ sub(/\.$/, "", $1); print $1}')
21886         [ $fileperms == "-rwxr-xr-x" ] ||
21887                 error "incorrect perms on $dir/testdir/testfile"
21888
21889         umask $SAVE_UMASK
21890 }
21891 run_test 420 "clear SGID bit on non-directories for non-members"
21892
21893 test_421a() {
21894         local cnt
21895         local fid1
21896         local fid2
21897
21898         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
21899                 skip "Need MDS version at least 2.12.54"
21900
21901         test_mkdir $DIR/$tdir
21902         createmany -o $DIR/$tdir/f 3
21903         cnt=$(ls -1 $DIR/$tdir | wc -l)
21904         [ $cnt != 3 ] && error "unexpected #files: $cnt"
21905
21906         fid1=$(lfs path2fid $DIR/$tdir/f1)
21907         fid2=$(lfs path2fid $DIR/$tdir/f2)
21908         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
21909
21910         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
21911         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
21912
21913         cnt=$(ls -1 $DIR/$tdir | wc -l)
21914         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
21915
21916         rm -f $DIR/$tdir/f3 || error "can't remove f3"
21917         createmany -o $DIR/$tdir/f 3
21918         cnt=$(ls -1 $DIR/$tdir | wc -l)
21919         [ $cnt != 3 ] && error "unexpected #files: $cnt"
21920
21921         fid1=$(lfs path2fid $DIR/$tdir/f1)
21922         fid2=$(lfs path2fid $DIR/$tdir/f2)
21923         echo "remove using fsname $FSNAME"
21924         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
21925
21926         cnt=$(ls -1 $DIR/$tdir | wc -l)
21927         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
21928 }
21929 run_test 421a "simple rm by fid"
21930
21931 test_421b() {
21932         local cnt
21933         local FID1
21934         local FID2
21935
21936         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
21937                 skip "Need MDS version at least 2.12.54"
21938
21939         test_mkdir $DIR/$tdir
21940         createmany -o $DIR/$tdir/f 3
21941         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
21942         MULTIPID=$!
21943
21944         FID1=$(lfs path2fid $DIR/$tdir/f1)
21945         FID2=$(lfs path2fid $DIR/$tdir/f2)
21946         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
21947
21948         kill -USR1 $MULTIPID
21949         wait
21950
21951         cnt=$(ls $DIR/$tdir | wc -l)
21952         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
21953 }
21954 run_test 421b "rm by fid on open file"
21955
21956 test_421c() {
21957         local cnt
21958         local FIDS
21959
21960         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
21961                 skip "Need MDS version at least 2.12.54"
21962
21963         test_mkdir $DIR/$tdir
21964         createmany -o $DIR/$tdir/f 3
21965         touch $DIR/$tdir/$tfile
21966         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
21967         cnt=$(ls -1 $DIR/$tdir | wc -l)
21968         [ $cnt != 184 ] && error "unexpected #files: $cnt"
21969
21970         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
21971         $LFS rmfid $DIR $FID1 || error "rmfid failed"
21972
21973         cnt=$(ls $DIR/$tdir | wc -l)
21974         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
21975 }
21976 run_test 421c "rm by fid against hardlinked files"
21977
21978 test_421d() {
21979         local cnt
21980         local FIDS
21981
21982         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
21983                 skip "Need MDS version at least 2.12.54"
21984
21985         test_mkdir $DIR/$tdir
21986         createmany -o $DIR/$tdir/f 4097
21987         cnt=$(ls -1 $DIR/$tdir | wc -l)
21988         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
21989
21990         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
21991         $LFS rmfid $DIR $FIDS || error "rmfid failed"
21992
21993         cnt=$(ls $DIR/$tdir | wc -l)
21994         rm -rf $DIR/$tdir
21995         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
21996 }
21997 run_test 421d "rmfid en masse"
21998
21999 test_421e() {
22000         local cnt
22001         local FID
22002
22003         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22004         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
22005                 skip "Need MDS version at least 2.12.54"
22006
22007         mkdir -p $DIR/$tdir
22008         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
22009         createmany -o $DIR/$tdir/striped_dir/f 512
22010         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
22011         [ $cnt != 512 ] && error "unexpected #files: $cnt"
22012
22013         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
22014                 sed "s/[/][^:]*://g")
22015         $LFS rmfid $DIR $FIDS || error "rmfid failed"
22016
22017         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
22018         rm -rf $DIR/$tdir
22019         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
22020 }
22021 run_test 421e "rmfid in DNE"
22022
22023 test_421f() {
22024         local cnt
22025         local FID
22026
22027         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
22028                 skip "Need MDS version at least 2.12.54"
22029
22030         test_mkdir $DIR/$tdir
22031         touch $DIR/$tdir/f
22032         cnt=$(ls -1 $DIR/$tdir | wc -l)
22033         [ $cnt != 1 ] && error "unexpected #files: $cnt"
22034
22035         FID=$(lfs path2fid $DIR/$tdir/f)
22036         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
22037         # rmfid should fail
22038         cnt=$(ls -1 $DIR/$tdir | wc -l)
22039         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
22040
22041         chmod a+rw $DIR/$tdir
22042         ls -la $DIR/$tdir
22043         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
22044         # rmfid should fail
22045         cnt=$(ls -1 $DIR/$tdir | wc -l)
22046         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
22047
22048         rm -f $DIR/$tdir/f
22049         $RUNAS touch $DIR/$tdir/f
22050         FID=$(lfs path2fid $DIR/$tdir/f)
22051         echo "rmfid as root"
22052         $LFS rmfid $DIR $FID || error "rmfid as root failed"
22053         cnt=$(ls -1 $DIR/$tdir | wc -l)
22054         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
22055
22056         rm -f $DIR/$tdir/f
22057         $RUNAS touch $DIR/$tdir/f
22058         cnt=$(ls -1 $DIR/$tdir | wc -l)
22059         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
22060         FID=$(lfs path2fid $DIR/$tdir/f)
22061         # rmfid w/o user_fid2path mount option should fail
22062         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
22063         cnt=$(ls -1 $DIR/$tdir | wc -l)
22064         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
22065
22066         umount_client $MOUNT || error "failed to umount client"
22067         mount_client $MOUNT "$MOUNT_OPTS,user_fid2path" ||
22068                 error "failed to mount client'"
22069
22070         $RUNAS $LFS rmfid $DIR $FID || error "rmfid failed"
22071         # rmfid should succeed
22072         cnt=$(ls -1 $DIR/$tdir | wc -l)
22073         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
22074
22075         # rmfid shouldn't allow to remove files due to dir's permission
22076         chmod a+rwx $DIR/$tdir
22077         touch $DIR/$tdir/f
22078         ls -la $DIR/$tdir
22079         FID=$(lfs path2fid $DIR/$tdir/f)
22080         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail"
22081
22082         umount_client $MOUNT || error "failed to umount client"
22083         mount_client $MOUNT "$MOUNT_OPTS" ||
22084                 error "failed to mount client'"
22085
22086 }
22087 run_test 421f "rmfid checks permissions"
22088
22089 test_421g() {
22090         local cnt
22091         local FIDS
22092
22093         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22094         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
22095                 skip "Need MDS version at least 2.12.54"
22096
22097         mkdir -p $DIR/$tdir
22098         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
22099         createmany -o $DIR/$tdir/striped_dir/f 512
22100         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
22101         [ $cnt != 512 ] && error "unexpected #files: $cnt"
22102
22103         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
22104                 sed "s/[/][^:]*://g")
22105
22106         rm -f $DIR/$tdir/striped_dir/f1*
22107         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
22108         removed=$((512 - cnt))
22109
22110         # few files have been just removed, so we expect
22111         # rmfid to fail on their fids
22112         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
22113         [ $removed != $errors ] && error "$errors != $removed"
22114
22115         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
22116         rm -rf $DIR/$tdir
22117         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
22118 }
22119 run_test 421g "rmfid to return errors properly"
22120
22121 test_422() {
22122         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
22123         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
22124         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
22125         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
22126         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
22127
22128         local amc=$(at_max_get client)
22129         local amo=$(at_max_get mds1)
22130         local timeout=`lctl get_param -n timeout`
22131
22132         at_max_set 0 client
22133         at_max_set 0 mds1
22134
22135 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
22136         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
22137                         fail_val=$(((2*timeout + 10)*1000))
22138         touch $DIR/$tdir/d3/file &
22139         sleep 2
22140 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
22141         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
22142                         fail_val=$((2*timeout + 5))
22143         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
22144         local pid=$!
22145         sleep 1
22146         kill -9 $pid
22147         sleep $((2 * timeout))
22148         echo kill $pid
22149         kill -9 $pid
22150         lctl mark touch
22151         touch $DIR/$tdir/d2/file3
22152         touch $DIR/$tdir/d2/file4
22153         touch $DIR/$tdir/d2/file5
22154
22155         wait
22156         at_max_set $amc client
22157         at_max_set $amo mds1
22158
22159         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
22160         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
22161                 error "Watchdog is always throttled"
22162 }
22163 run_test 422 "kill a process with RPC in progress"
22164
22165 stat_test() {
22166     df -h $MOUNT &
22167     df -h $MOUNT &
22168     df -h $MOUNT &
22169     df -h $MOUNT &
22170     df -h $MOUNT &
22171     df -h $MOUNT &
22172 }
22173
22174 test_423() {
22175     local _stats
22176     # ensure statfs cache is expired
22177     sleep 2;
22178
22179     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
22180     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
22181
22182     return 0
22183 }
22184 run_test 423 "statfs should return a right data"
22185
22186 prep_801() {
22187         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
22188         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
22189                 skip "Need server version at least 2.9.55"
22190
22191         start_full_debug_logging
22192 }
22193
22194 post_801() {
22195         stop_full_debug_logging
22196 }
22197
22198 barrier_stat() {
22199         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
22200                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
22201                            awk '/The barrier for/ { print $7 }')
22202                 echo $st
22203         else
22204                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
22205                 echo \'$st\'
22206         fi
22207 }
22208
22209 barrier_expired() {
22210         local expired
22211
22212         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
22213                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
22214                           awk '/will be expired/ { print $7 }')
22215         else
22216                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
22217         fi
22218
22219         echo $expired
22220 }
22221
22222 test_801a() {
22223         prep_801
22224
22225         echo "Start barrier_freeze at: $(date)"
22226         #define OBD_FAIL_BARRIER_DELAY          0x2202
22227         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
22228         # Do not reduce barrier time - See LU-11873
22229         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
22230
22231         sleep 2
22232         local b_status=$(barrier_stat)
22233         echo "Got barrier status at: $(date)"
22234         [ "$b_status" = "'freezing_p1'" ] ||
22235                 error "(1) unexpected barrier status $b_status"
22236
22237         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
22238         wait
22239         b_status=$(barrier_stat)
22240         [ "$b_status" = "'frozen'" ] ||
22241                 error "(2) unexpected barrier status $b_status"
22242
22243         local expired=$(barrier_expired)
22244         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
22245         sleep $((expired + 3))
22246
22247         b_status=$(barrier_stat)
22248         [ "$b_status" = "'expired'" ] ||
22249                 error "(3) unexpected barrier status $b_status"
22250
22251         # Do not reduce barrier time - See LU-11873
22252         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
22253                 error "(4) fail to freeze barrier"
22254
22255         b_status=$(barrier_stat)
22256         [ "$b_status" = "'frozen'" ] ||
22257                 error "(5) unexpected barrier status $b_status"
22258
22259         echo "Start barrier_thaw at: $(date)"
22260         #define OBD_FAIL_BARRIER_DELAY          0x2202
22261         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
22262         do_facet mgs $LCTL barrier_thaw $FSNAME &
22263
22264         sleep 2
22265         b_status=$(barrier_stat)
22266         echo "Got barrier status at: $(date)"
22267         [ "$b_status" = "'thawing'" ] ||
22268                 error "(6) unexpected barrier status $b_status"
22269
22270         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
22271         wait
22272         b_status=$(barrier_stat)
22273         [ "$b_status" = "'thawed'" ] ||
22274                 error "(7) unexpected barrier status $b_status"
22275
22276         #define OBD_FAIL_BARRIER_FAILURE        0x2203
22277         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
22278         do_facet mgs $LCTL barrier_freeze $FSNAME
22279
22280         b_status=$(barrier_stat)
22281         [ "$b_status" = "'failed'" ] ||
22282                 error "(8) unexpected barrier status $b_status"
22283
22284         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
22285         do_facet mgs $LCTL barrier_thaw $FSNAME
22286
22287         post_801
22288 }
22289 run_test 801a "write barrier user interfaces and stat machine"
22290
22291 test_801b() {
22292         prep_801
22293
22294         mkdir $DIR/$tdir || error "(1) fail to mkdir"
22295         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
22296         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
22297         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
22298         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
22299
22300         cancel_lru_locks mdc
22301
22302         # 180 seconds should be long enough
22303         do_facet mgs $LCTL barrier_freeze $FSNAME 180
22304
22305         local b_status=$(barrier_stat)
22306         [ "$b_status" = "'frozen'" ] ||
22307                 error "(6) unexpected barrier status $b_status"
22308
22309         mkdir $DIR/$tdir/d0/d10 &
22310         mkdir_pid=$!
22311
22312         touch $DIR/$tdir/d1/f13 &
22313         touch_pid=$!
22314
22315         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
22316         ln_pid=$!
22317
22318         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
22319         mv_pid=$!
22320
22321         rm -f $DIR/$tdir/d4/f12 &
22322         rm_pid=$!
22323
22324         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
22325
22326         # To guarantee taht the 'stat' is not blocked
22327         b_status=$(barrier_stat)
22328         [ "$b_status" = "'frozen'" ] ||
22329                 error "(8) unexpected barrier status $b_status"
22330
22331         # let above commands to run at background
22332         sleep 5
22333
22334         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
22335         ps -p $touch_pid || error "(10) touch should be blocked"
22336         ps -p $ln_pid || error "(11) link should be blocked"
22337         ps -p $mv_pid || error "(12) rename should be blocked"
22338         ps -p $rm_pid || error "(13) unlink should be blocked"
22339
22340         b_status=$(barrier_stat)
22341         [ "$b_status" = "'frozen'" ] ||
22342                 error "(14) unexpected barrier status $b_status"
22343
22344         do_facet mgs $LCTL barrier_thaw $FSNAME
22345         b_status=$(barrier_stat)
22346         [ "$b_status" = "'thawed'" ] ||
22347                 error "(15) unexpected barrier status $b_status"
22348
22349         wait $mkdir_pid || error "(16) mkdir should succeed"
22350         wait $touch_pid || error "(17) touch should succeed"
22351         wait $ln_pid || error "(18) link should succeed"
22352         wait $mv_pid || error "(19) rename should succeed"
22353         wait $rm_pid || error "(20) unlink should succeed"
22354
22355         post_801
22356 }
22357 run_test 801b "modification will be blocked by write barrier"
22358
22359 test_801c() {
22360         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
22361
22362         prep_801
22363
22364         stop mds2 || error "(1) Fail to stop mds2"
22365
22366         do_facet mgs $LCTL barrier_freeze $FSNAME 30
22367
22368         local b_status=$(barrier_stat)
22369         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
22370                 do_facet mgs $LCTL barrier_thaw $FSNAME
22371                 error "(2) unexpected barrier status $b_status"
22372         }
22373
22374         do_facet mgs $LCTL barrier_rescan $FSNAME ||
22375                 error "(3) Fail to rescan barrier bitmap"
22376
22377         # Do not reduce barrier time - See LU-11873
22378         do_facet mgs $LCTL barrier_freeze $FSNAME 20
22379
22380         b_status=$(barrier_stat)
22381         [ "$b_status" = "'frozen'" ] ||
22382                 error "(4) unexpected barrier status $b_status"
22383
22384         do_facet mgs $LCTL barrier_thaw $FSNAME
22385         b_status=$(barrier_stat)
22386         [ "$b_status" = "'thawed'" ] ||
22387                 error "(5) unexpected barrier status $b_status"
22388
22389         local devname=$(mdsdevname 2)
22390
22391         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
22392
22393         do_facet mgs $LCTL barrier_rescan $FSNAME ||
22394                 error "(7) Fail to rescan barrier bitmap"
22395
22396         post_801
22397 }
22398 run_test 801c "rescan barrier bitmap"
22399
22400 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
22401 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
22402 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
22403 saved_MOUNT_OPTS=$MOUNT_OPTS
22404
22405 cleanup_802a() {
22406         trap 0
22407
22408         stopall
22409         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
22410         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
22411         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
22412         MOUNT_OPTS=$saved_MOUNT_OPTS
22413         setupall
22414 }
22415
22416 test_802a() {
22417         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
22418         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
22419         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
22420                 skip "Need server version at least 2.9.55"
22421
22422         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
22423
22424         mkdir $DIR/$tdir || error "(1) fail to mkdir"
22425
22426         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
22427                 error "(2) Fail to copy"
22428
22429         trap cleanup_802a EXIT
22430
22431         # sync by force before remount as readonly
22432         sync; sync_all_data; sleep 3; sync_all_data
22433
22434         stopall
22435
22436         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
22437         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
22438         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
22439
22440         echo "Mount the server as read only"
22441         setupall server_only || error "(3) Fail to start servers"
22442
22443         echo "Mount client without ro should fail"
22444         mount_client $MOUNT &&
22445                 error "(4) Mount client without 'ro' should fail"
22446
22447         echo "Mount client with ro should succeed"
22448         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
22449         mount_client $MOUNT ||
22450                 error "(5) Mount client with 'ro' should succeed"
22451
22452         echo "Modify should be refused"
22453         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
22454
22455         echo "Read should be allowed"
22456         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
22457                 error "(7) Read should succeed under ro mode"
22458
22459         cleanup_802a
22460 }
22461 run_test 802a "simulate readonly device"
22462
22463 test_802b() {
22464         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22465         remote_mds_nodsh && skip "remote MDS with nodsh"
22466
22467         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
22468                 skip "readonly option not available"
22469
22470         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
22471
22472         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
22473                 error "(2) Fail to copy"
22474
22475         # write back all cached data before setting MDT to readonly
22476         cancel_lru_locks
22477         sync_all_data
22478
22479         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
22480         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
22481
22482         echo "Modify should be refused"
22483         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
22484
22485         echo "Read should be allowed"
22486         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
22487                 error "(7) Read should succeed under ro mode"
22488
22489         # disable readonly
22490         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
22491 }
22492 run_test 802b "be able to set MDTs to readonly"
22493
22494 test_803() {
22495         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
22496         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
22497                 skip "MDS needs to be newer than 2.10.54"
22498
22499         mkdir -p $DIR/$tdir
22500         # Create some objects on all MDTs to trigger related logs objects
22501         for idx in $(seq $MDSCOUNT); do
22502                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
22503                         $DIR/$tdir/dir${idx} ||
22504                         error "Fail to create $DIR/$tdir/dir${idx}"
22505         done
22506
22507         sync; sleep 3
22508         wait_delete_completed # ensure old test cleanups are finished
22509         echo "before create:"
22510         $LFS df -i $MOUNT
22511         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
22512
22513         for i in {1..10}; do
22514                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
22515                         error "Fail to create $DIR/$tdir/foo$i"
22516         done
22517
22518         sync; sleep 3
22519         echo "after create:"
22520         $LFS df -i $MOUNT
22521         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
22522
22523         # allow for an llog to be cleaned up during the test
22524         [ $after_used -ge $((before_used + 10 - 1)) ] ||
22525                 error "before ($before_used) + 10 > after ($after_used)"
22526
22527         for i in {1..10}; do
22528                 rm -rf $DIR/$tdir/foo$i ||
22529                         error "Fail to remove $DIR/$tdir/foo$i"
22530         done
22531
22532         sleep 3 # avoid MDT return cached statfs
22533         wait_delete_completed
22534         echo "after unlink:"
22535         $LFS df -i $MOUNT
22536         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
22537
22538         # allow for an llog to be created during the test
22539         [ $after_used -le $((before_used + 1)) ] ||
22540                 error "after ($after_used) > before ($before_used) + 1"
22541 }
22542 run_test 803 "verify agent object for remote object"
22543
22544 test_804() {
22545         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
22546         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
22547                 skip "MDS needs to be newer than 2.10.54"
22548         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
22549
22550         mkdir -p $DIR/$tdir
22551         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
22552                 error "Fail to create $DIR/$tdir/dir0"
22553
22554         local fid=$($LFS path2fid $DIR/$tdir/dir0)
22555         local dev=$(mdsdevname 2)
22556
22557         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
22558                 grep ${fid} || error "NOT found agent entry for dir0"
22559
22560         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
22561                 error "Fail to create $DIR/$tdir/dir1"
22562
22563         touch $DIR/$tdir/dir1/foo0 ||
22564                 error "Fail to create $DIR/$tdir/dir1/foo0"
22565         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
22566         local rc=0
22567
22568         for idx in $(seq $MDSCOUNT); do
22569                 dev=$(mdsdevname $idx)
22570                 do_facet mds${idx} \
22571                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
22572                         grep ${fid} && rc=$idx
22573         done
22574
22575         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
22576                 error "Fail to rename foo0 to foo1"
22577         if [ $rc -eq 0 ]; then
22578                 for idx in $(seq $MDSCOUNT); do
22579                         dev=$(mdsdevname $idx)
22580                         do_facet mds${idx} \
22581                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
22582                         grep ${fid} && rc=$idx
22583                 done
22584         fi
22585
22586         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
22587                 error "Fail to rename foo1 to foo2"
22588         if [ $rc -eq 0 ]; then
22589                 for idx in $(seq $MDSCOUNT); do
22590                         dev=$(mdsdevname $idx)
22591                         do_facet mds${idx} \
22592                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
22593                         grep ${fid} && rc=$idx
22594                 done
22595         fi
22596
22597         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
22598
22599         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
22600                 error "Fail to link to $DIR/$tdir/dir1/foo2"
22601         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
22602                 error "Fail to rename foo2 to foo0"
22603         unlink $DIR/$tdir/dir1/foo0 ||
22604                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
22605         rm -rf $DIR/$tdir/dir0 ||
22606                 error "Fail to rm $DIR/$tdir/dir0"
22607
22608         for idx in $(seq $MDSCOUNT); do
22609                 dev=$(mdsdevname $idx)
22610                 rc=0
22611
22612                 stop mds${idx}
22613                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
22614                         rc=$?
22615                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
22616                         error "mount mds$idx failed"
22617                 df $MOUNT > /dev/null 2>&1
22618
22619                 # e2fsck should not return error
22620                 [ $rc -eq 0 ] ||
22621                         error "e2fsck detected error on MDT${idx}: rc=$rc"
22622         done
22623 }
22624 run_test 804 "verify agent entry for remote entry"
22625
22626 cleanup_805() {
22627         do_facet $SINGLEMDS zfs set quota=$old $fsset
22628         unlinkmany $DIR/$tdir/f- 1000000
22629         trap 0
22630 }
22631
22632 test_805() {
22633         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
22634         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
22635         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
22636                 skip "netfree not implemented before 0.7"
22637         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
22638                 skip "Need MDS version at least 2.10.57"
22639
22640         local fsset
22641         local freekb
22642         local usedkb
22643         local old
22644         local quota
22645         local pref="osd-zfs.$FSNAME-MDT0000."
22646
22647         # limit available space on MDS dataset to meet nospace issue
22648         # quickly. then ZFS 0.7.2 can use reserved space if asked
22649         # properly (using netfree flag in osd_declare_destroy()
22650         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
22651         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
22652                 gawk '{print $3}')
22653         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
22654         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
22655         let "usedkb=usedkb-freekb"
22656         let "freekb=freekb/2"
22657         if let "freekb > 5000"; then
22658                 let "freekb=5000"
22659         fi
22660         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
22661         trap cleanup_805 EXIT
22662         mkdir $DIR/$tdir
22663         $LFS setstripe -E 1M -L mdt $DIR/$tdir || error "DoM not working"
22664         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
22665         rm -rf $DIR/$tdir || error "not able to remove"
22666         do_facet $SINGLEMDS zfs set quota=$old $fsset
22667         trap 0
22668 }
22669 run_test 805 "ZFS can remove from full fs"
22670
22671 # Size-on-MDS test
22672 check_lsom_data()
22673 {
22674         local file=$1
22675         local size=$($LFS getsom -s $file)
22676         local expect=$(stat -c %s $file)
22677
22678         [[ $size == $expect ]] ||
22679                 error "$file expected size: $expect, got: $size"
22680
22681         local blocks=$($LFS getsom -b $file)
22682         expect=$(stat -c %b $file)
22683         [[ $blocks == $expect ]] ||
22684                 error "$file expected blocks: $expect, got: $blocks"
22685 }
22686
22687 check_lsom_size()
22688 {
22689         local size=$($LFS getsom -s $1)
22690         local expect=$2
22691
22692         [[ $size == $expect ]] ||
22693                 error "$file expected size: $expect, got: $size"
22694 }
22695
22696 test_806() {
22697         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22698                 skip "Need MDS version at least 2.11.52"
22699
22700         local bs=1048576
22701
22702         touch $DIR/$tfile || error "touch $tfile failed"
22703
22704         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22705         save_lustre_params client "llite.*.xattr_cache" > $save
22706         lctl set_param llite.*.xattr_cache=0
22707         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22708
22709         # single-threaded write
22710         echo "Test SOM for single-threaded write"
22711         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
22712                 error "write $tfile failed"
22713         check_lsom_size $DIR/$tfile $bs
22714
22715         local num=32
22716         local size=$(($num * $bs))
22717         local offset=0
22718         local i
22719
22720         echo "Test SOM for single client multi-threaded($num) write"
22721         $TRUNCATE $DIR/$tfile 0
22722         for ((i = 0; i < $num; i++)); do
22723                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
22724                 local pids[$i]=$!
22725                 offset=$((offset + $bs))
22726         done
22727         for (( i=0; i < $num; i++ )); do
22728                 wait ${pids[$i]}
22729         done
22730         check_lsom_size $DIR/$tfile $size
22731
22732         $TRUNCATE $DIR/$tfile 0
22733         for ((i = 0; i < $num; i++)); do
22734                 offset=$((offset - $bs))
22735                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
22736                 local pids[$i]=$!
22737         done
22738         for (( i=0; i < $num; i++ )); do
22739                 wait ${pids[$i]}
22740         done
22741         check_lsom_size $DIR/$tfile $size
22742
22743         # multi-client writes
22744         num=$(get_node_count ${CLIENTS//,/ })
22745         size=$(($num * $bs))
22746         offset=0
22747         i=0
22748
22749         echo "Test SOM for multi-client ($num) writes"
22750         $TRUNCATE $DIR/$tfile 0
22751         for client in ${CLIENTS//,/ }; do
22752                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
22753                 local pids[$i]=$!
22754                 i=$((i + 1))
22755                 offset=$((offset + $bs))
22756         done
22757         for (( i=0; i < $num; i++ )); do
22758                 wait ${pids[$i]}
22759         done
22760         check_lsom_size $DIR/$tfile $offset
22761
22762         i=0
22763         $TRUNCATE $DIR/$tfile 0
22764         for client in ${CLIENTS//,/ }; do
22765                 offset=$((offset - $bs))
22766                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
22767                 local pids[$i]=$!
22768                 i=$((i + 1))
22769         done
22770         for (( i=0; i < $num; i++ )); do
22771                 wait ${pids[$i]}
22772         done
22773         check_lsom_size $DIR/$tfile $size
22774
22775         # verify truncate
22776         echo "Test SOM for truncate"
22777         $TRUNCATE $DIR/$tfile 1048576
22778         check_lsom_size $DIR/$tfile 1048576
22779         $TRUNCATE $DIR/$tfile 1234
22780         check_lsom_size $DIR/$tfile 1234
22781
22782         # verify SOM blocks count
22783         echo "Verify SOM block count"
22784         $TRUNCATE $DIR/$tfile 0
22785         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
22786                 error "failed to write file $tfile"
22787         check_lsom_data $DIR/$tfile
22788 }
22789 run_test 806 "Verify Lazy Size on MDS"
22790
22791 test_807() {
22792         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
22793         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22794                 skip "Need MDS version at least 2.11.52"
22795
22796         # Registration step
22797         changelog_register || error "changelog_register failed"
22798         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
22799         changelog_users $SINGLEMDS | grep -q $cl_user ||
22800                 error "User $cl_user not found in changelog_users"
22801
22802         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22803         save_lustre_params client "llite.*.xattr_cache" > $save
22804         lctl set_param llite.*.xattr_cache=0
22805         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22806
22807         rm -rf $DIR/$tdir || error "rm $tdir failed"
22808         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
22809         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
22810         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
22811         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
22812                 error "truncate $tdir/trunc failed"
22813
22814         local bs=1048576
22815         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
22816                 error "write $tfile failed"
22817
22818         # multi-client wirtes
22819         local num=$(get_node_count ${CLIENTS//,/ })
22820         local offset=0
22821         local i=0
22822
22823         echo "Test SOM for multi-client ($num) writes"
22824         touch $DIR/$tfile || error "touch $tfile failed"
22825         $TRUNCATE $DIR/$tfile 0
22826         for client in ${CLIENTS//,/ }; do
22827                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
22828                 local pids[$i]=$!
22829                 i=$((i + 1))
22830                 offset=$((offset + $bs))
22831         done
22832         for (( i=0; i < $num; i++ )); do
22833                 wait ${pids[$i]}
22834         done
22835
22836         sleep 5
22837         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
22838         check_lsom_data $DIR/$tdir/trunc
22839         check_lsom_data $DIR/$tdir/single_dd
22840         check_lsom_data $DIR/$tfile
22841
22842         rm -rf $DIR/$tdir
22843         # Deregistration step
22844         changelog_deregister || error "changelog_deregister failed"
22845 }
22846 run_test 807 "verify LSOM syncing tool"
22847
22848 check_som_nologged()
22849 {
22850         local lines=$($LFS changelog $FSNAME-MDT0000 |
22851                 grep 'x=trusted.som' | wc -l)
22852         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
22853 }
22854
22855 test_808() {
22856         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
22857                 skip "Need MDS version at least 2.11.55"
22858
22859         # Registration step
22860         changelog_register || error "changelog_register failed"
22861
22862         touch $DIR/$tfile || error "touch $tfile failed"
22863         check_som_nologged
22864
22865         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
22866                 error "write $tfile failed"
22867         check_som_nologged
22868
22869         $TRUNCATE $DIR/$tfile 1234
22870         check_som_nologged
22871
22872         $TRUNCATE $DIR/$tfile 1048576
22873         check_som_nologged
22874
22875         # Deregistration step
22876         changelog_deregister || error "changelog_deregister failed"
22877 }
22878 run_test 808 "Check trusted.som xattr not logged in Changelogs"
22879
22880 check_som_nodata()
22881 {
22882         $LFS getsom $1
22883         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
22884 }
22885
22886 test_809() {
22887         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22888                 skip "Need MDS version at least 2.11.56"
22889
22890         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
22891                 error "failed to create DoM-only file $DIR/$tfile"
22892         touch $DIR/$tfile || error "touch $tfile failed"
22893         check_som_nodata $DIR/$tfile
22894
22895         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
22896                 error "write $tfile failed"
22897         check_som_nodata $DIR/$tfile
22898
22899         $TRUNCATE $DIR/$tfile 1234
22900         check_som_nodata $DIR/$tfile
22901
22902         $TRUNCATE $DIR/$tfile 4097
22903         check_som_nodata $DIR/$file
22904 }
22905 run_test 809 "Verify no SOM xattr store for DoM-only files"
22906
22907 test_810() {
22908         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22909         $GSS && skip_env "could not run with gss"
22910         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
22911                 skip "OST < 2.12.58 doesn't align checksum"
22912
22913         set_checksums 1
22914         stack_trap "set_checksums $ORIG_CSUM" EXIT
22915         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
22916
22917         local csum
22918         local before
22919         local after
22920         for csum in $CKSUM_TYPES; do
22921                 #define OBD_FAIL_OSC_NO_GRANT   0x411
22922                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
22923                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
22924                         eval set -- $i
22925                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
22926                         before=$(md5sum $DIR/$tfile)
22927                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
22928                         after=$(md5sum $DIR/$tfile)
22929                         [ "$before" == "$after" ] ||
22930                                 error "$csum: $before != $after bs=$1 seek=$2"
22931                 done
22932         done
22933 }
22934 run_test 810 "partial page writes on ZFS (LU-11663)"
22935
22936 test_811() {
22937         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22938                 skip "Need MDS version at least 2.11.56"
22939
22940         #define OBD_FAIL_MDS_ORPHAN_DELETE      0x165
22941         do_facet mds1 $LCTL set_param fail_loc=0x165
22942         $MULTIOP $DIR/$tfile Ouc || error "multiop failed"
22943
22944         stop mds1
22945         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
22946
22947         wait_update_facet mds1 "pgrep orph_.*-MDD | wc -l" "0" ||
22948                 error "MDD orphan cleanup thread not quit"
22949 }
22950 run_test 811 "orphan name stub can be cleaned up in startup"
22951
22952 test_812a() {
22953         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
22954                 skip "OST < 2.12.51 doesn't support this fail_loc"
22955         [ "$SHARED_KEY" = true ] &&
22956                 skip "OSC connections never go IDLE with Shared-Keys enabled"
22957
22958         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22959         # ensure ost1 is connected
22960         stat $DIR/$tfile >/dev/null || error "can't stat"
22961         wait_osc_import_state client ost1 FULL
22962         # no locks, no reqs to let the connection idle
22963         cancel_lru_locks osc
22964
22965         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
22966 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
22967         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
22968         wait_osc_import_state client ost1 CONNECTING
22969         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
22970
22971         stat $DIR/$tfile >/dev/null || error "can't stat file"
22972 }
22973 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
22974
22975 test_812b() { # LU-12378
22976         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
22977                 skip "OST < 2.12.51 doesn't support this fail_loc"
22978         [ "$SHARED_KEY" = true ] &&
22979                 skip "OSC connections never go IDLE with Shared-Keys enabled"
22980
22981         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
22982         # ensure ost1 is connected
22983         stat $DIR/$tfile >/dev/null || error "can't stat"
22984         wait_osc_import_state client ost1 FULL
22985         # no locks, no reqs to let the connection idle
22986         cancel_lru_locks osc
22987
22988         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
22989 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
22990         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
22991         wait_osc_import_state client ost1 CONNECTING
22992         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
22993
22994         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
22995         wait_osc_import_state client ost1 IDLE
22996 }
22997 run_test 812b "do not drop no resend request for idle connect"
22998
22999 test_813() {
23000         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
23001         [ -z "$file_heat_sav" ] && skip "no file heat support"
23002
23003         local readsample
23004         local writesample
23005         local readbyte
23006         local writebyte
23007         local readsample1
23008         local writesample1
23009         local readbyte1
23010         local writebyte1
23011
23012         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
23013         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
23014
23015         $LCTL set_param -n llite.*.file_heat=1
23016         echo "Turn on file heat"
23017         echo "Period second: $period_second, Decay percentage: $decay_pct"
23018
23019         echo "QQQQ" > $DIR/$tfile
23020         echo "QQQQ" > $DIR/$tfile
23021         echo "QQQQ" > $DIR/$tfile
23022         cat $DIR/$tfile > /dev/null
23023         cat $DIR/$tfile > /dev/null
23024         cat $DIR/$tfile > /dev/null
23025         cat $DIR/$tfile > /dev/null
23026
23027         local out=$($LFS heat_get $DIR/$tfile)
23028
23029         $LFS heat_get $DIR/$tfile
23030         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
23031         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
23032         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
23033         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
23034
23035         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
23036         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
23037         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
23038         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
23039
23040         sleep $((period_second + 3))
23041         echo "Sleep $((period_second + 3)) seconds..."
23042         # The recursion formula to calculate the heat of the file f is as
23043         # follow:
23044         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
23045         # Where Hi is the heat value in the period between time points i*I and
23046         # (i+1)*I; Ci is the access count in the period; the symbol P refers
23047         # to the weight of Ci.
23048         out=$($LFS heat_get $DIR/$tfile)
23049         $LFS heat_get $DIR/$tfile
23050         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
23051         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
23052         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
23053         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
23054
23055         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
23056                 error "read sample ($readsample) is wrong"
23057         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
23058                 error "write sample ($writesample) is wrong"
23059         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
23060                 error "read bytes ($readbyte) is wrong"
23061         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
23062                 error "write bytes ($writebyte) is wrong"
23063
23064         echo "QQQQ" > $DIR/$tfile
23065         echo "QQQQ" > $DIR/$tfile
23066         echo "QQQQ" > $DIR/$tfile
23067         cat $DIR/$tfile > /dev/null
23068         cat $DIR/$tfile > /dev/null
23069         cat $DIR/$tfile > /dev/null
23070         cat $DIR/$tfile > /dev/null
23071
23072         sleep $((period_second + 3))
23073         echo "Sleep $((period_second + 3)) seconds..."
23074
23075         out=$($LFS heat_get $DIR/$tfile)
23076         $LFS heat_get $DIR/$tfile
23077         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
23078         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
23079         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
23080         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
23081
23082         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
23083                 4 * $decay_pct) / 100") -eq 1 ] ||
23084                 error "read sample ($readsample1) is wrong"
23085         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
23086                 3 * $decay_pct) / 100") -eq 1 ] ||
23087                 error "write sample ($writesample1) is wrong"
23088         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
23089                 20 * $decay_pct) / 100") -eq 1 ] ||
23090                 error "read bytes ($readbyte1) is wrong"
23091         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
23092                 15 * $decay_pct) / 100") -eq 1 ] ||
23093                 error "write bytes ($writebyte1) is wrong"
23094
23095         echo "Turn off file heat for the file $DIR/$tfile"
23096         $LFS heat_set -o $DIR/$tfile
23097
23098         echo "QQQQ" > $DIR/$tfile
23099         echo "QQQQ" > $DIR/$tfile
23100         echo "QQQQ" > $DIR/$tfile
23101         cat $DIR/$tfile > /dev/null
23102         cat $DIR/$tfile > /dev/null
23103         cat $DIR/$tfile > /dev/null
23104         cat $DIR/$tfile > /dev/null
23105
23106         out=$($LFS heat_get $DIR/$tfile)
23107         $LFS heat_get $DIR/$tfile
23108         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
23109         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
23110         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
23111         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
23112
23113         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
23114         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
23115         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
23116         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
23117
23118         echo "Trun on file heat for the file $DIR/$tfile"
23119         $LFS heat_set -O $DIR/$tfile
23120
23121         echo "QQQQ" > $DIR/$tfile
23122         echo "QQQQ" > $DIR/$tfile
23123         echo "QQQQ" > $DIR/$tfile
23124         cat $DIR/$tfile > /dev/null
23125         cat $DIR/$tfile > /dev/null
23126         cat $DIR/$tfile > /dev/null
23127         cat $DIR/$tfile > /dev/null
23128
23129         out=$($LFS heat_get $DIR/$tfile)
23130         $LFS heat_get $DIR/$tfile
23131         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
23132         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
23133         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
23134         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
23135
23136         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
23137         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
23138         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
23139         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
23140
23141         $LFS heat_set -c $DIR/$tfile
23142         $LCTL set_param -n llite.*.file_heat=0
23143         echo "Turn off file heat support for the Lustre filesystem"
23144
23145         echo "QQQQ" > $DIR/$tfile
23146         echo "QQQQ" > $DIR/$tfile
23147         echo "QQQQ" > $DIR/$tfile
23148         cat $DIR/$tfile > /dev/null
23149         cat $DIR/$tfile > /dev/null
23150         cat $DIR/$tfile > /dev/null
23151         cat $DIR/$tfile > /dev/null
23152
23153         out=$($LFS heat_get $DIR/$tfile)
23154         $LFS heat_get $DIR/$tfile
23155         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
23156         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
23157         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
23158         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
23159
23160         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
23161         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
23162         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
23163         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
23164
23165         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
23166         rm -f $DIR/$tfile
23167 }
23168 run_test 813 "File heat verfication"
23169
23170 test_814()
23171 {
23172         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
23173         echo -n y >> $DIR/$tfile
23174         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
23175         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
23176 }
23177 run_test 814 "sparse cp works as expected (LU-12361)"
23178
23179 test_815()
23180 {
23181         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
23182         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
23183 }
23184 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
23185
23186 test_816() {
23187         [ "$SHARED_KEY" = true ] &&
23188                 skip "OSC connections never go IDLE with Shared-Keys enabled"
23189
23190         $LFS setstripe -c 1 -i 0 $DIR/$tfile
23191         # ensure ost1 is connected
23192         stat $DIR/$tfile >/dev/null || error "can't stat"
23193         wait_osc_import_state client ost1 FULL
23194         # no locks, no reqs to let the connection idle
23195         cancel_lru_locks osc
23196         lru_resize_disable osc
23197         local before
23198         local now
23199         before=$($LCTL get_param -n \
23200                  ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
23201
23202         wait_osc_import_state client ost1 IDLE
23203         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
23204         now=$($LCTL get_param -n \
23205               ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
23206         [ $before == $now ] || error "lru_size changed $before != $now"
23207 }
23208 run_test 816 "do not reset lru_resize on idle reconnect"
23209
23210 cleanup_817() {
23211         umount $tmpdir
23212         exportfs -u localhost:$DIR/nfsexp
23213         rm -rf $DIR/nfsexp
23214 }
23215
23216 test_817() {
23217         systemctl restart nfs-server.service || skip "failed to restart nfsd"
23218
23219         mkdir -p $DIR/nfsexp
23220         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
23221                 error "failed to export nfs"
23222
23223         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
23224         stack_trap cleanup_817 EXIT
23225
23226         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
23227                 error "failed to mount nfs to $tmpdir"
23228
23229         cp /bin/true $tmpdir
23230         $DIR/nfsexp/true || error "failed to execute 'true' command"
23231 }
23232 run_test 817 "nfsd won't cache write lock for exec file"
23233
23234 test_818() {
23235         mkdir $DIR/$tdir
23236         $LFS setstripe -c1 -i0 $DIR/$tfile
23237         $LFS setstripe -c1 -i1 $DIR/$tfile
23238         stop $SINGLEMDS
23239         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
23240         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
23241         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
23242                 error "start $SINGLEMDS failed"
23243         rm -rf $DIR/$tdir
23244 }
23245 run_test 818 "unlink with failed llog"
23246
23247 test_819a() {
23248         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23249         cancel_lru_locks osc
23250         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
23251         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
23252         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
23253         rm -f $TDIR/$tfile
23254 }
23255 run_test 819a "too big niobuf in read"
23256
23257 test_819b() {
23258         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
23259         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
23260         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23261         cancel_lru_locks osc
23262         sleep 1
23263         rm -f $TDIR/$tfile
23264 }
23265 run_test 819b "too big niobuf in write"
23266
23267
23268 function test_820_start_ost() {
23269         sleep 5
23270
23271         for num in $(seq $OSTCOUNT); do
23272                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
23273         done
23274 }
23275
23276 test_820() {
23277         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
23278
23279         mkdir $DIR/$tdir
23280         umount_client $MOUNT || error "umount failed"
23281         for num in $(seq $OSTCOUNT); do
23282                 stop ost$num
23283         done
23284
23285         # mount client with no active OSTs
23286         # so that the client can't initialize max LOV EA size
23287         # from OSC notifications
23288         mount_client $MOUNT || error "mount failed"
23289         # delay OST starting to keep this 0 max EA size for a while
23290         test_820_start_ost &
23291
23292         # create a directory on MDS2
23293         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
23294                 error "Failed to create directory"
23295         # open intent should update default EA size
23296         # see mdc_update_max_ea_from_body()
23297         # notice this is the very first RPC to MDS2
23298         cp /etc/services $DIR/$tdir/mds2 ||
23299                 error "Failed to copy files to mds$n"
23300 }
23301 run_test 820 "update max EA from open intent"
23302
23303 #
23304 # tests that do cleanup/setup should be run at the end
23305 #
23306
23307 test_900() {
23308         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23309         local ls
23310
23311         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
23312         $LCTL set_param fail_loc=0x903
23313
23314         cancel_lru_locks MGC
23315
23316         FAIL_ON_ERROR=true cleanup
23317         FAIL_ON_ERROR=true setup
23318 }
23319 run_test 900 "umount should not race with any mgc requeue thread"
23320
23321 # LUS-6253/LU-11185
23322 test_901() {
23323         local oldc
23324         local newc
23325         local olds
23326         local news
23327         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23328
23329         # some get_param have a bug to handle dot in param name
23330         cancel_lru_locks MGC
23331         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
23332         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
23333         umount_client $MOUNT || error "umount failed"
23334         mount_client $MOUNT || error "mount failed"
23335         cancel_lru_locks MGC
23336         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
23337         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
23338
23339         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
23340         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
23341
23342         return 0
23343 }
23344 run_test 901 "don't leak a mgc lock on client umount"
23345
23346 # LU-13377
23347 test_902() {
23348         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
23349                 skip "client does not have LU-13377 fix"
23350         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
23351         $LCTL set_param fail_loc=0x1415
23352         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23353         cancel_lru_locks osc
23354         rm -f $DIR/$tfile
23355 }
23356 run_test 902 "test short write doesn't hang lustre"
23357
23358 complete $SECONDS
23359 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
23360 check_and_cleanup_lustre
23361 if [ "$I_MOUNTED" != "yes" ]; then
23362         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
23363 fi
23364 exit_status