Whamcloud - gitweb
LU-12785 dom: adjust DOM stripe size by free space
[fs/lustre-release.git] / lustre / tests / sanity.sh
1 #!/bin/bash
2 #
3 # Run select tests by setting ONLY, or as arguments to the script.
4 # Skip specific tests by setting EXCEPT.
5 #
6 # e.g. ONLY="22 23" or ONLY="`seq 32 39`" or EXCEPT="31"
7 set -e
8
9 ONLY=${ONLY:-"$*"}
10
11 # Check Grants after these tests
12 GRANT_CHECK_LIST="$GRANT_CHECK_LIST 42a 42b 42c 42d 42e 63a 63b 64a 64b 64c 64d"
13
14 OSC=${OSC:-"osc"}
15
16 CC=${CC:-cc}
17 CREATETEST=${CREATETEST:-createtest}
18 LVERIFY=${LVERIFY:-ll_dirstripe_verify}
19 OPENFILE=${OPENFILE:-openfile}
20 OPENUNLINK=${OPENUNLINK:-openunlink}
21 READS=${READS:-"reads"}
22 MUNLINK=${MUNLINK:-munlink}
23 SOCKETSERVER=${SOCKETSERVER:-socketserver}
24 SOCKETCLIENT=${SOCKETCLIENT:-socketclient}
25 MEMHOG=${MEMHOG:-memhog}
26 DIRECTIO=${DIRECTIO:-directio}
27 ACCEPTOR_PORT=${ACCEPTOR_PORT:-988}
28 DEF_STRIPE_COUNT=-1
29 CHECK_GRANT=${CHECK_GRANT:-"yes"}
30 GRANT_CHECK_LIST=${GRANT_CHECK_LIST:-""}
31 export PARALLEL=${PARALLEL:-"no"}
32
33 TRACE=${TRACE:-""}
34 LUSTRE=${LUSTRE:-$(dirname $0)/..}
35 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
36 . $LUSTRE/tests/test-framework.sh
37 init_test_env $@
38
39 init_logging
40
41 ALWAYS_EXCEPT="$SANITY_EXCEPT "
42 # bug number for skipped test: LU-9693 LU-6493 LU-9693
43 ALWAYS_EXCEPT+="               42a     42b     42c "
44 # bug number:    LU-8411 LU-9054 LU-13314
45 ALWAYS_EXCEPT+=" 407     312    56ob"
46
47 if $SHARED_KEY; then
48         # bug number:    LU-9795 LU-9795 LU-9795 LU-9795
49         ALWAYS_EXCEPT+=" 17n     60a     133g    300f"
50 fi
51
52 selinux_status=$(getenforce)
53 if [ "$selinux_status" != "Disabled" ]; then
54         # bug number:
55         ALWAYS_EXCEPT+=""
56 fi
57
58 # skip the grant tests for ARM until they are fixed
59 if [[ $(uname -m) = aarch64 ]]; then
60         # bug number:    LU-11596
61         ALWAYS_EXCEPT+=" $GRANT_CHECK_LIST"
62         # bug number:    LU-11671 LU-11667
63         ALWAYS_EXCEPT+=" 45       317"
64 fi
65
66 # skip nfs tests on kernels >= 4.14.0 until they are fixed
67 if [ $LINUX_VERSION_CODE -ge $(version_code 4.14.0) ]; then
68         # bug number:   LU-12661
69         ALWAYS_EXCEPT+=" 817"
70 fi
71 # skip cgroup tests on RHEL8.1 kernels until they are fixed
72 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
73       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
74         # bug number:   LU-13063
75         ALWAYS_EXCEPT+=" 411"
76 fi
77
78 #                                  5          12     8   12  (min)"
79 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 64b 68 71 115 135 136 300o"
80
81 if [ "$mds1_FSTYPE" = "zfs" ]; then
82         # bug number for skipped test:
83         ALWAYS_EXCEPT="$ALWAYS_EXCEPT  "
84         #                                               13    (min)"
85         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
86 fi
87
88 # Get the SLES distro version
89 #
90 # Returns a version string that should only be used in comparing
91 # strings returned by version_code()
92 sles_version_code()
93 {
94         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
95
96         # All SuSE Linux versions have one decimal. version_code expects two
97         local sles_version=$version.0
98         version_code $sles_version
99 }
100
101 # Check if we are running on Ubuntu or SLES so we can make decisions on
102 # what tests to run
103 if [ -r /etc/SuSE-release ]; then
104         sles_version=$(sles_version_code)
105         [ $sles_version -lt $(version_code 11.4.0) ] &&
106                 # bug number for skipped test: LU-4341
107                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  170"
108         [ $sles_version -lt $(version_code 12.0.0) ] &&
109                 # bug number for skipped test: LU-3703
110                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  234"
111 elif [ -r /etc/os-release ]; then
112         if grep -qi ubuntu /etc/os-release; then
113                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
114                                                 -e 's/^VERSION=//p' \
115                                                 /etc/os-release |
116                                                 awk '{ print $1 }'))
117
118                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
119                         # bug number for skipped test:
120                         #                LU-10334 LU-10366
121                         ALWAYS_EXCEPT+=" 103a     410"
122                 fi
123         fi
124 fi
125
126 build_test_filter
127 FAIL_ON_ERROR=false
128
129 cleanup() {
130         echo -n "cln.."
131         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
132         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
133 }
134 setup() {
135         echo -n "mnt.."
136         load_modules
137         setupall || exit 10
138         echo "done"
139 }
140
141 check_swap_layouts_support()
142 {
143         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
144                 skip "Does not support layout lock."
145 }
146
147 check_and_setup_lustre
148 DIR=${DIR:-$MOUNT}
149 assert_DIR
150
151 MAXFREE=${MAXFREE:-$((200000 * $OSTCOUNT))}
152
153 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
154 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
155 rm -rf $DIR/[Rdfs][0-9]*
156
157 # $RUNAS_ID may get set incorrectly somewhere else
158 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
159         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
160
161 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
162
163 if [ "${ONLY}" = "MOUNT" ] ; then
164         echo "Lustre is up, please go on"
165         exit
166 fi
167
168 echo "preparing for tests involving mounts"
169 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
170 touch $EXT2_DEV
171 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
172 echo # add a newline after mke2fs.
173
174 umask 077
175
176 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
177 lctl set_param debug=-1 2> /dev/null || true
178 test_0a() {
179         touch $DIR/$tfile
180         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
181         rm $DIR/$tfile
182         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
183 }
184 run_test 0a "touch; rm ====================="
185
186 test_0b() {
187         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
188         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
189 }
190 run_test 0b "chmod 0755 $DIR ============================="
191
192 test_0c() {
193         $LCTL get_param mdc.*.import | grep "state: FULL" ||
194                 error "import not FULL"
195         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
196                 error "bad target"
197 }
198 run_test 0c "check import proc"
199
200 test_0d() { # LU-3397
201         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
202                 skip "proc exports not supported before 2.10.57"
203
204         local mgs_exp="mgs.MGS.exports"
205         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
206         local exp_client_nid
207         local exp_client_version
208         local exp_val
209         local imp_val
210         local temp_imp=$DIR/$tfile.import
211         local temp_exp=$DIR/$tfile.export
212
213         # save mgc import file to $temp_imp
214         $LCTL get_param mgc.*.import | tee $temp_imp
215         # Check if client uuid is found in MGS export
216         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
217                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
218                         $client_uuid ] &&
219                         break;
220         done
221         # save mgs export file to $temp_exp
222         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
223
224         # Compare the value of field "connect_flags"
225         imp_val=$(grep "connect_flags" $temp_imp)
226         exp_val=$(grep "connect_flags" $temp_exp)
227         [ "$exp_val" == "$imp_val" ] ||
228                 error "export flags '$exp_val' != import flags '$imp_val'"
229
230         # Compare the value of client version
231         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
232         exp_val=$(version_code $exp_client_version)
233         imp_val=$CLIENT_VERSION
234         [ "$exp_val" == "$imp_val" ] ||
235                 error "export client version '$exp_val' != '$imp_val'"
236 }
237 run_test 0d "check export proc ============================="
238
239 test_1() {
240         test_mkdir $DIR/$tdir
241         test_mkdir $DIR/$tdir/d2
242         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
243         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
244         rmdir $DIR/$tdir/d2
245         rmdir $DIR/$tdir
246         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
247 }
248 run_test 1 "mkdir; remkdir; rmdir"
249
250 test_2() {
251         test_mkdir $DIR/$tdir
252         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
253         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
254         rm -r $DIR/$tdir
255         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
256 }
257 run_test 2 "mkdir; touch; rmdir; check file"
258
259 test_3() {
260         test_mkdir $DIR/$tdir
261         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
262         touch $DIR/$tdir/$tfile
263         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
264         rm -r $DIR/$tdir
265         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
266 }
267 run_test 3 "mkdir; touch; rmdir; check dir"
268
269 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
270 test_4() {
271         test_mkdir -i 1 $DIR/$tdir
272
273         touch $DIR/$tdir/$tfile ||
274                 error "Create file under remote directory failed"
275
276         rmdir $DIR/$tdir &&
277                 error "Expect error removing in-use dir $DIR/$tdir"
278
279         test -d $DIR/$tdir || error "Remote directory disappeared"
280
281         rm -rf $DIR/$tdir || error "remove remote dir error"
282 }
283 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
284
285 test_5() {
286         test_mkdir $DIR/$tdir
287         test_mkdir $DIR/$tdir/d2
288         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
289         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
290         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
291 }
292 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
293
294 test_6a() {
295         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
296         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
297         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
298                 error "$tfile does not have perm 0666 or UID $UID"
299         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
300         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
301                 error "$tfile should be 0666 and owned by UID $UID"
302 }
303 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
304
305 test_6c() {
306         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
307
308         touch $DIR/$tfile
309         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
310         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
311                 error "$tfile should be owned by UID $RUNAS_ID"
312         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
313         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
314                 error "$tfile should be owned by UID $RUNAS_ID"
315 }
316 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
317
318 test_6e() {
319         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
320
321         touch $DIR/$tfile
322         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
323         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
324                 error "$tfile should be owned by GID $UID"
325         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
326         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
327                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
328 }
329 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
330
331 test_6g() {
332         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
333
334         test_mkdir $DIR/$tdir
335         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
336         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
337         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
338         test_mkdir $DIR/$tdir/d/subdir
339         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
340                 error "$tdir/d/subdir should be GID $RUNAS_GID"
341         if [[ $MDSCOUNT -gt 1 ]]; then
342                 # check remote dir sgid inherite
343                 $LFS mkdir -i 0 $DIR/$tdir.local ||
344                         error "mkdir $tdir.local failed"
345                 chmod g+s $DIR/$tdir.local ||
346                         error "chmod $tdir.local failed"
347                 chgrp $RUNAS_GID $DIR/$tdir.local ||
348                         error "chgrp $tdir.local failed"
349                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
350                         error "mkdir $tdir.remote failed"
351                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
352                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
353                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
354                         error "$tdir.remote should be mode 02755"
355         fi
356 }
357 run_test 6g "verify new dir in sgid dir inherits group"
358
359 test_6h() { # bug 7331
360         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
361
362         touch $DIR/$tfile || error "touch failed"
363         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
364         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
365                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
366         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
367                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
368 }
369 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
370
371 test_7a() {
372         test_mkdir $DIR/$tdir
373         $MCREATE $DIR/$tdir/$tfile
374         chmod 0666 $DIR/$tdir/$tfile
375         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
376                 error "$tdir/$tfile should be mode 0666"
377 }
378 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
379
380 test_7b() {
381         if [ ! -d $DIR/$tdir ]; then
382                 test_mkdir $DIR/$tdir
383         fi
384         $MCREATE $DIR/$tdir/$tfile
385         echo -n foo > $DIR/$tdir/$tfile
386         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
387         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
388 }
389 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
390
391 test_8() {
392         test_mkdir $DIR/$tdir
393         touch $DIR/$tdir/$tfile
394         chmod 0666 $DIR/$tdir/$tfile
395         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
396                 error "$tfile mode not 0666"
397 }
398 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
399
400 test_9() {
401         test_mkdir $DIR/$tdir
402         test_mkdir $DIR/$tdir/d2
403         test_mkdir $DIR/$tdir/d2/d3
404         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
405 }
406 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
407
408 test_10() {
409         test_mkdir $DIR/$tdir
410         test_mkdir $DIR/$tdir/d2
411         touch $DIR/$tdir/d2/$tfile
412         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
413                 error "$tdir/d2/$tfile not a file"
414 }
415 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
416
417 test_11() {
418         test_mkdir $DIR/$tdir
419         test_mkdir $DIR/$tdir/d2
420         chmod 0666 $DIR/$tdir/d2
421         chmod 0705 $DIR/$tdir/d2
422         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
423                 error "$tdir/d2 mode not 0705"
424 }
425 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
426
427 test_12() {
428         test_mkdir $DIR/$tdir
429         touch $DIR/$tdir/$tfile
430         chmod 0666 $DIR/$tdir/$tfile
431         chmod 0654 $DIR/$tdir/$tfile
432         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
433                 error "$tdir/d2 mode not 0654"
434 }
435 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
436
437 test_13() {
438         test_mkdir $DIR/$tdir
439         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
440         >  $DIR/$tdir/$tfile
441         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
442                 error "$tdir/$tfile size not 0 after truncate"
443 }
444 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
445
446 test_14() {
447         test_mkdir $DIR/$tdir
448         touch $DIR/$tdir/$tfile
449         rm $DIR/$tdir/$tfile
450         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
451 }
452 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
453
454 test_15() {
455         test_mkdir $DIR/$tdir
456         touch $DIR/$tdir/$tfile
457         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
458         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
459                 error "$tdir/${tfile_2} not a file after rename"
460         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
461 }
462 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
463
464 test_16() {
465         test_mkdir $DIR/$tdir
466         touch $DIR/$tdir/$tfile
467         rm -rf $DIR/$tdir/$tfile
468         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
469 }
470 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
471
472 test_17a() {
473         test_mkdir $DIR/$tdir
474         touch $DIR/$tdir/$tfile
475         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
476         ls -l $DIR/$tdir
477         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
478                 error "$tdir/l-exist not a symlink"
479         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
480                 error "$tdir/l-exist not referencing a file"
481         rm -f $DIR/$tdir/l-exist
482         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
483 }
484 run_test 17a "symlinks: create, remove (real)"
485
486 test_17b() {
487         test_mkdir $DIR/$tdir
488         ln -s no-such-file $DIR/$tdir/l-dangle
489         ls -l $DIR/$tdir
490         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
491                 error "$tdir/l-dangle not referencing no-such-file"
492         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
493                 error "$tdir/l-dangle not referencing non-existent file"
494         rm -f $DIR/$tdir/l-dangle
495         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
496 }
497 run_test 17b "symlinks: create, remove (dangling)"
498
499 test_17c() { # bug 3440 - don't save failed open RPC for replay
500         test_mkdir $DIR/$tdir
501         ln -s foo $DIR/$tdir/$tfile
502         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
503 }
504 run_test 17c "symlinks: open dangling (should return error)"
505
506 test_17d() {
507         test_mkdir $DIR/$tdir
508         ln -s foo $DIR/$tdir/$tfile
509         touch $DIR/$tdir/$tfile || error "creating to new symlink"
510 }
511 run_test 17d "symlinks: create dangling"
512
513 test_17e() {
514         test_mkdir $DIR/$tdir
515         local foo=$DIR/$tdir/$tfile
516         ln -s $foo $foo || error "create symlink failed"
517         ls -l $foo || error "ls -l failed"
518         ls $foo && error "ls not failed" || true
519 }
520 run_test 17e "symlinks: create recursive symlink (should return error)"
521
522 test_17f() {
523         test_mkdir $DIR/$tdir
524         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
525         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
526         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
527         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
528         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
529         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890/aaaaaaaaaa/bbbbbbbbbb/cccccccccc/dddddddddd/eeeeeeeeee/ffffffffff/ $DIR/$tdir/666
530         ls -l  $DIR/$tdir
531 }
532 run_test 17f "symlinks: long and very long symlink name"
533
534 # str_repeat(S, N) generate a string that is string S repeated N times
535 str_repeat() {
536         local s=$1
537         local n=$2
538         local ret=''
539         while [ $((n -= 1)) -ge 0 ]; do
540                 ret=$ret$s
541         done
542         echo $ret
543 }
544
545 # Long symlinks and LU-2241
546 test_17g() {
547         test_mkdir $DIR/$tdir
548         local TESTS="59 60 61 4094 4095"
549
550         # Fix for inode size boundary in 2.1.4
551         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
552                 TESTS="4094 4095"
553
554         # Patch not applied to 2.2 or 2.3 branches
555         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
556         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
557                 TESTS="4094 4095"
558
559         for i in $TESTS; do
560                 local SYMNAME=$(str_repeat 'x' $i)
561                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
562                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
563         done
564 }
565 run_test 17g "symlinks: really long symlink name and inode boundaries"
566
567 test_17h() { #bug 17378
568         [ $PARALLEL == "yes" ] && skip "skip parallel run"
569         remote_mds_nodsh && skip "remote MDS with nodsh"
570
571         local mdt_idx
572
573         test_mkdir $DIR/$tdir
574         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
575         $LFS setstripe -c -1 $DIR/$tdir
576         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
577         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
578         touch $DIR/$tdir/$tfile || true
579 }
580 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
581
582 test_17i() { #bug 20018
583         [ $PARALLEL == "yes" ] && skip "skip parallel run"
584         remote_mds_nodsh && skip "remote MDS with nodsh"
585
586         local foo=$DIR/$tdir/$tfile
587         local mdt_idx
588
589         test_mkdir -c1 $DIR/$tdir
590         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
591         ln -s $foo $foo || error "create symlink failed"
592 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
593         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
594         ls -l $foo && error "error not detected"
595         return 0
596 }
597 run_test 17i "don't panic on short symlink (should return error)"
598
599 test_17k() { #bug 22301
600         [ $PARALLEL == "yes" ] && skip "skip parallel run"
601         [[ -z "$(which rsync 2>/dev/null)" ]] &&
602                 skip "no rsync command"
603         rsync --help | grep -q xattr ||
604                 skip_env "$(rsync --version | head -n1) does not support xattrs"
605         test_mkdir $DIR/$tdir
606         test_mkdir $DIR/$tdir.new
607         touch $DIR/$tdir/$tfile
608         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
609         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
610                 error "rsync failed with xattrs enabled"
611 }
612 run_test 17k "symlinks: rsync with xattrs enabled"
613
614 test_17l() { # LU-279
615         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
616                 skip "no getfattr command"
617
618         test_mkdir $DIR/$tdir
619         touch $DIR/$tdir/$tfile
620         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
621         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
622                 # -h to not follow symlinks. -m '' to list all the xattrs.
623                 # grep to remove first line: '# file: $path'.
624                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
625                 do
626                         lgetxattr_size_check $path $xattr ||
627                                 error "lgetxattr_size_check $path $xattr failed"
628                 done
629         done
630 }
631 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
632
633 # LU-1540
634 test_17m() {
635         [ $PARALLEL == "yes" ] && skip "skip parallel run"
636         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
637         remote_mds_nodsh && skip "remote MDS with nodsh"
638         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
639         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
640                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
641
642         local short_sym="0123456789"
643         local wdir=$DIR/$tdir
644         local i
645
646         test_mkdir $wdir
647         long_sym=$short_sym
648         # create a long symlink file
649         for ((i = 0; i < 4; ++i)); do
650                 long_sym=${long_sym}${long_sym}
651         done
652
653         echo "create 512 short and long symlink files under $wdir"
654         for ((i = 0; i < 256; ++i)); do
655                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
656                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
657         done
658
659         echo "erase them"
660         rm -f $wdir/*
661         sync
662         wait_delete_completed
663
664         echo "recreate the 512 symlink files with a shorter string"
665         for ((i = 0; i < 512; ++i)); do
666                 # rewrite the symlink file with a shorter string
667                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
668                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
669         done
670
671         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
672         local devname=$(mdsdevname $mds_index)
673
674         echo "stop and checking mds${mds_index}:"
675         # e2fsck should not return error
676         stop mds${mds_index}
677         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
678         rc=$?
679
680         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
681                 error "start mds${mds_index} failed"
682         df $MOUNT > /dev/null 2>&1
683         [ $rc -eq 0 ] ||
684                 error "e2fsck detected error for short/long symlink: rc=$rc"
685         rm -f $wdir/*
686 }
687 run_test 17m "run e2fsck against MDT which contains short/long symlink"
688
689 check_fs_consistency_17n() {
690         local mdt_index
691         local rc=0
692
693         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
694         # so it only check MDT1/MDT2 instead of all of MDTs.
695         for mdt_index in 1 2; do
696                 local devname=$(mdsdevname $mdt_index)
697                 # e2fsck should not return error
698                 stop mds${mdt_index}
699                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
700                         rc=$((rc + $?))
701
702                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
703                         error "mount mds$mdt_index failed"
704                 df $MOUNT > /dev/null 2>&1
705         done
706         return $rc
707 }
708
709 test_17n() {
710         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
711         [ $PARALLEL == "yes" ] && skip "skip parallel run"
712         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
713         remote_mds_nodsh && skip "remote MDS with nodsh"
714         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
715         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
716                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
717
718         local i
719
720         test_mkdir $DIR/$tdir
721         for ((i=0; i<10; i++)); do
722                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
723                         error "create remote dir error $i"
724                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
725                         error "create files under remote dir failed $i"
726         done
727
728         check_fs_consistency_17n ||
729                 error "e2fsck report error after create files under remote dir"
730
731         for ((i = 0; i < 10; i++)); do
732                 rm -rf $DIR/$tdir/remote_dir_${i} ||
733                         error "destroy remote dir error $i"
734         done
735
736         check_fs_consistency_17n ||
737                 error "e2fsck report error after unlink files under remote dir"
738
739         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
740                 skip "lustre < 2.4.50 does not support migrate mv"
741
742         for ((i = 0; i < 10; i++)); do
743                 mkdir -p $DIR/$tdir/remote_dir_${i}
744                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
745                         error "create files under remote dir failed $i"
746                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
747                         error "migrate remote dir error $i"
748         done
749         check_fs_consistency_17n || error "e2fsck report error after migration"
750
751         for ((i = 0; i < 10; i++)); do
752                 rm -rf $DIR/$tdir/remote_dir_${i} ||
753                         error "destroy remote dir error $i"
754         done
755
756         check_fs_consistency_17n || error "e2fsck report error after unlink"
757 }
758 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
759
760 test_17o() {
761         remote_mds_nodsh && skip "remote MDS with nodsh"
762         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
763                 skip "Need MDS version at least 2.3.64"
764
765         local wdir=$DIR/${tdir}o
766         local mdt_index
767         local rc=0
768
769         test_mkdir $wdir
770         touch $wdir/$tfile
771         mdt_index=$($LFS getstripe -m $wdir/$tfile)
772         mdt_index=$((mdt_index + 1))
773
774         cancel_lru_locks mdc
775         #fail mds will wait the failover finish then set
776         #following fail_loc to avoid interfer the recovery process.
777         fail mds${mdt_index}
778
779         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
780         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
781         ls -l $wdir/$tfile && rc=1
782         do_facet mds${mdt_index} lctl set_param fail_loc=0
783         [[ $rc -eq 0 ]] || error "stat file should fail"
784 }
785 run_test 17o "stat file with incompat LMA feature"
786
787 test_18() {
788         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
789         ls $DIR || error "Failed to ls $DIR: $?"
790 }
791 run_test 18 "touch .../f ; ls ... =============================="
792
793 test_19a() {
794         touch $DIR/$tfile
795         ls -l $DIR
796         rm $DIR/$tfile
797         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
798 }
799 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
800
801 test_19b() {
802         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
803 }
804 run_test 19b "ls -l .../f19 (should return error) =============="
805
806 test_19c() {
807         [ $RUNAS_ID -eq $UID ] &&
808                 skip_env "RUNAS_ID = UID = $UID -- skipping"
809
810         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
811 }
812 run_test 19c "$RUNAS touch .../f19 (should return error) =="
813
814 test_19d() {
815         cat $DIR/f19 && error || true
816 }
817 run_test 19d "cat .../f19 (should return error) =============="
818
819 test_20() {
820         touch $DIR/$tfile
821         rm $DIR/$tfile
822         touch $DIR/$tfile
823         rm $DIR/$tfile
824         touch $DIR/$tfile
825         rm $DIR/$tfile
826         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
827 }
828 run_test 20 "touch .../f ; ls -l ..."
829
830 test_21() {
831         test_mkdir $DIR/$tdir
832         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
833         ln -s dangle $DIR/$tdir/link
834         echo foo >> $DIR/$tdir/link
835         cat $DIR/$tdir/dangle
836         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
837         $CHECKSTAT -f -t file $DIR/$tdir/link ||
838                 error "$tdir/link not linked to a file"
839 }
840 run_test 21 "write to dangling link"
841
842 test_22() {
843         local wdir=$DIR/$tdir
844         test_mkdir $wdir
845         chown $RUNAS_ID:$RUNAS_GID $wdir
846         (cd $wdir || error "cd $wdir failed";
847                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
848                 $RUNAS tar xf -)
849         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
850         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
851         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
852                 error "checkstat -u failed"
853 }
854 run_test 22 "unpack tar archive as non-root user"
855
856 # was test_23
857 test_23a() {
858         test_mkdir $DIR/$tdir
859         local file=$DIR/$tdir/$tfile
860
861         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
862         openfile -f O_CREAT:O_EXCL $file &&
863                 error "$file recreate succeeded" || true
864 }
865 run_test 23a "O_CREAT|O_EXCL in subdir"
866
867 test_23b() { # bug 18988
868         test_mkdir $DIR/$tdir
869         local file=$DIR/$tdir/$tfile
870
871         rm -f $file
872         echo foo > $file || error "write filed"
873         echo bar >> $file || error "append filed"
874         $CHECKSTAT -s 8 $file || error "wrong size"
875         rm $file
876 }
877 run_test 23b "O_APPEND check"
878
879 # LU-9409, size with O_APPEND and tiny writes
880 test_23c() {
881         local file=$DIR/$tfile
882
883         # single dd
884         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
885         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
886         rm -f $file
887
888         # racing tiny writes
889         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
890         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
891         wait
892         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
893         rm -f $file
894
895         #racing tiny & normal writes
896         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
897         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
898         wait
899         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
900         rm -f $file
901
902         #racing tiny & normal writes 2, ugly numbers
903         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
904         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
905         wait
906         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
907         rm -f $file
908 }
909 run_test 23c "O_APPEND size checks for tiny writes"
910
911 # LU-11069 file offset is correct after appending writes
912 test_23d() {
913         local file=$DIR/$tfile
914         local offset
915
916         echo CentaurHauls > $file
917         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
918         if ((offset != 26)); then
919                 error "wrong offset, expected 26, got '$offset'"
920         fi
921 }
922 run_test 23d "file offset is correct after appending writes"
923
924 # rename sanity
925 test_24a() {
926         echo '-- same directory rename'
927         test_mkdir $DIR/$tdir
928         touch $DIR/$tdir/$tfile.1
929         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
930         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
931 }
932 run_test 24a "rename file to non-existent target"
933
934 test_24b() {
935         test_mkdir $DIR/$tdir
936         touch $DIR/$tdir/$tfile.{1,2}
937         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
938         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
939         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
940 }
941 run_test 24b "rename file to existing target"
942
943 test_24c() {
944         test_mkdir $DIR/$tdir
945         test_mkdir $DIR/$tdir/d$testnum.1
946         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
947         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
948         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
949 }
950 run_test 24c "rename directory to non-existent target"
951
952 test_24d() {
953         test_mkdir -c1 $DIR/$tdir
954         test_mkdir -c1 $DIR/$tdir/d$testnum.1
955         test_mkdir -c1 $DIR/$tdir/d$testnum.2
956         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
957         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
958         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
959 }
960 run_test 24d "rename directory to existing target"
961
962 test_24e() {
963         echo '-- cross directory renames --'
964         test_mkdir $DIR/R5a
965         test_mkdir $DIR/R5b
966         touch $DIR/R5a/f
967         mv $DIR/R5a/f $DIR/R5b/g
968         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
969         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
970 }
971 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
972
973 test_24f() {
974         test_mkdir $DIR/R6a
975         test_mkdir $DIR/R6b
976         touch $DIR/R6a/f $DIR/R6b/g
977         mv $DIR/R6a/f $DIR/R6b/g
978         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
979         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
980 }
981 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
982
983 test_24g() {
984         test_mkdir $DIR/R7a
985         test_mkdir $DIR/R7b
986         test_mkdir $DIR/R7a/d
987         mv $DIR/R7a/d $DIR/R7b/e
988         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
989         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
990 }
991 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
992
993 test_24h() {
994         test_mkdir -c1 $DIR/R8a
995         test_mkdir -c1 $DIR/R8b
996         test_mkdir -c1 $DIR/R8a/d
997         test_mkdir -c1 $DIR/R8b/e
998         mrename $DIR/R8a/d $DIR/R8b/e
999         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1000         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1001 }
1002 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1003
1004 test_24i() {
1005         echo "-- rename error cases"
1006         test_mkdir $DIR/R9
1007         test_mkdir $DIR/R9/a
1008         touch $DIR/R9/f
1009         mrename $DIR/R9/f $DIR/R9/a
1010         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1011         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1012         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1013 }
1014 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1015
1016 test_24j() {
1017         test_mkdir $DIR/R10
1018         mrename $DIR/R10/f $DIR/R10/g
1019         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1020         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1021         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1022 }
1023 run_test 24j "source does not exist ============================"
1024
1025 test_24k() {
1026         test_mkdir $DIR/R11a
1027         test_mkdir $DIR/R11a/d
1028         touch $DIR/R11a/f
1029         mv $DIR/R11a/f $DIR/R11a/d
1030         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1031         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1032 }
1033 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1034
1035 # bug 2429 - rename foo foo foo creates invalid file
1036 test_24l() {
1037         f="$DIR/f24l"
1038         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1039 }
1040 run_test 24l "Renaming a file to itself ========================"
1041
1042 test_24m() {
1043         f="$DIR/f24m"
1044         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1045         # on ext3 this does not remove either the source or target files
1046         # though the "expected" operation would be to remove the source
1047         $CHECKSTAT -t file ${f} || error "${f} missing"
1048         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1049 }
1050 run_test 24m "Renaming a file to a hard link to itself ========="
1051
1052 test_24n() {
1053     f="$DIR/f24n"
1054     # this stats the old file after it was renamed, so it should fail
1055     touch ${f}
1056     $CHECKSTAT ${f} || error "${f} missing"
1057     mv ${f} ${f}.rename
1058     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1059     $CHECKSTAT -a ${f} || error "${f} exists"
1060 }
1061 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1062
1063 test_24o() {
1064         test_mkdir $DIR/$tdir
1065         rename_many -s random -v -n 10 $DIR/$tdir
1066 }
1067 run_test 24o "rename of files during htree split"
1068
1069 test_24p() {
1070         test_mkdir $DIR/R12a
1071         test_mkdir $DIR/R12b
1072         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1073         mrename $DIR/R12a $DIR/R12b
1074         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1075         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1076         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1077         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1078 }
1079 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1080
1081 cleanup_multiop_pause() {
1082         trap 0
1083         kill -USR1 $MULTIPID
1084 }
1085
1086 test_24q() {
1087         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1088
1089         test_mkdir $DIR/R13a
1090         test_mkdir $DIR/R13b
1091         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1092         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1093         MULTIPID=$!
1094
1095         trap cleanup_multiop_pause EXIT
1096         mrename $DIR/R13a $DIR/R13b
1097         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1098         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1099         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1100         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1101         cleanup_multiop_pause
1102         wait $MULTIPID || error "multiop close failed"
1103 }
1104 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1105
1106 test_24r() { #bug 3789
1107         test_mkdir $DIR/R14a
1108         test_mkdir $DIR/R14a/b
1109         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1110         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1111         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1112 }
1113 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1114
1115 test_24s() {
1116         test_mkdir $DIR/R15a
1117         test_mkdir $DIR/R15a/b
1118         test_mkdir $DIR/R15a/b/c
1119         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1120         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1121         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1122 }
1123 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1124 test_24t() {
1125         test_mkdir $DIR/R16a
1126         test_mkdir $DIR/R16a/b
1127         test_mkdir $DIR/R16a/b/c
1128         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1129         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1130         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1131 }
1132 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1133
1134 test_24u() { # bug12192
1135         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1136         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1137 }
1138 run_test 24u "create stripe file"
1139
1140 simple_cleanup_common() {
1141         local rc=0
1142         trap 0
1143         [ -z "$DIR" ] || [ -z "$tdir" ] && return 0
1144
1145         local start=$SECONDS
1146         rm -rf $DIR/$tdir
1147         rc=$?
1148         wait_delete_completed
1149         echo "cleanup time $((SECONDS - start))"
1150         return $rc
1151 }
1152
1153 max_pages_per_rpc() {
1154         local mdtname="$(printf "MDT%04x" ${1:-0})"
1155         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1156 }
1157
1158 test_24v() {
1159         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1160
1161         local nrfiles=${COUNT:-100000}
1162         local fname="$DIR/$tdir/$tfile"
1163
1164         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1165         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1166
1167         test_mkdir "$(dirname $fname)"
1168         # assume MDT0000 has the fewest inodes
1169         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1170         local free_inodes=$(($(mdt_free_inodes 0) * stripes))
1171         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1172
1173         trap simple_cleanup_common EXIT
1174
1175         createmany -m "$fname" $nrfiles
1176
1177         cancel_lru_locks mdc
1178         lctl set_param mdc.*.stats clear
1179
1180         # was previously test_24D: LU-6101
1181         # readdir() returns correct number of entries after cursor reload
1182         local num_ls=$(ls $DIR/$tdir | wc -l)
1183         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1184         local num_all=$(ls -a $DIR/$tdir | wc -l)
1185         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1186                 [ $num_all -ne $((nrfiles + 2)) ]; then
1187                         error "Expected $nrfiles files, got $num_ls " \
1188                                 "($num_uniq unique $num_all .&..)"
1189         fi
1190         # LU-5 large readdir
1191         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1192         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1193         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1194         # take into account of overhead in lu_dirpage header and end mark in
1195         # each page, plus one in rpc_num calculation.
1196         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1197         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1198         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1199         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1200         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1201         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1202         echo "readpages: $mds_readpage rpc_max: $rpc_max"
1203         (( $mds_readpage < $rpc_max - 2 || $mds_readpage > $rpc_max + 1)) &&
1204                 error "large readdir doesn't take effect: " \
1205                       "$mds_readpage should be about $rpc_max"
1206
1207         simple_cleanup_common
1208 }
1209 run_test 24v "list large directory (test hash collision, b=17560)"
1210
1211 test_24w() { # bug21506
1212         SZ1=234852
1213         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1214         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1215         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1216         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1217         [[ "$SZ1" -eq "$SZ2" ]] ||
1218                 error "Error reading at the end of the file $tfile"
1219 }
1220 run_test 24w "Reading a file larger than 4Gb"
1221
1222 test_24x() {
1223         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1224         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1225         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1226                 skip "Need MDS version at least 2.7.56"
1227
1228         local MDTIDX=1
1229         local remote_dir=$DIR/$tdir/remote_dir
1230
1231         test_mkdir $DIR/$tdir
1232         $LFS mkdir -i $MDTIDX $remote_dir ||
1233                 error "create remote directory failed"
1234
1235         test_mkdir $DIR/$tdir/src_dir
1236         touch $DIR/$tdir/src_file
1237         test_mkdir $remote_dir/tgt_dir
1238         touch $remote_dir/tgt_file
1239
1240         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1241                 error "rename dir cross MDT failed!"
1242
1243         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1244                 error "rename file cross MDT failed!"
1245
1246         touch $DIR/$tdir/ln_file
1247         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1248                 error "ln file cross MDT failed"
1249
1250         rm -rf $DIR/$tdir || error "Can not delete directories"
1251 }
1252 run_test 24x "cross MDT rename/link"
1253
1254 test_24y() {
1255         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1256         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1257
1258         local remote_dir=$DIR/$tdir/remote_dir
1259         local mdtidx=1
1260
1261         test_mkdir $DIR/$tdir
1262         $LFS mkdir -i $mdtidx $remote_dir ||
1263                 error "create remote directory failed"
1264
1265         test_mkdir $remote_dir/src_dir
1266         touch $remote_dir/src_file
1267         test_mkdir $remote_dir/tgt_dir
1268         touch $remote_dir/tgt_file
1269
1270         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1271                 error "rename subdir in the same remote dir failed!"
1272
1273         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1274                 error "rename files in the same remote dir failed!"
1275
1276         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1277                 error "link files in the same remote dir failed!"
1278
1279         rm -rf $DIR/$tdir || error "Can not delete directories"
1280 }
1281 run_test 24y "rename/link on the same dir should succeed"
1282
1283 test_24z() {
1284         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1285         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1286                 skip "Need MDS version at least 2.12.51"
1287
1288         local index
1289
1290         for index in 0 1; do
1291                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1292                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1293         done
1294
1295         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1296
1297         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1298         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1299
1300         local mdts=$(comma_list $(mdts_nodes))
1301
1302         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1303         stack_trap "do_nodes $mdts $LCTL \
1304                 set_param mdt.*.enable_remote_rename=1" EXIT
1305
1306         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1307
1308         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1309         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1310 }
1311 run_test 24z "cross-MDT rename is done as cp"
1312
1313 test_24A() { # LU-3182
1314         local NFILES=5000
1315
1316         rm -rf $DIR/$tdir
1317         test_mkdir $DIR/$tdir
1318         trap simple_cleanup_common EXIT
1319         createmany -m $DIR/$tdir/$tfile $NFILES
1320         local t=$(ls $DIR/$tdir | wc -l)
1321         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1322         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1323         if [ $t -ne $NFILES ] || [ $u -ne $NFILES ] ||
1324            [ $v -ne $((NFILES + 2)) ] ; then
1325                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1326         fi
1327
1328         simple_cleanup_common || error "Can not delete directories"
1329 }
1330 run_test 24A "readdir() returns correct number of entries."
1331
1332 test_24B() { # LU-4805
1333         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1334
1335         local count
1336
1337         test_mkdir $DIR/$tdir
1338         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1339                 error "create striped dir failed"
1340
1341         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1342         [ $count -eq 2 ] || error "Expected 2, got $count"
1343
1344         touch $DIR/$tdir/striped_dir/a
1345
1346         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1347         [ $count -eq 3 ] || error "Expected 3, got $count"
1348
1349         touch $DIR/$tdir/striped_dir/.f
1350
1351         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1352         [ $count -eq 4 ] || error "Expected 4, got $count"
1353
1354         rm -rf $DIR/$tdir || error "Can not delete directories"
1355 }
1356 run_test 24B "readdir for striped dir return correct number of entries"
1357
1358 test_24C() {
1359         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1360
1361         mkdir $DIR/$tdir
1362         mkdir $DIR/$tdir/d0
1363         mkdir $DIR/$tdir/d1
1364
1365         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1366                 error "create striped dir failed"
1367
1368         cd $DIR/$tdir/d0/striped_dir
1369
1370         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1371         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1372         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1373
1374         [ "$d0_ino" = "$parent_ino" ] ||
1375                 error ".. wrong, expect $d0_ino, get $parent_ino"
1376
1377         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1378                 error "mv striped dir failed"
1379
1380         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1381
1382         [ "$d1_ino" = "$parent_ino" ] ||
1383                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1384 }
1385 run_test 24C "check .. in striped dir"
1386
1387 test_24E() {
1388         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1389         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1390
1391         mkdir -p $DIR/$tdir
1392         mkdir $DIR/$tdir/src_dir
1393         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1394                 error "create remote source failed"
1395
1396         touch $DIR/$tdir/src_dir/src_child/a
1397
1398         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1399                 error "create remote target dir failed"
1400
1401         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1402                 error "create remote target child failed"
1403
1404         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1405                 error "rename dir cross MDT failed!"
1406
1407         find $DIR/$tdir
1408
1409         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1410                 error "src_child still exists after rename"
1411
1412         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1413                 error "missing file(a) after rename"
1414
1415         rm -rf $DIR/$tdir || error "Can not delete directories"
1416 }
1417 run_test 24E "cross MDT rename/link"
1418
1419 test_24F () {
1420         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1421
1422         local repeats=1000
1423         [ "$SLOW" = "no" ] && repeats=100
1424
1425         mkdir -p $DIR/$tdir
1426
1427         echo "$repeats repeats"
1428         for ((i = 0; i < repeats; i++)); do
1429                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1430                 touch $DIR/$tdir/test/a || error "touch fails"
1431                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1432                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1433         done
1434
1435         true
1436 }
1437 run_test 24F "hash order vs readdir (LU-11330)"
1438
1439 test_25a() {
1440         echo '== symlink sanity ============================================='
1441
1442         test_mkdir $DIR/d25
1443         ln -s d25 $DIR/s25
1444         touch $DIR/s25/foo ||
1445                 error "File creation in symlinked directory failed"
1446 }
1447 run_test 25a "create file in symlinked directory ==============="
1448
1449 test_25b() {
1450         [ ! -d $DIR/d25 ] && test_25a
1451         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1452 }
1453 run_test 25b "lookup file in symlinked directory ==============="
1454
1455 test_26a() {
1456         test_mkdir $DIR/d26
1457         test_mkdir $DIR/d26/d26-2
1458         ln -s d26/d26-2 $DIR/s26
1459         touch $DIR/s26/foo || error "File creation failed"
1460 }
1461 run_test 26a "multiple component symlink ======================="
1462
1463 test_26b() {
1464         test_mkdir -p $DIR/$tdir/d26-2
1465         ln -s $tdir/d26-2/foo $DIR/s26-2
1466         touch $DIR/s26-2 || error "File creation failed"
1467 }
1468 run_test 26b "multiple component symlink at end of lookup ======"
1469
1470 test_26c() {
1471         test_mkdir $DIR/d26.2
1472         touch $DIR/d26.2/foo
1473         ln -s d26.2 $DIR/s26.2-1
1474         ln -s s26.2-1 $DIR/s26.2-2
1475         ln -s s26.2-2 $DIR/s26.2-3
1476         chmod 0666 $DIR/s26.2-3/foo
1477 }
1478 run_test 26c "chain of symlinks"
1479
1480 # recursive symlinks (bug 439)
1481 test_26d() {
1482         ln -s d26-3/foo $DIR/d26-3
1483 }
1484 run_test 26d "create multiple component recursive symlink"
1485
1486 test_26e() {
1487         [ ! -h $DIR/d26-3 ] && test_26d
1488         rm $DIR/d26-3
1489 }
1490 run_test 26e "unlink multiple component recursive symlink"
1491
1492 # recursive symlinks (bug 7022)
1493 test_26f() {
1494         test_mkdir $DIR/$tdir
1495         test_mkdir $DIR/$tdir/$tfile
1496         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1497         test_mkdir -p lndir/bar1
1498         test_mkdir $DIR/$tdir/$tfile/$tfile
1499         cd $tfile                || error "cd $tfile failed"
1500         ln -s .. dotdot          || error "ln dotdot failed"
1501         ln -s dotdot/lndir lndir || error "ln lndir failed"
1502         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1503         output=`ls $tfile/$tfile/lndir/bar1`
1504         [ "$output" = bar1 ] && error "unexpected output"
1505         rm -r $tfile             || error "rm $tfile failed"
1506         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1507 }
1508 run_test 26f "rm -r of a directory which has recursive symlink"
1509
1510 test_27a() {
1511         test_mkdir $DIR/$tdir
1512         $LFS getstripe $DIR/$tdir
1513         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1514         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1515         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1516 }
1517 run_test 27a "one stripe file"
1518
1519 test_27b() {
1520         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1521
1522         test_mkdir $DIR/$tdir
1523         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1524         $LFS getstripe -c $DIR/$tdir/$tfile
1525         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1526                 error "two-stripe file doesn't have two stripes"
1527
1528         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1529 }
1530 run_test 27b "create and write to two stripe file"
1531
1532 # 27c family tests specific striping, setstripe -o
1533 test_27ca() {
1534         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1535         test_mkdir -p $DIR/$tdir
1536         local osts="1"
1537
1538         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1539         $LFS getstripe -i $DIR/$tdir/$tfile
1540         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1541                 error "stripe not on specified OST"
1542
1543         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1544 }
1545 run_test 27ca "one stripe on specified OST"
1546
1547 test_27cb() {
1548         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1549         test_mkdir -p $DIR/$tdir
1550         local osts="1,0"
1551         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1552         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1553         echo "$getstripe"
1554
1555         # Strip getstripe output to a space separated list of OSTs
1556         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1557                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1558         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1559                 error "stripes not on specified OSTs"
1560
1561         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1562 }
1563 run_test 27cb "two stripes on specified OSTs"
1564
1565 test_27cc() {
1566         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1567         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1568                 skip "server does not support overstriping"
1569
1570         test_mkdir -p $DIR/$tdir
1571         local osts="0,0"
1572         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1573         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1574         echo "$getstripe"
1575
1576         # Strip getstripe output to a space separated list of OSTs
1577         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1578                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1579         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1580                 error "stripes not on specified OSTs"
1581
1582         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1583 }
1584 run_test 27cc "two stripes on the same OST"
1585
1586 test_27cd() {
1587         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1588         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1589                 skip "server does not support overstriping"
1590         test_mkdir -p $DIR/$tdir
1591         local osts="0,1,1,0"
1592         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1593         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1594         echo "$getstripe"
1595
1596         # Strip getstripe output to a space separated list of OSTs
1597         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1598                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1599         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1600                 error "stripes not on specified OSTs"
1601
1602         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1603 }
1604 run_test 27cd "four stripes on two OSTs"
1605
1606 test_27ce() {
1607         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1608                 skip_env "too many osts, skipping"
1609         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1610                 skip "server does not support overstriping"
1611         # We do one more stripe than we have OSTs
1612         [ $OSTCOUNT -ge 159 ] || large_xattr_enabled ||
1613                 skip_env "ea_inode feature disabled"
1614
1615         test_mkdir -p $DIR/$tdir
1616         local osts=""
1617         for i in $(seq 0 $OSTCOUNT);
1618         do
1619                 osts=$osts"0"
1620                 if [ $i -ne $OSTCOUNT ]; then
1621                         osts=$osts","
1622                 fi
1623         done
1624         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1625         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1626         echo "$getstripe"
1627
1628         # Strip getstripe output to a space separated list of OSTs
1629         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1630                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1631         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1632                 error "stripes not on specified OSTs"
1633
1634         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1635 }
1636 run_test 27ce "more stripes than OSTs with -o"
1637
1638 test_27cf() {
1639         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1640         local pid=0
1641
1642         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1643         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1644         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1645         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1646                 error "failed to set $osp_proc=0"
1647
1648         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1649         pid=$!
1650         sleep 1
1651         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1652         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1653                 error "failed to set $osp_proc=1"
1654         wait $pid
1655         [[ $pid -ne 0 ]] ||
1656                 error "should return error due to $osp_proc=0"
1657 }
1658 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1659
1660 test_27d() {
1661         test_mkdir $DIR/$tdir
1662         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1663                 error "setstripe failed"
1664         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1665         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1666 }
1667 run_test 27d "create file with default settings"
1668
1669 test_27e() {
1670         # LU-5839 adds check for existed layout before setting it
1671         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1672                 skip "Need MDS version at least 2.7.56"
1673
1674         test_mkdir $DIR/$tdir
1675         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1676         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1677         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1678 }
1679 run_test 27e "setstripe existing file (should return error)"
1680
1681 test_27f() {
1682         test_mkdir $DIR/$tdir
1683         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1684                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1685         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1686                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1687         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1688         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1689 }
1690 run_test 27f "setstripe with bad stripe size (should return error)"
1691
1692 test_27g() {
1693         test_mkdir $DIR/$tdir
1694         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1695         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1696                 error "$DIR/$tdir/$tfile has object"
1697 }
1698 run_test 27g "$LFS getstripe with no objects"
1699
1700 test_27ga() {
1701         test_mkdir $DIR/$tdir
1702         touch $DIR/$tdir/$tfile || error "touch failed"
1703         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1704         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1705         local rc=$?
1706         (( rc == 2 )) || error "getstripe did not return ENOENT"
1707 }
1708 run_test 27ga "$LFS getstripe with missing file (should return error)"
1709
1710 test_27i() {
1711         test_mkdir $DIR/$tdir
1712         touch $DIR/$tdir/$tfile || error "touch failed"
1713         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1714                 error "missing objects"
1715 }
1716 run_test 27i "$LFS getstripe with some objects"
1717
1718 test_27j() {
1719         test_mkdir $DIR/$tdir
1720         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1721                 error "setstripe failed" || true
1722 }
1723 run_test 27j "setstripe with bad stripe offset (should return error)"
1724
1725 test_27k() { # bug 2844
1726         test_mkdir $DIR/$tdir
1727         local file=$DIR/$tdir/$tfile
1728         local ll_max_blksize=$((4 * 1024 * 1024))
1729         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1730         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1731         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1732         dd if=/dev/zero of=$file bs=4k count=1
1733         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1734         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1735 }
1736 run_test 27k "limit i_blksize for broken user apps"
1737
1738 test_27l() {
1739         mcreate $DIR/$tfile || error "creating file"
1740         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1741                 error "setstripe should have failed" || true
1742 }
1743 run_test 27l "check setstripe permissions (should return error)"
1744
1745 test_27m() {
1746         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1747
1748         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1749                 skip_env "multiple clients -- skipping"
1750
1751         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1752                    head -n1)
1753         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1754                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1755         fi
1756         trap simple_cleanup_common EXIT
1757         test_mkdir $DIR/$tdir
1758         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1759         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1760                 error "dd should fill OST0"
1761         i=2
1762         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1763                 i=$((i + 1))
1764                 [ $i -gt 256 ] && break
1765         done
1766         i=$((i + 1))
1767         touch $DIR/$tdir/$tfile.$i
1768         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1769             awk '{print $1}'| grep -w "0") ] &&
1770                 error "OST0 was full but new created file still use it"
1771         i=$((i + 1))
1772         touch $DIR/$tdir/$tfile.$i
1773         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1774             awk '{print $1}'| grep -w "0") ] &&
1775                 error "OST0 was full but new created file still use it"
1776         simple_cleanup_common
1777 }
1778 run_test 27m "create file while OST0 was full"
1779
1780 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1781 # if the OST isn't full anymore.
1782 reset_enospc() {
1783         local OSTIDX=${1:-""}
1784
1785         local list=$(comma_list $(osts_nodes))
1786         [ "$OSTIDX" ] && list=$(facet_host ost$((OSTIDX + 1)))
1787
1788         do_nodes $list lctl set_param fail_loc=0
1789         sync    # initiate all OST_DESTROYs from MDS to OST
1790         sleep_maxage
1791 }
1792
1793 exhaust_precreations() {
1794         local OSTIDX=$1
1795         local FAILLOC=$2
1796         local FAILIDX=${3:-$OSTIDX}
1797         local ofacet=ost$((OSTIDX + 1))
1798
1799         test_mkdir -p -c1 $DIR/$tdir
1800         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
1801         local mfacet=mds$((mdtidx + 1))
1802         echo OSTIDX=$OSTIDX MDTIDX=$mdtidx
1803
1804         local OST=$(ostname_from_index $OSTIDX)
1805
1806         # on the mdt's osc
1807         local mdtosc_proc1=$(get_mdtosc_proc_path $mfacet $OST)
1808         local last_id=$(do_facet $mfacet lctl get_param -n \
1809                         osp.$mdtosc_proc1.prealloc_last_id)
1810         local next_id=$(do_facet $mfacet lctl get_param -n \
1811                         osp.$mdtosc_proc1.prealloc_next_id)
1812
1813         local mdtosc_proc2=$(get_mdtosc_proc_path $mfacet)
1814         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1815
1816         test_mkdir -p $DIR/$tdir/${OST}
1817         $LFS setstripe -i $OSTIDX -c 1 $DIR/$tdir/${OST}
1818 #define OBD_FAIL_OST_ENOSPC              0x215
1819         do_facet $ofacet lctl set_param fail_val=$FAILIDX fail_loc=0x215
1820         echo "Creating to objid $last_id on ost $OST..."
1821         createmany -o $DIR/$tdir/${OST}/f $next_id $((last_id - next_id + 2))
1822         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1823         do_facet $ofacet lctl set_param fail_loc=$FAILLOC
1824         sleep_maxage
1825 }
1826
1827 exhaust_all_precreations() {
1828         local i
1829         for (( i=0; i < OSTCOUNT; i++ )) ; do
1830                 exhaust_precreations $i $1 -1
1831         done
1832 }
1833
1834 test_27n() {
1835         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1836         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1837         remote_mds_nodsh && skip "remote MDS with nodsh"
1838         remote_ost_nodsh && skip "remote OST with nodsh"
1839
1840         reset_enospc
1841         rm -f $DIR/$tdir/$tfile
1842         exhaust_precreations 0 0x80000215
1843         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1844         touch $DIR/$tdir/$tfile || error "touch failed"
1845         $LFS getstripe $DIR/$tdir/$tfile
1846         reset_enospc
1847 }
1848 run_test 27n "create file with some full OSTs"
1849
1850 test_27o() {
1851         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1852         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1853         remote_mds_nodsh && skip "remote MDS with nodsh"
1854         remote_ost_nodsh && skip "remote OST with nodsh"
1855
1856         reset_enospc
1857         rm -f $DIR/$tdir/$tfile
1858         exhaust_all_precreations 0x215
1859
1860         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1861
1862         reset_enospc
1863         rm -rf $DIR/$tdir/*
1864 }
1865 run_test 27o "create file with all full OSTs (should error)"
1866
1867 test_27p() {
1868         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1869         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1870         remote_mds_nodsh && skip "remote MDS with nodsh"
1871         remote_ost_nodsh && skip "remote OST with nodsh"
1872
1873         reset_enospc
1874         rm -f $DIR/$tdir/$tfile
1875         test_mkdir $DIR/$tdir
1876
1877         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1878         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1879         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1880
1881         exhaust_precreations 0 0x80000215
1882         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1883         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1884         $LFS getstripe $DIR/$tdir/$tfile
1885
1886         reset_enospc
1887 }
1888 run_test 27p "append to a truncated file with some full OSTs"
1889
1890 test_27q() {
1891         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1892         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1893         remote_mds_nodsh && skip "remote MDS with nodsh"
1894         remote_ost_nodsh && skip "remote OST with nodsh"
1895
1896         reset_enospc
1897         rm -f $DIR/$tdir/$tfile
1898
1899         test_mkdir $DIR/$tdir
1900         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1901         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1902                 error "truncate $DIR/$tdir/$tfile failed"
1903         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1904
1905         exhaust_all_precreations 0x215
1906
1907         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1908         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1909
1910         reset_enospc
1911 }
1912 run_test 27q "append to truncated file with all OSTs full (should error)"
1913
1914 test_27r() {
1915         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1916         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1917         remote_mds_nodsh && skip "remote MDS with nodsh"
1918         remote_ost_nodsh && skip "remote OST with nodsh"
1919
1920         reset_enospc
1921         rm -f $DIR/$tdir/$tfile
1922         exhaust_precreations 0 0x80000215
1923
1924         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1925
1926         reset_enospc
1927 }
1928 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
1929
1930 test_27s() { # bug 10725
1931         test_mkdir $DIR/$tdir
1932         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
1933         local stripe_count=0
1934         [ $OSTCOUNT -eq 1 ] || stripe_count=2
1935         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
1936                 error "stripe width >= 2^32 succeeded" || true
1937
1938 }
1939 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
1940
1941 test_27t() { # bug 10864
1942         WDIR=$(pwd)
1943         WLFS=$(which lfs)
1944         cd $DIR
1945         touch $tfile
1946         $WLFS getstripe $tfile
1947         cd $WDIR
1948 }
1949 run_test 27t "check that utils parse path correctly"
1950
1951 test_27u() { # bug 4900
1952         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1953         remote_mds_nodsh && skip "remote MDS with nodsh"
1954
1955         local index
1956         local list=$(comma_list $(mdts_nodes))
1957
1958 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
1959         do_nodes $list $LCTL set_param fail_loc=0x139
1960         test_mkdir -p $DIR/$tdir
1961         trap simple_cleanup_common EXIT
1962         createmany -o $DIR/$tdir/t- 1000
1963         do_nodes $list $LCTL set_param fail_loc=0
1964
1965         TLOG=$TMP/$tfile.getstripe
1966         $LFS getstripe $DIR/$tdir > $TLOG
1967         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
1968         unlinkmany $DIR/$tdir/t- 1000
1969         trap 0
1970         [[ $OBJS -gt 0 ]] &&
1971                 error "$OBJS objects created on OST-0. See $TLOG" ||
1972                 rm -f $TLOG
1973 }
1974 run_test 27u "skip object creation on OSC w/o objects"
1975
1976 test_27v() { # bug 4900
1977         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1978         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1979         remote_mds_nodsh && skip "remote MDS with nodsh"
1980         remote_ost_nodsh && skip "remote OST with nodsh"
1981
1982         exhaust_all_precreations 0x215
1983         reset_enospc
1984
1985         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
1986
1987         touch $DIR/$tdir/$tfile
1988         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
1989         # all except ost1
1990         for (( i=1; i < OSTCOUNT; i++ )); do
1991                 do_facet ost$i lctl set_param fail_loc=0x705
1992         done
1993         local START=`date +%s`
1994         createmany -o $DIR/$tdir/$tfile 32
1995
1996         local FINISH=`date +%s`
1997         local TIMEOUT=`lctl get_param -n timeout`
1998         local PROCESS=$((FINISH - START))
1999         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2000                error "$FINISH - $START >= $TIMEOUT / 2"
2001         sleep $((TIMEOUT / 2 - PROCESS))
2002         reset_enospc
2003 }
2004 run_test 27v "skip object creation on slow OST"
2005
2006 test_27w() { # bug 10997
2007         test_mkdir $DIR/$tdir
2008         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2009         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2010                 error "stripe size $size != 65536" || true
2011         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2012                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2013 }
2014 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2015
2016 test_27wa() {
2017         [[ $OSTCOUNT -lt 2 ]] &&
2018                 skip_env "skipping multiple stripe count/offset test"
2019
2020         test_mkdir $DIR/$tdir
2021         for i in $(seq 1 $OSTCOUNT); do
2022                 offset=$((i - 1))
2023                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2024                         error "setstripe -c $i -i $offset failed"
2025                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2026                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2027                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2028                 [ $index -ne $offset ] &&
2029                         error "stripe offset $index != $offset" || true
2030         done
2031 }
2032 run_test 27wa "check $LFS setstripe -c -i options"
2033
2034 test_27x() {
2035         remote_ost_nodsh && skip "remote OST with nodsh"
2036         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2037         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2038
2039         OFFSET=$(($OSTCOUNT - 1))
2040         OSTIDX=0
2041         local OST=$(ostname_from_index $OSTIDX)
2042
2043         test_mkdir $DIR/$tdir
2044         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2045         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2046         sleep_maxage
2047         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2048         for i in $(seq 0 $OFFSET); do
2049                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2050                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2051                 error "OST0 was degraded but new created file still use it"
2052         done
2053         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2054 }
2055 run_test 27x "create files while OST0 is degraded"
2056
2057 test_27y() {
2058         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2059         remote_mds_nodsh && skip "remote MDS with nodsh"
2060         remote_ost_nodsh && skip "remote OST with nodsh"
2061         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2062
2063         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2064         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2065                 osp.$mdtosc.prealloc_last_id)
2066         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2067                 osp.$mdtosc.prealloc_next_id)
2068         local fcount=$((last_id - next_id))
2069         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2070         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2071
2072         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2073                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2074         local OST_DEACTIVE_IDX=-1
2075         local OSC
2076         local OSTIDX
2077         local OST
2078
2079         for OSC in $MDS_OSCS; do
2080                 OST=$(osc_to_ost $OSC)
2081                 OSTIDX=$(index_from_ostuuid $OST)
2082                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2083                         OST_DEACTIVE_IDX=$OSTIDX
2084                 fi
2085                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2086                         echo $OSC "is Deactivated:"
2087                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2088                 fi
2089         done
2090
2091         OSTIDX=$(index_from_ostuuid $OST)
2092         test_mkdir $DIR/$tdir
2093         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2094
2095         for OSC in $MDS_OSCS; do
2096                 OST=$(osc_to_ost $OSC)
2097                 OSTIDX=$(index_from_ostuuid $OST)
2098                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2099                         echo $OST "is degraded:"
2100                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2101                                                 obdfilter.$OST.degraded=1
2102                 fi
2103         done
2104
2105         sleep_maxage
2106         createmany -o $DIR/$tdir/$tfile $fcount
2107
2108         for OSC in $MDS_OSCS; do
2109                 OST=$(osc_to_ost $OSC)
2110                 OSTIDX=$(index_from_ostuuid $OST)
2111                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2112                         echo $OST "is recovered from degraded:"
2113                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2114                                                 obdfilter.$OST.degraded=0
2115                 else
2116                         do_facet $SINGLEMDS lctl --device %$OSC activate
2117                 fi
2118         done
2119
2120         # all osp devices get activated, hence -1 stripe count restored
2121         local stripe_count=0
2122
2123         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2124         # devices get activated.
2125         sleep_maxage
2126         $LFS setstripe -c -1 $DIR/$tfile
2127         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2128         rm -f $DIR/$tfile
2129         [ $stripe_count -ne $OSTCOUNT ] &&
2130                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2131         return 0
2132 }
2133 run_test 27y "create files while OST0 is degraded and the rest inactive"
2134
2135 check_seq_oid()
2136 {
2137         log "check file $1"
2138
2139         lmm_count=$($LFS getstripe -c $1)
2140         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2141         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2142
2143         local old_ifs="$IFS"
2144         IFS=$'[:]'
2145         fid=($($LFS path2fid $1))
2146         IFS="$old_ifs"
2147
2148         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2149         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2150
2151         # compare lmm_seq and lu_fid->f_seq
2152         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2153         # compare lmm_object_id and lu_fid->oid
2154         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2155
2156         # check the trusted.fid attribute of the OST objects of the file
2157         local have_obdidx=false
2158         local stripe_nr=0
2159         $LFS getstripe $1 | while read obdidx oid hex seq; do
2160                 # skip lines up to and including "obdidx"
2161                 [ -z "$obdidx" ] && break
2162                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2163                 $have_obdidx || continue
2164
2165                 local ost=$((obdidx + 1))
2166                 local dev=$(ostdevname $ost)
2167                 local oid_hex
2168
2169                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2170
2171                 seq=$(echo $seq | sed -e "s/^0x//g")
2172                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2173                         oid_hex=$(echo $oid)
2174                 else
2175                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2176                 fi
2177                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2178
2179                 local ff=""
2180                 #
2181                 # Don't unmount/remount the OSTs if we don't need to do that.
2182                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2183                 # update too, until that use mount/ll_decode_filter_fid/mount.
2184                 # Re-enable when debugfs will understand new filter_fid.
2185                 #
2186                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2187                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2188                                 $dev 2>/dev/null" | grep "parent=")
2189                 fi
2190                 if [ -z "$ff" ]; then
2191                         stop ost$ost
2192                         mount_fstype ost$ost
2193                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2194                                 $(facet_mntpt ost$ost)/$obj_file)
2195                         unmount_fstype ost$ost
2196                         start ost$ost $dev $OST_MOUNT_OPTS
2197                         clients_up
2198                 fi
2199
2200                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2201
2202                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2203
2204                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2205                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2206                 #
2207                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2208                 #       stripe_size=1048576 component_id=1 component_start=0 \
2209                 #       component_end=33554432
2210                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2211                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2212                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2213                 local ff_pstripe
2214                 if grep -q 'stripe=' <<<$ff; then
2215                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2216                 else
2217                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2218                         # into f_ver in this case.  See comment on ff_parent.
2219                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2220                 fi
2221
2222                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2223                 [ $ff_pseq = $lmm_seq ] ||
2224                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2225                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2226                 [ $ff_poid = $lmm_oid ] ||
2227                         error "FF parent OID $ff_poid != $lmm_oid"
2228                 (($ff_pstripe == $stripe_nr)) ||
2229                         error "FF stripe $ff_pstripe != $stripe_nr"
2230
2231                 stripe_nr=$((stripe_nr + 1))
2232                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2233                         continue
2234                 if grep -q 'stripe_count=' <<<$ff; then
2235                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2236                                             -e 's/ .*//' <<<$ff)
2237                         [ $lmm_count = $ff_scnt ] ||
2238                                 error "FF stripe count $lmm_count != $ff_scnt"
2239                 fi
2240         done
2241 }
2242
2243 test_27z() {
2244         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2245         remote_ost_nodsh && skip "remote OST with nodsh"
2246
2247         test_mkdir $DIR/$tdir
2248         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2249                 { error "setstripe -c -1 failed"; return 1; }
2250         # We need to send a write to every object to get parent FID info set.
2251         # This _should_ also work for setattr, but does not currently.
2252         # touch $DIR/$tdir/$tfile-1 ||
2253         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2254                 { error "dd $tfile-1 failed"; return 2; }
2255         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2256                 { error "setstripe -c -1 failed"; return 3; }
2257         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2258                 { error "dd $tfile-2 failed"; return 4; }
2259
2260         # make sure write RPCs have been sent to OSTs
2261         sync; sleep 5; sync
2262
2263         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2264         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2265 }
2266 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2267
2268 test_27A() { # b=19102
2269         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2270
2271         save_layout_restore_at_exit $MOUNT
2272         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2273         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2274                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2275         local default_size=$($LFS getstripe -S $MOUNT)
2276         local default_offset=$($LFS getstripe -i $MOUNT)
2277         local dsize=$(do_facet $SINGLEMDS \
2278                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2279         [ $default_size -eq $dsize ] ||
2280                 error "stripe size $default_size != $dsize"
2281         [ $default_offset -eq -1 ] ||
2282                 error "stripe offset $default_offset != -1"
2283 }
2284 run_test 27A "check filesystem-wide default LOV EA values"
2285
2286 test_27B() { # LU-2523
2287         test_mkdir $DIR/$tdir
2288         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2289         touch $DIR/$tdir/f0
2290         # open f1 with O_LOV_DELAY_CREATE
2291         # rename f0 onto f1
2292         # call setstripe ioctl on open file descriptor for f1
2293         # close
2294         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2295                 $DIR/$tdir/f0
2296
2297         rm -f $DIR/$tdir/f1
2298         # open f1 with O_LOV_DELAY_CREATE
2299         # unlink f1
2300         # call setstripe ioctl on open file descriptor for f1
2301         # close
2302         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2303
2304         # Allow multiop to fail in imitation of NFS's busted semantics.
2305         true
2306 }
2307 run_test 27B "call setstripe on open unlinked file/rename victim"
2308
2309 # 27C family tests full striping and overstriping
2310 test_27Ca() { #LU-2871
2311         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2312
2313         declare -a ost_idx
2314         local index
2315         local found
2316         local i
2317         local j
2318
2319         test_mkdir $DIR/$tdir
2320         cd $DIR/$tdir
2321         for i in $(seq 0 $((OSTCOUNT - 1))); do
2322                 # set stripe across all OSTs starting from OST$i
2323                 $LFS setstripe -i $i -c -1 $tfile$i
2324                 # get striping information
2325                 ost_idx=($($LFS getstripe $tfile$i |
2326                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2327                 echo ${ost_idx[@]}
2328
2329                 # check the layout
2330                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2331                         error "${#ost_idx[@]} != $OSTCOUNT"
2332
2333                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2334                         found=0
2335                         for j in $(echo ${ost_idx[@]}); do
2336                                 if [ $index -eq $j ]; then
2337                                         found=1
2338                                         break
2339                                 fi
2340                         done
2341                         [ $found = 1 ] ||
2342                                 error "Can not find $index in ${ost_idx[@]}"
2343                 done
2344         done
2345 }
2346 run_test 27Ca "check full striping across all OSTs"
2347
2348 test_27Cb() {
2349         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2350                 skip "server does not support overstriping"
2351         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2352                 skip_env "too many osts, skipping"
2353
2354         test_mkdir -p $DIR/$tdir
2355         local setcount=$(($OSTCOUNT * 2))
2356         [ $setcount -ge 160 ] || large_xattr_enabled ||
2357                 skip_env "ea_inode feature disabled"
2358
2359         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2360                 error "setstripe failed"
2361
2362         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2363         [ $count -eq $setcount ] ||
2364                 error "stripe count $count, should be $setcount"
2365
2366         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2367                 error "overstriped should be set in pattern"
2368
2369         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2370                 error "dd failed"
2371 }
2372 run_test 27Cb "more stripes than OSTs with -C"
2373
2374 test_27Cc() {
2375         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2376                 skip "server does not support overstriping"
2377         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2378
2379         test_mkdir -p $DIR/$tdir
2380         local setcount=$(($OSTCOUNT - 1))
2381
2382         [ $setcount -ge 160 ] || large_xattr_enabled ||
2383                 skip_env "ea_inode feature disabled"
2384
2385         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2386                 error "setstripe failed"
2387
2388         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2389         [ $count -eq $setcount ] ||
2390                 error "stripe count $count, should be $setcount"
2391
2392         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2393                 error "overstriped should not be set in pattern"
2394
2395         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2396                 error "dd failed"
2397 }
2398 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2399
2400 test_27Cd() {
2401         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2402                 skip "server does not support overstriping"
2403         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2404         large_xattr_enabled || skip_env "ea_inode feature disabled"
2405
2406         test_mkdir -p $DIR/$tdir
2407         local setcount=$LOV_MAX_STRIPE_COUNT
2408
2409         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2410                 error "setstripe failed"
2411
2412         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2413         [ $count -eq $setcount ] ||
2414                 error "stripe count $count, should be $setcount"
2415
2416         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2417                 error "overstriped should be set in pattern"
2418
2419         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2420                 error "dd failed"
2421
2422         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2423 }
2424 run_test 27Cd "test maximum stripe count"
2425
2426 test_27Ce() {
2427         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2428                 skip "server does not support overstriping"
2429         test_mkdir -p $DIR/$tdir
2430
2431         pool_add $TESTNAME || error "Pool creation failed"
2432         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2433
2434         local setcount=8
2435
2436         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2437                 error "setstripe failed"
2438
2439         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2440         [ $count -eq $setcount ] ||
2441                 error "stripe count $count, should be $setcount"
2442
2443         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2444                 error "overstriped should be set in pattern"
2445
2446         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2447                 error "dd failed"
2448
2449         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2450 }
2451 run_test 27Ce "test pool with overstriping"
2452
2453 test_27Cf() {
2454         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2455                 skip "server does not support overstriping"
2456         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2457                 skip_env "too many osts, skipping"
2458
2459         test_mkdir -p $DIR/$tdir
2460
2461         local setcount=$(($OSTCOUNT * 2))
2462         [ $setcount -ge 160 ] || large_xattr_enabled ||
2463                 skip_env "ea_inode feature disabled"
2464
2465         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2466                 error "setstripe failed"
2467
2468         echo 1 > $DIR/$tdir/$tfile
2469
2470         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2471         [ $count -eq $setcount ] ||
2472                 error "stripe count $count, should be $setcount"
2473
2474         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2475                 error "overstriped should be set in pattern"
2476
2477         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2478                 error "dd failed"
2479
2480         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2481 }
2482 run_test 27Cf "test default inheritance with overstriping"
2483
2484 test_27D() {
2485         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2486         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2487         remote_mds_nodsh && skip "remote MDS with nodsh"
2488
2489         local POOL=${POOL:-testpool}
2490         local first_ost=0
2491         local last_ost=$(($OSTCOUNT - 1))
2492         local ost_step=1
2493         local ost_list=$(seq $first_ost $ost_step $last_ost)
2494         local ost_range="$first_ost $last_ost $ost_step"
2495
2496         test_mkdir $DIR/$tdir
2497         pool_add $POOL || error "pool_add failed"
2498         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2499
2500         local skip27D
2501         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2502                 skip27D+="-s 29"
2503         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2504                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2505                         skip27D+=" -s 30,31"
2506         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2507           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2508                 skip27D+=" -s 32,33"
2509         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2510                 skip27D+=" -s 34"
2511         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2512                 error "llapi_layout_test failed"
2513
2514         destroy_test_pools || error "destroy test pools failed"
2515 }
2516 run_test 27D "validate llapi_layout API"
2517
2518 # Verify that default_easize is increased from its initial value after
2519 # accessing a widely striped file.
2520 test_27E() {
2521         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2522         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2523                 skip "client does not have LU-3338 fix"
2524
2525         # 72 bytes is the minimum space required to store striping
2526         # information for a file striped across one OST:
2527         # (sizeof(struct lov_user_md_v3) +
2528         #  sizeof(struct lov_user_ost_data_v1))
2529         local min_easize=72
2530         $LCTL set_param -n llite.*.default_easize $min_easize ||
2531                 error "lctl set_param failed"
2532         local easize=$($LCTL get_param -n llite.*.default_easize)
2533
2534         [ $easize -eq $min_easize ] ||
2535                 error "failed to set default_easize"
2536
2537         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2538                 error "setstripe failed"
2539         # In order to ensure stat() call actually talks to MDS we need to
2540         # do something drastic to this file to shake off all lock, e.g.
2541         # rename it (kills lookup lock forcing cache cleaning)
2542         mv $DIR/$tfile $DIR/${tfile}-1
2543         ls -l $DIR/${tfile}-1
2544         rm $DIR/${tfile}-1
2545
2546         easize=$($LCTL get_param -n llite.*.default_easize)
2547
2548         [ $easize -gt $min_easize ] ||
2549                 error "default_easize not updated"
2550 }
2551 run_test 27E "check that default extended attribute size properly increases"
2552
2553 test_27F() { # LU-5346/LU-7975
2554         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2555         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2556         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2557                 skip "Need MDS version at least 2.8.51"
2558         remote_ost_nodsh && skip "remote OST with nodsh"
2559
2560         test_mkdir $DIR/$tdir
2561         rm -f $DIR/$tdir/f0
2562         $LFS setstripe -c 2 $DIR/$tdir
2563
2564         # stop all OSTs to reproduce situation for LU-7975 ticket
2565         for num in $(seq $OSTCOUNT); do
2566                 stop ost$num
2567         done
2568
2569         # open/create f0 with O_LOV_DELAY_CREATE
2570         # truncate f0 to a non-0 size
2571         # close
2572         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2573
2574         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2575         # open/write it again to force delayed layout creation
2576         cat /etc/hosts > $DIR/$tdir/f0 &
2577         catpid=$!
2578
2579         # restart OSTs
2580         for num in $(seq $OSTCOUNT); do
2581                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2582                         error "ost$num failed to start"
2583         done
2584
2585         wait $catpid || error "cat failed"
2586
2587         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2588         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2589                 error "wrong stripecount"
2590
2591 }
2592 run_test 27F "Client resend delayed layout creation with non-zero size"
2593
2594 test_27G() { #LU-10629
2595         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2596                 skip "Need MDS version at least 2.11.51"
2597         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2598         remote_mds_nodsh && skip "remote MDS with nodsh"
2599         local POOL=${POOL:-testpool}
2600         local ostrange="0 0 1"
2601
2602         test_mkdir $DIR/$tdir
2603         pool_add $POOL || error "pool_add failed"
2604         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2605         $LFS setstripe -p $POOL $DIR/$tdir
2606
2607         local pool=$($LFS getstripe -p $DIR/$tdir)
2608
2609         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2610
2611         $LFS setstripe -d $DIR/$tdir
2612
2613         pool=$($LFS getstripe -p $DIR/$tdir)
2614
2615         rmdir $DIR/$tdir
2616
2617         [ -z "$pool" ] || error "'$pool' is not empty"
2618 }
2619 run_test 27G "Clear OST pool from stripe"
2620
2621 test_27H() {
2622         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2623                 skip "Need MDS version newer than 2.11.54"
2624         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2625         test_mkdir $DIR/$tdir
2626         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2627         touch $DIR/$tdir/$tfile
2628         $LFS getstripe -c $DIR/$tdir/$tfile
2629         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2630                 error "two-stripe file doesn't have two stripes"
2631
2632         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2633         $LFS getstripe -y $DIR/$tdir/$tfile
2634         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2635              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2636                 error "expected l_ost_idx: [02]$ not matched"
2637
2638         # make sure ost list has been cleared
2639         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2640         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2641                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2642         touch $DIR/$tdir/f3
2643         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2644 }
2645 run_test 27H "Set specific OSTs stripe"
2646
2647 test_27I() {
2648         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2649         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2650         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2651                 skip "Need MDS version newer than 2.12.52"
2652         local pool=$TESTNAME
2653         local ostrange="1 1 1"
2654
2655         save_layout_restore_at_exit $MOUNT
2656         $LFS setstripe -c 2 -i 0 $MOUNT
2657         pool_add $pool || error "pool_add failed"
2658         pool_add_targets $pool $ostrange || "pool_add_targets failed"
2659         test_mkdir $DIR/$tdir
2660         $LFS setstripe -p $pool $DIR/$tdir
2661         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2662         $LFS getstripe $DIR/$tdir/$tfile
2663 }
2664 run_test 27I "check that root dir striping does not break parent dir one"
2665
2666 test_27J() {
2667         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2668                 skip "Need MDS version newer than 2.12.51"
2669
2670         test_mkdir $DIR/$tdir
2671         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2672         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2673
2674         # create foreign file (raw way)
2675         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2676                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2677
2678         # verify foreign file (raw way)
2679         parse_foreign_file -f $DIR/$tdir/$tfile |
2680                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2681                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2682         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2683                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2684         parse_foreign_file -f $DIR/$tdir/$tfile |
2685                 grep "lov_foreign_size: 73" ||
2686                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2687         parse_foreign_file -f $DIR/$tdir/$tfile |
2688                 grep "lov_foreign_type: 1" ||
2689                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2690         parse_foreign_file -f $DIR/$tdir/$tfile |
2691                 grep "lov_foreign_flags: 0x0000DA08" ||
2692                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2693         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2694                 grep "lov_foreign_value: 0x" |
2695                 sed -e 's/lov_foreign_value: 0x//')
2696         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2697         [[ $lov = ${lov2// /} ]] ||
2698                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2699
2700         # create foreign file (lfs + API)
2701         $LFS setstripe --foreign=daos --flags 0xda08 \
2702                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2703                 error "$DIR/$tdir/${tfile}2: create failed"
2704
2705         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2706                 grep "lfm_magic:.*0x0BD70BD0" ||
2707                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2708         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2709         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2710                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2711         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*daos" ||
2712                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2713         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2714                 grep "lfm_flags:.*0x0000DA08" ||
2715                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2716         $LFS getstripe $DIR/$tdir/${tfile}2 |
2717                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2718                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2719
2720         # modify striping should fail
2721         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2722                 error "$DIR/$tdir/$tfile: setstripe should fail"
2723         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2724                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2725
2726         # R/W should fail
2727         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2728         cat $DIR/$tdir/${tfile}2 &&
2729                 error "$DIR/$tdir/${tfile}2: read should fail"
2730         cat /etc/passwd > $DIR/$tdir/$tfile &&
2731                 error "$DIR/$tdir/$tfile: write should fail"
2732         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2733                 error "$DIR/$tdir/${tfile}2: write should fail"
2734
2735         # chmod should work
2736         chmod 222 $DIR/$tdir/$tfile ||
2737                 error "$DIR/$tdir/$tfile: chmod failed"
2738         chmod 222 $DIR/$tdir/${tfile}2 ||
2739                 error "$DIR/$tdir/${tfile}2: chmod failed"
2740
2741         # chown should work
2742         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2743                 error "$DIR/$tdir/$tfile: chown failed"
2744         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2745                 error "$DIR/$tdir/${tfile}2: chown failed"
2746
2747         # rename should work
2748         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2749                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2750         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2751                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2752
2753         #remove foreign file
2754         rm $DIR/$tdir/${tfile}.new ||
2755                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2756         rm $DIR/$tdir/${tfile}2.new ||
2757                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2758 }
2759 run_test 27J "basic ops on file with foreign LOV"
2760
2761 test_27K() {
2762         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2763                 skip "Need MDS version newer than 2.12.49"
2764
2765         test_mkdir $DIR/$tdir
2766         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2767         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2768
2769         # create foreign dir (raw way)
2770         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2771                 error "create_foreign_dir FAILED"
2772
2773         # verify foreign dir (raw way)
2774         parse_foreign_dir -d $DIR/$tdir/$tdir |
2775                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2776                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2777         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2778                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2779         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2780                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2781         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_flags: 0$" ||
2782                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2783         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2784                 grep "lmv_foreign_value: 0x" |
2785                 sed 's/lmv_foreign_value: 0x//')
2786         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2787                 sed 's/ //g')
2788         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2789
2790         # create foreign dir (lfs + API)
2791         $LFS mkdir --foreign=daos --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2792                 $DIR/$tdir/${tdir}2 ||
2793                 error "$DIR/$tdir/${tdir}2: create failed"
2794
2795         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2796                 grep "lfm_magic:.*0x0CD50CD0" ||
2797                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2798         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2799         # - sizeof(lfm_type) - sizeof(lfm_flags)
2800         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2801                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2802         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*daos" ||
2803                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2804         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2805                 grep "lfm_flags:.*0x0000DA05" ||
2806                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2807         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2808                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2809                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2810
2811         # file create in dir should fail
2812         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
2813         touch $DIR/$tdir/${tdir}2/$tfile &&
2814                 "$DIR/${tdir}2: file create should fail"
2815
2816         # chmod should work
2817         chmod 777 $DIR/$tdir/$tdir ||
2818                 error "$DIR/$tdir: chmod failed"
2819         chmod 777 $DIR/$tdir/${tdir}2 ||
2820                 error "$DIR/${tdir}2: chmod failed"
2821
2822         # chown should work
2823         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2824                 error "$DIR/$tdir: chown failed"
2825         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2826                 error "$DIR/${tdir}2: chown failed"
2827
2828         # rename should work
2829         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2830                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2831         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2832                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2833
2834         #remove foreign dir
2835         rmdir $DIR/$tdir/${tdir}.new ||
2836                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2837         rmdir $DIR/$tdir/${tdir}2.new ||
2838                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2839 }
2840 run_test 27K "basic ops on dir with foreign LMV"
2841
2842 test_27L() {
2843         remote_mds_nodsh && skip "remote MDS with nodsh"
2844
2845         local POOL=${POOL:-$TESTNAME}
2846
2847         pool_add $POOL || error "pool_add failed"
2848
2849         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2850                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2851                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2852 }
2853 run_test 27L "lfs pool_list gives correct pool name"
2854
2855 test_27M() {
2856         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2857                 skip "Need MDS version >= than 2.12.57"
2858         remote_mds_nodsh && skip "remote MDS with nodsh"
2859         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2860
2861         test_mkdir $DIR/$tdir
2862
2863         # Set default striping on directory
2864         $LFS setstripe -C 4 $DIR/$tdir
2865
2866         echo 1 > $DIR/$tdir/${tfile}.1
2867         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2868         local setcount=4
2869         [ $count -eq $setcount ] ||
2870                 error "(1) stripe count $count, should be $setcount"
2871
2872         # Capture existing append_stripe_count setting for restore
2873         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2874         local mdts=$(comma_list $(mdts_nodes))
2875         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$orig_count" EXIT
2876
2877         local appendcount=$orig_count
2878         echo 1 >> $DIR/$tdir/${tfile}.2_append
2879         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
2880         [ $count -eq $appendcount ] ||
2881                 error "(2)stripe count $count, should be $appendcount for append"
2882
2883         # Disable O_APPEND striping, verify it works
2884         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
2885
2886         # Should now get the default striping, which is 4
2887         setcount=4
2888         echo 1 >> $DIR/$tdir/${tfile}.3_append
2889         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
2890         [ $count -eq $setcount ] ||
2891                 error "(3) stripe count $count, should be $setcount"
2892
2893         # Try changing the stripe count for append files
2894         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
2895
2896         # Append striping is now 2 (directory default is still 4)
2897         appendcount=2
2898         echo 1 >> $DIR/$tdir/${tfile}.4_append
2899         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
2900         [ $count -eq $appendcount ] ||
2901                 error "(4) stripe count $count, should be $appendcount for append"
2902
2903         # Test append stripe count of -1
2904         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
2905         appendcount=$OSTCOUNT
2906         echo 1 >> $DIR/$tdir/${tfile}.5
2907         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
2908         [ $count -eq $appendcount ] ||
2909                 error "(5) stripe count $count, should be $appendcount for append"
2910
2911         # Set append striping back to default of 1
2912         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
2913
2914         # Try a new default striping, PFL + DOM
2915         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
2916
2917         # Create normal DOM file, DOM returns stripe count == 0
2918         setcount=0
2919         touch $DIR/$tdir/${tfile}.6
2920         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
2921         [ $count -eq $setcount ] ||
2922                 error "(6) stripe count $count, should be $setcount"
2923
2924         # Show
2925         appendcount=1
2926         echo 1 >> $DIR/$tdir/${tfile}.7_append
2927         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
2928         [ $count -eq $appendcount ] ||
2929                 error "(7) stripe count $count, should be $appendcount for append"
2930
2931         # Clean up DOM layout
2932         $LFS setstripe -d $DIR/$tdir
2933
2934         # Now test that append striping works when layout is from root
2935         $LFS setstripe -c 2 $MOUNT
2936         # Make a special directory for this
2937         mkdir $DIR/${tdir}/${tdir}.2
2938         stack_trap "$LFS setstripe -d $MOUNT" EXIT
2939
2940         # Verify for normal file
2941         setcount=2
2942         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
2943         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
2944         [ $count -eq $setcount ] ||
2945                 error "(8) stripe count $count, should be $setcount"
2946
2947         appendcount=1
2948         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
2949         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
2950         [ $count -eq $appendcount ] ||
2951                 error "(9) stripe count $count, should be $appendcount for append"
2952
2953         # Now test O_APPEND striping with pools
2954         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
2955         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'" EXIT
2956
2957         # Create the pool
2958         pool_add $TESTNAME || error "pool creation failed"
2959         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
2960
2961         echo 1 >> $DIR/$tdir/${tfile}.10_append
2962
2963         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
2964         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
2965
2966         # Check that count is still correct
2967         appendcount=1
2968         echo 1 >> $DIR/$tdir/${tfile}.11_append
2969         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
2970         [ $count -eq $appendcount ] ||
2971                 error "(11) stripe count $count, should be $appendcount for append"
2972
2973         # Disable O_APPEND stripe count, verify pool works separately
2974         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
2975
2976         echo 1 >> $DIR/$tdir/${tfile}.12_append
2977
2978         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
2979         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
2980
2981         # Remove pool setting, verify it's not applied
2982         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
2983
2984         echo 1 >> $DIR/$tdir/${tfile}.13_append
2985
2986         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
2987         [ "$pool" = "" ] || error "(13) pool found: $pool"
2988 }
2989 run_test 27M "test O_APPEND striping"
2990
2991 test_27N() {
2992         combined_mgs_mds && skip "needs separate MGS/MDT"
2993
2994         pool_add $TESTNAME || error "pool_add failed"
2995         do_facet mgs "$LCTL pool_list $FSNAME" |
2996                 grep -Fx "${FSNAME}.${TESTNAME}" ||
2997                 error "lctl pool_list on MGS failed"
2998 }
2999 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3000
3001 # createtest also checks that device nodes are created and
3002 # then visible correctly (#2091)
3003 test_28() { # bug 2091
3004         test_mkdir $DIR/d28
3005         $CREATETEST $DIR/d28/ct || error "createtest failed"
3006 }
3007 run_test 28 "create/mknod/mkdir with bad file types ============"
3008
3009 test_29() {
3010         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3011
3012         sync; sleep 1; sync # flush out any dirty pages from previous tests
3013         cancel_lru_locks
3014         test_mkdir $DIR/d29
3015         touch $DIR/d29/foo
3016         log 'first d29'
3017         ls -l $DIR/d29
3018
3019         declare -i LOCKCOUNTORIG=0
3020         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3021                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3022         done
3023         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3024
3025         declare -i LOCKUNUSEDCOUNTORIG=0
3026         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3027                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3028         done
3029
3030         log 'second d29'
3031         ls -l $DIR/d29
3032         log 'done'
3033
3034         declare -i LOCKCOUNTCURRENT=0
3035         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3036                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3037         done
3038
3039         declare -i LOCKUNUSEDCOUNTCURRENT=0
3040         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3041                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3042         done
3043
3044         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3045                 $LCTL set_param -n ldlm.dump_namespaces ""
3046                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3047                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3048                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3049                 return 2
3050         fi
3051         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3052                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3053                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3054                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3055                 return 3
3056         fi
3057 }
3058 run_test 29 "IT_GETATTR regression  ============================"
3059
3060 test_30a() { # was test_30
3061         cp $(which ls) $DIR || cp /bin/ls $DIR
3062         $DIR/ls / || error "Can't execute binary from lustre"
3063         rm $DIR/ls
3064 }
3065 run_test 30a "execute binary from Lustre (execve) =============="
3066
3067 test_30b() {
3068         cp `which ls` $DIR || cp /bin/ls $DIR
3069         chmod go+rx $DIR/ls
3070         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3071         rm $DIR/ls
3072 }
3073 run_test 30b "execute binary from Lustre as non-root ==========="
3074
3075 test_30c() { # b=22376
3076         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3077
3078         cp `which ls` $DIR || cp /bin/ls $DIR
3079         chmod a-rw $DIR/ls
3080         cancel_lru_locks mdc
3081         cancel_lru_locks osc
3082         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3083         rm -f $DIR/ls
3084 }
3085 run_test 30c "execute binary from Lustre without read perms ===="
3086
3087 test_31a() {
3088         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3089         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3090 }
3091 run_test 31a "open-unlink file =================================="
3092
3093 test_31b() {
3094         touch $DIR/f31 || error "touch $DIR/f31 failed"
3095         ln $DIR/f31 $DIR/f31b || error "ln failed"
3096         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3097         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3098 }
3099 run_test 31b "unlink file with multiple links while open ======="
3100
3101 test_31c() {
3102         touch $DIR/f31 || error "touch $DIR/f31 failed"
3103         ln $DIR/f31 $DIR/f31c || error "ln failed"
3104         multiop_bg_pause $DIR/f31 O_uc ||
3105                 error "multiop_bg_pause for $DIR/f31 failed"
3106         MULTIPID=$!
3107         $MULTIOP $DIR/f31c Ouc
3108         kill -USR1 $MULTIPID
3109         wait $MULTIPID
3110 }
3111 run_test 31c "open-unlink file with multiple links ============="
3112
3113 test_31d() {
3114         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3115         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3116 }
3117 run_test 31d "remove of open directory ========================="
3118
3119 test_31e() { # bug 2904
3120         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3121 }
3122 run_test 31e "remove of open non-empty directory ==============="
3123
3124 test_31f() { # bug 4554
3125         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3126
3127         set -vx
3128         test_mkdir $DIR/d31f
3129         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3130         cp /etc/hosts $DIR/d31f
3131         ls -l $DIR/d31f
3132         $LFS getstripe $DIR/d31f/hosts
3133         multiop_bg_pause $DIR/d31f D_c || return 1
3134         MULTIPID=$!
3135
3136         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3137         test_mkdir $DIR/d31f
3138         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3139         cp /etc/hosts $DIR/d31f
3140         ls -l $DIR/d31f
3141         $LFS getstripe $DIR/d31f/hosts
3142         multiop_bg_pause $DIR/d31f D_c || return 1
3143         MULTIPID2=$!
3144
3145         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3146         wait $MULTIPID || error "first opendir $MULTIPID failed"
3147
3148         sleep 6
3149
3150         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3151         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3152         set +vx
3153 }
3154 run_test 31f "remove of open directory with open-unlink file ==="
3155
3156 test_31g() {
3157         echo "-- cross directory link --"
3158         test_mkdir -c1 $DIR/${tdir}ga
3159         test_mkdir -c1 $DIR/${tdir}gb
3160         touch $DIR/${tdir}ga/f
3161         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3162         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3163         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3164         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3165         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3166 }
3167 run_test 31g "cross directory link==============="
3168
3169 test_31h() {
3170         echo "-- cross directory link --"
3171         test_mkdir -c1 $DIR/${tdir}
3172         test_mkdir -c1 $DIR/${tdir}/dir
3173         touch $DIR/${tdir}/f
3174         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3175         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3176         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3177         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3178         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3179 }
3180 run_test 31h "cross directory link under child==============="
3181
3182 test_31i() {
3183         echo "-- cross directory link --"
3184         test_mkdir -c1 $DIR/$tdir
3185         test_mkdir -c1 $DIR/$tdir/dir
3186         touch $DIR/$tdir/dir/f
3187         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3188         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3189         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3190         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3191         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3192 }
3193 run_test 31i "cross directory link under parent==============="
3194
3195 test_31j() {
3196         test_mkdir -c1 -p $DIR/$tdir
3197         test_mkdir -c1 -p $DIR/$tdir/dir1
3198         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3199         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3200         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3201         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3202         return 0
3203 }
3204 run_test 31j "link for directory==============="
3205
3206 test_31k() {
3207         test_mkdir -c1 -p $DIR/$tdir
3208         touch $DIR/$tdir/s
3209         touch $DIR/$tdir/exist
3210         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3211         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3212         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3213         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3214         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3215         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3216         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3217         return 0
3218 }
3219 run_test 31k "link to file: the same, non-existing, dir==============="
3220
3221 test_31m() {
3222         mkdir $DIR/d31m
3223         touch $DIR/d31m/s
3224         mkdir $DIR/d31m2
3225         touch $DIR/d31m2/exist
3226         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3227         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3228         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3229         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3230         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3231         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3232         return 0
3233 }
3234 run_test 31m "link to file: the same, non-existing, dir==============="
3235
3236 test_31n() {
3237         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3238         nlink=$(stat --format=%h $DIR/$tfile)
3239         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3240         local fd=$(free_fd)
3241         local cmd="exec $fd<$DIR/$tfile"
3242         eval $cmd
3243         cmd="exec $fd<&-"
3244         trap "eval $cmd" EXIT
3245         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3246         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3247         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3248         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3249         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3250         eval $cmd
3251 }
3252 run_test 31n "check link count of unlinked file"
3253
3254 link_one() {
3255         local tempfile=$(mktemp $1_XXXXXX)
3256         mlink $tempfile $1 2> /dev/null &&
3257                 echo "$BASHPID: link $tempfile to $1 succeeded"
3258         munlink $tempfile
3259 }
3260
3261 test_31o() { # LU-2901
3262         test_mkdir $DIR/$tdir
3263         for LOOP in $(seq 100); do
3264                 rm -f $DIR/$tdir/$tfile*
3265                 for THREAD in $(seq 8); do
3266                         link_one $DIR/$tdir/$tfile.$LOOP &
3267                 done
3268                 wait
3269                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3270                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3271                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3272                         break || true
3273         done
3274 }
3275 run_test 31o "duplicate hard links with same filename"
3276
3277 test_31p() {
3278         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3279
3280         test_mkdir $DIR/$tdir
3281         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3282         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3283
3284         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3285                 error "open unlink test1 failed"
3286         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3287                 error "open unlink test2 failed"
3288
3289         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3290                 error "test1 still exists"
3291         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3292                 error "test2 still exists"
3293 }
3294 run_test 31p "remove of open striped directory"
3295
3296 cleanup_test32_mount() {
3297         local rc=0
3298         trap 0
3299         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3300         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3301         losetup -d $loopdev || true
3302         rm -rf $DIR/$tdir
3303         return $rc
3304 }
3305
3306 test_32a() {
3307         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3308
3309         echo "== more mountpoints and symlinks ================="
3310         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3311         trap cleanup_test32_mount EXIT
3312         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3313         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3314                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3315         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3316                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3317         cleanup_test32_mount
3318 }
3319 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3320
3321 test_32b() {
3322         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3323
3324         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3325         trap cleanup_test32_mount EXIT
3326         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3327         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3328                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3329         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3330                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3331         cleanup_test32_mount
3332 }
3333 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3334
3335 test_32c() {
3336         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3337
3338         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3339         trap cleanup_test32_mount EXIT
3340         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3341         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3342                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3343         test_mkdir -p $DIR/$tdir/d2/test_dir
3344         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3345                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3346         cleanup_test32_mount
3347 }
3348 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3349
3350 test_32d() {
3351         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3352
3353         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3354         trap cleanup_test32_mount EXIT
3355         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3356         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3357                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3358         test_mkdir -p $DIR/$tdir/d2/test_dir
3359         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3360                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3361         cleanup_test32_mount
3362 }
3363 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3364
3365 test_32e() {
3366         rm -fr $DIR/$tdir
3367         test_mkdir -p $DIR/$tdir/tmp
3368         local tmp_dir=$DIR/$tdir/tmp
3369         ln -s $DIR/$tdir $tmp_dir/symlink11
3370         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3371         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3372         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3373 }
3374 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3375
3376 test_32f() {
3377         rm -fr $DIR/$tdir
3378         test_mkdir -p $DIR/$tdir/tmp
3379         local tmp_dir=$DIR/$tdir/tmp
3380         ln -s $DIR/$tdir $tmp_dir/symlink11
3381         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3382         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3383         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3384 }
3385 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3386
3387 test_32g() {
3388         local tmp_dir=$DIR/$tdir/tmp
3389         test_mkdir -p $tmp_dir
3390         test_mkdir $DIR/${tdir}2
3391         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3392         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3393         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3394         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3395         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3396         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3397 }
3398 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3399
3400 test_32h() {
3401         rm -fr $DIR/$tdir $DIR/${tdir}2
3402         tmp_dir=$DIR/$tdir/tmp
3403         test_mkdir -p $tmp_dir
3404         test_mkdir $DIR/${tdir}2
3405         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3406         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3407         ls $tmp_dir/symlink12 || error "listing symlink12"
3408         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3409 }
3410 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3411
3412 test_32i() {
3413         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3414
3415         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3416         trap cleanup_test32_mount EXIT
3417         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3418         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3419                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3420         touch $DIR/$tdir/test_file
3421         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3422                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3423         cleanup_test32_mount
3424 }
3425 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3426
3427 test_32j() {
3428         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3429
3430         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3431         trap cleanup_test32_mount EXIT
3432         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3433         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3434                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3435         touch $DIR/$tdir/test_file
3436         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3437                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3438         cleanup_test32_mount
3439 }
3440 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3441
3442 test_32k() {
3443         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3444
3445         rm -fr $DIR/$tdir
3446         trap cleanup_test32_mount EXIT
3447         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3448         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3449                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3450         test_mkdir -p $DIR/$tdir/d2
3451         touch $DIR/$tdir/d2/test_file || error "touch failed"
3452         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3453                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3454         cleanup_test32_mount
3455 }
3456 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3457
3458 test_32l() {
3459         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3460
3461         rm -fr $DIR/$tdir
3462         trap cleanup_test32_mount EXIT
3463         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3464         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3465                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3466         test_mkdir -p $DIR/$tdir/d2
3467         touch $DIR/$tdir/d2/test_file || error "touch failed"
3468         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3469                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3470         cleanup_test32_mount
3471 }
3472 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3473
3474 test_32m() {
3475         rm -fr $DIR/d32m
3476         test_mkdir -p $DIR/d32m/tmp
3477         TMP_DIR=$DIR/d32m/tmp
3478         ln -s $DIR $TMP_DIR/symlink11
3479         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3480         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3481                 error "symlink11 not a link"
3482         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3483                 error "symlink01 not a link"
3484 }
3485 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3486
3487 test_32n() {
3488         rm -fr $DIR/d32n
3489         test_mkdir -p $DIR/d32n/tmp
3490         TMP_DIR=$DIR/d32n/tmp
3491         ln -s $DIR $TMP_DIR/symlink11
3492         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3493         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3494         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3495 }
3496 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3497
3498 test_32o() {
3499         touch $DIR/$tfile
3500         test_mkdir -p $DIR/d32o/tmp
3501         TMP_DIR=$DIR/d32o/tmp
3502         ln -s $DIR/$tfile $TMP_DIR/symlink12
3503         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3504         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3505                 error "symlink12 not a link"
3506         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3507         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3508                 error "$DIR/d32o/tmp/symlink12 not file type"
3509         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3510                 error "$DIR/d32o/symlink02 not file type"
3511 }
3512 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3513
3514 test_32p() {
3515         log 32p_1
3516         rm -fr $DIR/d32p
3517         log 32p_2
3518         rm -f $DIR/$tfile
3519         log 32p_3
3520         touch $DIR/$tfile
3521         log 32p_4
3522         test_mkdir -p $DIR/d32p/tmp
3523         log 32p_5
3524         TMP_DIR=$DIR/d32p/tmp
3525         log 32p_6
3526         ln -s $DIR/$tfile $TMP_DIR/symlink12
3527         log 32p_7
3528         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3529         log 32p_8
3530         cat $DIR/d32p/tmp/symlink12 ||
3531                 error "Can't open $DIR/d32p/tmp/symlink12"
3532         log 32p_9
3533         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3534         log 32p_10
3535 }
3536 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3537
3538 test_32q() {
3539         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3540
3541         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3542         trap cleanup_test32_mount EXIT
3543         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3544         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3545         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3546                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3547         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3548         cleanup_test32_mount
3549 }
3550 run_test 32q "stat follows mountpoints in Lustre (should return error)"
3551
3552 test_32r() {
3553         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3554
3555         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3556         trap cleanup_test32_mount EXIT
3557         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3558         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3559         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3560                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3561         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
3562         cleanup_test32_mount
3563 }
3564 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
3565
3566 test_33aa() {
3567         rm -f $DIR/$tfile
3568         touch $DIR/$tfile
3569         chmod 444 $DIR/$tfile
3570         chown $RUNAS_ID $DIR/$tfile
3571         log 33_1
3572         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3573         log 33_2
3574 }
3575 run_test 33aa "write file with mode 444 (should return error)"
3576
3577 test_33a() {
3578         rm -fr $DIR/$tdir
3579         test_mkdir $DIR/$tdir
3580         chown $RUNAS_ID $DIR/$tdir
3581         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
3582                 error "$RUNAS create $tdir/$tfile failed"
3583         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
3584                 error "open RDWR" || true
3585 }
3586 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
3587
3588 test_33b() {
3589         rm -fr $DIR/$tdir
3590         test_mkdir $DIR/$tdir
3591         chown $RUNAS_ID $DIR/$tdir
3592         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
3593 }
3594 run_test 33b "test open file with malformed flags (No panic)"
3595
3596 test_33c() {
3597         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3598         remote_ost_nodsh && skip "remote OST with nodsh"
3599
3600         local ostnum
3601         local ostname
3602         local write_bytes
3603         local all_zeros
3604
3605         all_zeros=:
3606         rm -fr $DIR/$tdir
3607         test_mkdir $DIR/$tdir
3608         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
3609
3610         sync
3611         for ostnum in $(seq $OSTCOUNT); do
3612                 # test-framework's OST numbering is one-based, while Lustre's
3613                 # is zero-based
3614                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3615                 # Parsing llobdstat's output sucks; we could grep the /proc
3616                 # path, but that's likely to not be as portable as using the
3617                 # llobdstat utility.  So we parse lctl output instead.
3618                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3619                         obdfilter/$ostname/stats |
3620                         awk '/^write_bytes/ {print $7}' )
3621                 echo "baseline_write_bytes@$OSTnum/$ostname=$write_bytes"
3622                 if (( ${write_bytes:-0} > 0 ))
3623                 then
3624                         all_zeros=false
3625                         break;
3626                 fi
3627         done
3628
3629         $all_zeros || return 0
3630
3631         # Write four bytes
3632         echo foo > $DIR/$tdir/bar
3633         # Really write them
3634         sync
3635
3636         # Total up write_bytes after writing.  We'd better find non-zeros.
3637         for ostnum in $(seq $OSTCOUNT); do
3638                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3639                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3640                         obdfilter/$ostname/stats |
3641                         awk '/^write_bytes/ {print $7}' )
3642                 echo "write_bytes@$OSTnum/$ostname=$write_bytes"
3643                 if (( ${write_bytes:-0} > 0 ))
3644                 then
3645                         all_zeros=false
3646                         break;
3647                 fi
3648         done
3649
3650         if $all_zeros
3651         then
3652                 for ostnum in $(seq $OSTCOUNT); do
3653                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3654                         echo "Check that write_bytes is present in obdfilter/*/stats:"
3655                         do_facet ost$ostnum lctl get_param -n \
3656                                 obdfilter/$ostname/stats
3657                 done
3658                 error "OST not keeping write_bytes stats (b22312)"
3659         fi
3660 }
3661 run_test 33c "test llobdstat and write_bytes"
3662
3663 test_33d() {
3664         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
3665         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3666
3667         local MDTIDX=1
3668         local remote_dir=$DIR/$tdir/remote_dir
3669
3670         test_mkdir $DIR/$tdir
3671         $LFS mkdir -i $MDTIDX $remote_dir ||
3672                 error "create remote directory failed"
3673
3674         touch $remote_dir/$tfile
3675         chmod 444 $remote_dir/$tfile
3676         chown $RUNAS_ID $remote_dir/$tfile
3677
3678         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3679
3680         chown $RUNAS_ID $remote_dir
3681         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
3682                                         error "create" || true
3683         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
3684                                     error "open RDWR" || true
3685         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
3686 }
3687 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
3688
3689 test_33e() {
3690         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3691
3692         mkdir $DIR/$tdir
3693
3694         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3695         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3696         mkdir $DIR/$tdir/local_dir
3697
3698         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3699         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3700         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3701
3702         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3703                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
3704
3705         rmdir $DIR/$tdir/* || error "rmdir failed"
3706
3707         umask 777
3708         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3709         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3710         mkdir $DIR/$tdir/local_dir
3711
3712         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3713         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3714         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3715
3716         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3717                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
3718
3719         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
3720
3721         umask 000
3722         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3723         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3724         mkdir $DIR/$tdir/local_dir
3725
3726         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3727         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3728         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3729
3730         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3731                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
3732 }
3733 run_test 33e "mkdir and striped directory should have same mode"
3734
3735 cleanup_33f() {
3736         trap 0
3737         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
3738 }
3739
3740 test_33f() {
3741         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3742         remote_mds_nodsh && skip "remote MDS with nodsh"
3743
3744         mkdir $DIR/$tdir
3745         chmod go+rwx $DIR/$tdir
3746         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
3747         trap cleanup_33f EXIT
3748
3749         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
3750                 error "cannot create striped directory"
3751
3752         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
3753                 error "cannot create files in striped directory"
3754
3755         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
3756                 error "cannot remove files in striped directory"
3757
3758         $RUNAS rmdir $DIR/$tdir/striped_dir ||
3759                 error "cannot remove striped directory"
3760
3761         cleanup_33f
3762 }
3763 run_test 33f "nonroot user can create, access, and remove a striped directory"
3764
3765 test_33g() {
3766         mkdir -p $DIR/$tdir/dir2
3767
3768         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
3769         echo $err
3770         [[ $err =~ "exists" ]] || error "Not exists error"
3771 }
3772 run_test 33g "nonroot user create already existing root created file"
3773
3774 test_33h() {
3775         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3776         [ $MDS1_VERSION -lt $(version_code 2.13.50) ] &&
3777                 skip "Need MDS version at least 2.13.50"
3778
3779         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir ||
3780                 error "mkdir $tdir failed"
3781         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
3782
3783         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
3784         local index2
3785
3786         for fname in $DIR/$tdir/$tfile.bak \
3787                      $DIR/$tdir/$tfile.SAV \
3788                      $DIR/$tdir/$tfile.orig \
3789                      $DIR/$tdir/$tfile~; do
3790                 touch $fname  || error "touch $fname failed"
3791                 index2=$($LFS getstripe -m $fname)
3792                 [ $index -eq $index2 ] ||
3793                         error "$fname MDT index mismatch $index != $index2"
3794         done
3795
3796         local failed=0
3797         for i in {1..50}; do
3798                 for fname in $(mktemp -u $DIR/$tdir/.$tfile.XXXXXX) \
3799                              $(mktemp $DIR/$tdir/$tfile.XXXXXXXX); do
3800                         touch $fname  || error "touch $fname failed"
3801                         index2=$($LFS getstripe -m $fname)
3802                         if [[ $index != $index2 ]]; then
3803                                 failed=$((failed + 1))
3804                                 echo "$fname MDT index mismatch $index != $index2"
3805                         fi
3806                 done
3807         done
3808         echo "$failed MDT index mismatches"
3809         (( failed < 4 )) || error "MDT index mismatch $failed times"
3810
3811 }
3812 run_test 33h "temp file is located on the same MDT as target"
3813
3814 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
3815 test_34a() {
3816         rm -f $DIR/f34
3817         $MCREATE $DIR/f34 || error "mcreate failed"
3818         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3819                 error "getstripe failed"
3820         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
3821         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3822                 error "getstripe failed"
3823         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3824                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3825 }
3826 run_test 34a "truncate file that has not been opened ==========="
3827
3828 test_34b() {
3829         [ ! -f $DIR/f34 ] && test_34a
3830         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3831                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3832         $OPENFILE -f O_RDONLY $DIR/f34
3833         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3834                 error "getstripe failed"
3835         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3836                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3837 }
3838 run_test 34b "O_RDONLY opening file doesn't create objects ====="
3839
3840 test_34c() {
3841         [ ! -f $DIR/f34 ] && test_34a
3842         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3843                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3844         $OPENFILE -f O_RDWR $DIR/f34
3845         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
3846                 error "$LFS getstripe failed"
3847         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3848                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3849 }
3850 run_test 34c "O_RDWR opening file-with-size works =============="
3851
3852 test_34d() {
3853         [ ! -f $DIR/f34 ] && test_34a
3854         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
3855                 error "dd failed"
3856         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3857                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3858         rm $DIR/f34
3859 }
3860 run_test 34d "write to sparse file ============================="
3861
3862 test_34e() {
3863         rm -f $DIR/f34e
3864         $MCREATE $DIR/f34e || error "mcreate failed"
3865         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
3866         $CHECKSTAT -s 1000 $DIR/f34e ||
3867                 error "Size of $DIR/f34e not equal to 1000 bytes"
3868         $OPENFILE -f O_RDWR $DIR/f34e
3869         $CHECKSTAT -s 1000 $DIR/f34e ||
3870                 error "Size of $DIR/f34e not equal to 1000 bytes"
3871 }
3872 run_test 34e "create objects, some with size and some without =="
3873
3874 test_34f() { # bug 6242, 6243
3875         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3876
3877         SIZE34F=48000
3878         rm -f $DIR/f34f
3879         $MCREATE $DIR/f34f || error "mcreate failed"
3880         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
3881         dd if=$DIR/f34f of=$TMP/f34f
3882         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
3883         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
3884         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
3885         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
3886         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
3887 }
3888 run_test 34f "read from a file with no objects until EOF ======="
3889
3890 test_34g() {
3891         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3892
3893         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
3894                 error "dd failed"
3895         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
3896         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3897                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
3898         cancel_lru_locks osc
3899         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3900                 error "wrong size after lock cancel"
3901
3902         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
3903         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3904                 error "expanding truncate failed"
3905         cancel_lru_locks osc
3906         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3907                 error "wrong expanded size after lock cancel"
3908 }
3909 run_test 34g "truncate long file ==============================="
3910
3911 test_34h() {
3912         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3913
3914         local gid=10
3915         local sz=1000
3916
3917         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
3918         sync # Flush the cache so that multiop below does not block on cache
3919              # flush when getting the group lock
3920         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
3921         MULTIPID=$!
3922
3923         # Since just timed wait is not good enough, let's do a sync write
3924         # that way we are sure enough time for a roundtrip + processing
3925         # passed + 2 seconds of extra margin.
3926         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
3927         rm $DIR/${tfile}-1
3928         sleep 2
3929
3930         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
3931                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
3932                 kill -9 $MULTIPID
3933         fi
3934         wait $MULTIPID
3935         local nsz=`stat -c %s $DIR/$tfile`
3936         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
3937 }
3938 run_test 34h "ftruncate file under grouplock should not block"
3939
3940 test_35a() {
3941         cp /bin/sh $DIR/f35a
3942         chmod 444 $DIR/f35a
3943         chown $RUNAS_ID $DIR/f35a
3944         $RUNAS $DIR/f35a && error || true
3945         rm $DIR/f35a
3946 }
3947 run_test 35a "exec file with mode 444 (should return and not leak)"
3948
3949 test_36a() {
3950         rm -f $DIR/f36
3951         utime $DIR/f36 || error "utime failed for MDS"
3952 }
3953 run_test 36a "MDS utime check (mknod, utime)"
3954
3955 test_36b() {
3956         echo "" > $DIR/f36
3957         utime $DIR/f36 || error "utime failed for OST"
3958 }
3959 run_test 36b "OST utime check (open, utime)"
3960
3961 test_36c() {
3962         rm -f $DIR/d36/f36
3963         test_mkdir $DIR/d36
3964         chown $RUNAS_ID $DIR/d36
3965         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
3966 }
3967 run_test 36c "non-root MDS utime check (mknod, utime)"
3968
3969 test_36d() {
3970         [ ! -d $DIR/d36 ] && test_36c
3971         echo "" > $DIR/d36/f36
3972         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
3973 }
3974 run_test 36d "non-root OST utime check (open, utime)"
3975
3976 test_36e() {
3977         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
3978
3979         test_mkdir $DIR/$tdir
3980         touch $DIR/$tdir/$tfile
3981         $RUNAS utime $DIR/$tdir/$tfile &&
3982                 error "utime worked, expected failure" || true
3983 }
3984 run_test 36e "utime on non-owned file (should return error)"
3985
3986 subr_36fh() {
3987         local fl="$1"
3988         local LANG_SAVE=$LANG
3989         local LC_LANG_SAVE=$LC_LANG
3990         export LANG=C LC_LANG=C # for date language
3991
3992         DATESTR="Dec 20  2000"
3993         test_mkdir $DIR/$tdir
3994         lctl set_param fail_loc=$fl
3995         date; date +%s
3996         cp /etc/hosts $DIR/$tdir/$tfile
3997         sync & # write RPC generated with "current" inode timestamp, but delayed
3998         sleep 1
3999         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4000         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4001         cancel_lru_locks $OSC
4002         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4003         date; date +%s
4004         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4005                 echo "BEFORE: $LS_BEFORE" && \
4006                 echo "AFTER : $LS_AFTER" && \
4007                 echo "WANT  : $DATESTR" && \
4008                 error "$DIR/$tdir/$tfile timestamps changed" || true
4009
4010         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4011 }
4012
4013 test_36f() {
4014         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4015
4016         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4017         subr_36fh "0x80000214"
4018 }
4019 run_test 36f "utime on file racing with OST BRW write =========="
4020
4021 test_36g() {
4022         remote_ost_nodsh && skip "remote OST with nodsh"
4023         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4024         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4025                 skip "Need MDS version at least 2.12.51"
4026
4027         local fmd_max_age
4028         local fmd
4029         local facet="ost1"
4030         local tgt="obdfilter"
4031
4032         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4033
4034         test_mkdir $DIR/$tdir
4035         fmd_max_age=$(do_facet $facet \
4036                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4037                 head -n 1")
4038
4039         echo "FMD max age: ${fmd_max_age}s"
4040         touch $DIR/$tdir/$tfile
4041         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4042                 gawk '{cnt=cnt+$1}  END{print cnt}')
4043         echo "FMD before: $fmd"
4044         [[ $fmd == 0 ]] &&
4045                 error "FMD wasn't create by touch"
4046         sleep $((fmd_max_age + 12))
4047         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4048                 gawk '{cnt=cnt+$1}  END{print cnt}')
4049         echo "FMD after: $fmd"
4050         [[ $fmd == 0 ]] ||
4051                 error "FMD wasn't expired by ping"
4052 }
4053 run_test 36g "FMD cache expiry ====================="
4054
4055 test_36h() {
4056         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4057
4058         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4059         subr_36fh "0x80000227"
4060 }
4061 run_test 36h "utime on file racing with OST BRW write =========="
4062
4063 test_36i() {
4064         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4065
4066         test_mkdir $DIR/$tdir
4067         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4068
4069         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4070         local new_mtime=$((mtime + 200))
4071
4072         #change Modify time of striped dir
4073         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4074                         error "change mtime failed"
4075
4076         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4077
4078         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4079 }
4080 run_test 36i "change mtime on striped directory"
4081
4082 # test_37 - duplicate with tests 32q 32r
4083
4084 test_38() {
4085         local file=$DIR/$tfile
4086         touch $file
4087         openfile -f O_DIRECTORY $file
4088         local RC=$?
4089         local ENOTDIR=20
4090         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4091         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4092 }
4093 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4094
4095 test_39a() { # was test_39
4096         touch $DIR/$tfile
4097         touch $DIR/${tfile}2
4098 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4099 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4100 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4101         sleep 2
4102         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4103         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4104                 echo "mtime"
4105                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4106                 echo "atime"
4107                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4108                 echo "ctime"
4109                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4110                 error "O_TRUNC didn't change timestamps"
4111         fi
4112 }
4113 run_test 39a "mtime changed on create"
4114
4115 test_39b() {
4116         test_mkdir -c1 $DIR/$tdir
4117         cp -p /etc/passwd $DIR/$tdir/fopen
4118         cp -p /etc/passwd $DIR/$tdir/flink
4119         cp -p /etc/passwd $DIR/$tdir/funlink
4120         cp -p /etc/passwd $DIR/$tdir/frename
4121         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4122
4123         sleep 1
4124         echo "aaaaaa" >> $DIR/$tdir/fopen
4125         echo "aaaaaa" >> $DIR/$tdir/flink
4126         echo "aaaaaa" >> $DIR/$tdir/funlink
4127         echo "aaaaaa" >> $DIR/$tdir/frename
4128
4129         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4130         local link_new=`stat -c %Y $DIR/$tdir/flink`
4131         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4132         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4133
4134         cat $DIR/$tdir/fopen > /dev/null
4135         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4136         rm -f $DIR/$tdir/funlink2
4137         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4138
4139         for (( i=0; i < 2; i++ )) ; do
4140                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4141                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4142                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4143                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4144
4145                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4146                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4147                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4148                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4149
4150                 cancel_lru_locks $OSC
4151                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4152         done
4153 }
4154 run_test 39b "mtime change on open, link, unlink, rename  ======"
4155
4156 # this should be set to past
4157 TEST_39_MTIME=`date -d "1 year ago" +%s`
4158
4159 # bug 11063
4160 test_39c() {
4161         touch $DIR1/$tfile
4162         sleep 2
4163         local mtime0=`stat -c %Y $DIR1/$tfile`
4164
4165         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4166         local mtime1=`stat -c %Y $DIR1/$tfile`
4167         [ "$mtime1" = $TEST_39_MTIME ] || \
4168                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4169
4170         local d1=`date +%s`
4171         echo hello >> $DIR1/$tfile
4172         local d2=`date +%s`
4173         local mtime2=`stat -c %Y $DIR1/$tfile`
4174         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4175                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4176
4177         mv $DIR1/$tfile $DIR1/$tfile-1
4178
4179         for (( i=0; i < 2; i++ )) ; do
4180                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4181                 [ "$mtime2" = "$mtime3" ] || \
4182                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4183
4184                 cancel_lru_locks $OSC
4185                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4186         done
4187 }
4188 run_test 39c "mtime change on rename ==========================="
4189
4190 # bug 21114
4191 test_39d() {
4192         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4193
4194         touch $DIR1/$tfile
4195         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4196
4197         for (( i=0; i < 2; i++ )) ; do
4198                 local mtime=`stat -c %Y $DIR1/$tfile`
4199                 [ $mtime = $TEST_39_MTIME ] || \
4200                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4201
4202                 cancel_lru_locks $OSC
4203                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4204         done
4205 }
4206 run_test 39d "create, utime, stat =============================="
4207
4208 # bug 21114
4209 test_39e() {
4210         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4211
4212         touch $DIR1/$tfile
4213         local mtime1=`stat -c %Y $DIR1/$tfile`
4214
4215         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4216
4217         for (( i=0; i < 2; i++ )) ; do
4218                 local mtime2=`stat -c %Y $DIR1/$tfile`
4219                 [ $mtime2 = $TEST_39_MTIME ] || \
4220                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4221
4222                 cancel_lru_locks $OSC
4223                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4224         done
4225 }
4226 run_test 39e "create, stat, utime, stat ========================"
4227
4228 # bug 21114
4229 test_39f() {
4230         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4231
4232         touch $DIR1/$tfile
4233         mtime1=`stat -c %Y $DIR1/$tfile`
4234
4235         sleep 2
4236         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4237
4238         for (( i=0; i < 2; i++ )) ; do
4239                 local mtime2=`stat -c %Y $DIR1/$tfile`
4240                 [ $mtime2 = $TEST_39_MTIME ] || \
4241                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4242
4243                 cancel_lru_locks $OSC
4244                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4245         done
4246 }
4247 run_test 39f "create, stat, sleep, utime, stat ================="
4248
4249 # bug 11063
4250 test_39g() {
4251         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4252
4253         echo hello >> $DIR1/$tfile
4254         local mtime1=`stat -c %Y $DIR1/$tfile`
4255
4256         sleep 2
4257         chmod o+r $DIR1/$tfile
4258
4259         for (( i=0; i < 2; i++ )) ; do
4260                 local mtime2=`stat -c %Y $DIR1/$tfile`
4261                 [ "$mtime1" = "$mtime2" ] || \
4262                         error "lost mtime: $mtime2, should be $mtime1"
4263
4264                 cancel_lru_locks $OSC
4265                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4266         done
4267 }
4268 run_test 39g "write, chmod, stat ==============================="
4269
4270 # bug 11063
4271 test_39h() {
4272         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4273
4274         touch $DIR1/$tfile
4275         sleep 1
4276
4277         local d1=`date`
4278         echo hello >> $DIR1/$tfile
4279         local mtime1=`stat -c %Y $DIR1/$tfile`
4280
4281         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4282         local d2=`date`
4283         if [ "$d1" != "$d2" ]; then
4284                 echo "write and touch not within one second"
4285         else
4286                 for (( i=0; i < 2; i++ )) ; do
4287                         local mtime2=`stat -c %Y $DIR1/$tfile`
4288                         [ "$mtime2" = $TEST_39_MTIME ] || \
4289                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4290
4291                         cancel_lru_locks $OSC
4292                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4293                 done
4294         fi
4295 }
4296 run_test 39h "write, utime within one second, stat ============="
4297
4298 test_39i() {
4299         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4300
4301         touch $DIR1/$tfile
4302         sleep 1
4303
4304         echo hello >> $DIR1/$tfile
4305         local mtime1=`stat -c %Y $DIR1/$tfile`
4306
4307         mv $DIR1/$tfile $DIR1/$tfile-1
4308
4309         for (( i=0; i < 2; i++ )) ; do
4310                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4311
4312                 [ "$mtime1" = "$mtime2" ] || \
4313                         error "lost mtime: $mtime2, should be $mtime1"
4314
4315                 cancel_lru_locks $OSC
4316                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4317         done
4318 }
4319 run_test 39i "write, rename, stat =============================="
4320
4321 test_39j() {
4322         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4323
4324         start_full_debug_logging
4325         touch $DIR1/$tfile
4326         sleep 1
4327
4328         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4329         lctl set_param fail_loc=0x80000412
4330         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4331                 error "multiop failed"
4332         local multipid=$!
4333         local mtime1=`stat -c %Y $DIR1/$tfile`
4334
4335         mv $DIR1/$tfile $DIR1/$tfile-1
4336
4337         kill -USR1 $multipid
4338         wait $multipid || error "multiop close failed"
4339
4340         for (( i=0; i < 2; i++ )) ; do
4341                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4342                 [ "$mtime1" = "$mtime2" ] ||
4343                         error "mtime is lost on close: $mtime2, " \
4344                               "should be $mtime1"
4345
4346                 cancel_lru_locks
4347                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4348         done
4349         lctl set_param fail_loc=0
4350         stop_full_debug_logging
4351 }
4352 run_test 39j "write, rename, close, stat ======================="
4353
4354 test_39k() {
4355         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4356
4357         touch $DIR1/$tfile
4358         sleep 1
4359
4360         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4361         local multipid=$!
4362         local mtime1=`stat -c %Y $DIR1/$tfile`
4363
4364         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4365
4366         kill -USR1 $multipid
4367         wait $multipid || error "multiop close failed"
4368
4369         for (( i=0; i < 2; i++ )) ; do
4370                 local mtime2=`stat -c %Y $DIR1/$tfile`
4371
4372                 [ "$mtime2" = $TEST_39_MTIME ] || \
4373                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4374
4375                 cancel_lru_locks
4376                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4377         done
4378 }
4379 run_test 39k "write, utime, close, stat ========================"
4380
4381 # this should be set to future
4382 TEST_39_ATIME=`date -d "1 year" +%s`
4383
4384 test_39l() {
4385         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4386         remote_mds_nodsh && skip "remote MDS with nodsh"
4387
4388         local atime_diff=$(do_facet $SINGLEMDS \
4389                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4390         rm -rf $DIR/$tdir
4391         mkdir -p $DIR/$tdir
4392
4393         # test setting directory atime to future
4394         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4395         local atime=$(stat -c %X $DIR/$tdir)
4396         [ "$atime" = $TEST_39_ATIME ] ||
4397                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4398
4399         # test setting directory atime from future to now
4400         local now=$(date +%s)
4401         touch -a -d @$now $DIR/$tdir
4402
4403         atime=$(stat -c %X $DIR/$tdir)
4404         [ "$atime" -eq "$now"  ] ||
4405                 error "atime is not updated from future: $atime, $now"
4406
4407         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4408         sleep 3
4409
4410         # test setting directory atime when now > dir atime + atime_diff
4411         local d1=$(date +%s)
4412         ls $DIR/$tdir
4413         local d2=$(date +%s)
4414         cancel_lru_locks mdc
4415         atime=$(stat -c %X $DIR/$tdir)
4416         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4417                 error "atime is not updated  : $atime, should be $d2"
4418
4419         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4420         sleep 3
4421
4422         # test not setting directory atime when now < dir atime + atime_diff
4423         ls $DIR/$tdir
4424         cancel_lru_locks mdc
4425         atime=$(stat -c %X $DIR/$tdir)
4426         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4427                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4428
4429         do_facet $SINGLEMDS \
4430                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4431 }
4432 run_test 39l "directory atime update ==========================="
4433
4434 test_39m() {
4435         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4436
4437         touch $DIR1/$tfile
4438         sleep 2
4439         local far_past_mtime=$(date -d "May 29 1953" +%s)
4440         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4441
4442         touch -m -d @$far_past_mtime $DIR1/$tfile
4443         touch -a -d @$far_past_atime $DIR1/$tfile
4444
4445         for (( i=0; i < 2; i++ )) ; do
4446                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4447                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4448                         error "atime or mtime set incorrectly"
4449
4450                 cancel_lru_locks $OSC
4451                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4452         done
4453 }
4454 run_test 39m "test atime and mtime before 1970"
4455
4456 test_39n() { # LU-3832
4457         remote_mds_nodsh && skip "remote MDS with nodsh"
4458
4459         local atime_diff=$(do_facet $SINGLEMDS \
4460                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4461         local atime0
4462         local atime1
4463         local atime2
4464
4465         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4466
4467         rm -rf $DIR/$tfile
4468         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4469         atime0=$(stat -c %X $DIR/$tfile)
4470
4471         sleep 5
4472         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4473         atime1=$(stat -c %X $DIR/$tfile)
4474
4475         sleep 5
4476         cancel_lru_locks mdc
4477         cancel_lru_locks osc
4478         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4479         atime2=$(stat -c %X $DIR/$tfile)
4480
4481         do_facet $SINGLEMDS \
4482                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4483
4484         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4485         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4486 }
4487 run_test 39n "check that O_NOATIME is honored"
4488
4489 test_39o() {
4490         TESTDIR=$DIR/$tdir/$tfile
4491         [ -e $TESTDIR ] && rm -rf $TESTDIR
4492         mkdir -p $TESTDIR
4493         cd $TESTDIR
4494         links1=2
4495         ls
4496         mkdir a b
4497         ls
4498         links2=$(stat -c %h .)
4499         [ $(($links1 + 2)) != $links2 ] &&
4500                 error "wrong links count $(($links1 + 2)) != $links2"
4501         rmdir b
4502         links3=$(stat -c %h .)
4503         [ $(($links1 + 1)) != $links3 ] &&
4504                 error "wrong links count $links1 != $links3"
4505         return 0
4506 }
4507 run_test 39o "directory cached attributes updated after create"
4508
4509 test_39p() {
4510         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4511
4512         local MDTIDX=1
4513         TESTDIR=$DIR/$tdir/$tdir
4514         [ -e $TESTDIR ] && rm -rf $TESTDIR
4515         test_mkdir -p $TESTDIR
4516         cd $TESTDIR
4517         links1=2
4518         ls
4519         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4520         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4521         ls
4522         links2=$(stat -c %h .)
4523         [ $(($links1 + 2)) != $links2 ] &&
4524                 error "wrong links count $(($links1 + 2)) != $links2"
4525         rmdir remote_dir2
4526         links3=$(stat -c %h .)
4527         [ $(($links1 + 1)) != $links3 ] &&
4528                 error "wrong links count $links1 != $links3"
4529         return 0
4530 }
4531 run_test 39p "remote directory cached attributes updated after create ========"
4532
4533 test_39r() {
4534         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
4535                 skip "no atime update on old OST"
4536         if [ "$ost1_FSTYPE" != ldiskfs ]; then
4537                 skip_env "ldiskfs only test"
4538         fi
4539
4540         local saved_adiff
4541         saved_adiff=$(do_facet ost1 \
4542                 lctl get_param -n obdfilter.*OST0000.atime_diff)
4543         stack_trap "do_facet ost1 \
4544                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
4545
4546         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
4547
4548         $LFS setstripe -i 0 $DIR/$tfile
4549         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
4550                 error "can't write initial file"
4551         cancel_lru_locks osc
4552
4553         # exceed atime_diff and access file
4554         sleep 6
4555         dd if=$DIR/$tfile of=/dev/null || error "can't udpate atime"
4556
4557         local atime_cli=$(stat -c %X $DIR/$tfile)
4558         echo "client atime: $atime_cli"
4559         # allow atime update to be written to device
4560         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
4561         sleep 5
4562
4563         local ostdev=$(ostdevname 1)
4564         local fid=($(lfs getstripe -y $DIR/$tfile |
4565                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
4566         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
4567         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
4568
4569         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
4570         local atime_ost=$(do_facet ost1 "$cmd" |&
4571                           awk -F'[: ]' '/atime:/ { print $4 }')
4572         (( atime_cli == atime_ost )) ||
4573                 error "atime on client $atime_cli != ost $atime_ost"
4574 }
4575 run_test 39r "lazy atime update on OST"
4576
4577 test_39q() { # LU-8041
4578         local testdir=$DIR/$tdir
4579         mkdir -p $testdir
4580         multiop_bg_pause $testdir D_c || error "multiop failed"
4581         local multipid=$!
4582         cancel_lru_locks mdc
4583         kill -USR1 $multipid
4584         local atime=$(stat -c %X $testdir)
4585         [ "$atime" -ne 0 ] || error "atime is zero"
4586 }
4587 run_test 39q "close won't zero out atime"
4588
4589 test_40() {
4590         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
4591         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
4592                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
4593         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
4594                 error "$tfile is not 4096 bytes in size"
4595 }
4596 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
4597
4598 test_41() {
4599         # bug 1553
4600         small_write $DIR/f41 18
4601 }
4602 run_test 41 "test small file write + fstat ====================="
4603
4604 count_ost_writes() {
4605         lctl get_param -n ${OSC}.*.stats |
4606                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
4607                         END { printf("%0.0f", writes) }'
4608 }
4609
4610 # decent default
4611 WRITEBACK_SAVE=500
4612 DIRTY_RATIO_SAVE=40
4613 MAX_DIRTY_RATIO=50
4614 BG_DIRTY_RATIO_SAVE=10
4615 MAX_BG_DIRTY_RATIO=25
4616
4617 start_writeback() {
4618         trap 0
4619         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
4620         # dirty_ratio, dirty_background_ratio
4621         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4622                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
4623                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
4624                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
4625         else
4626                 # if file not here, we are a 2.4 kernel
4627                 kill -CONT `pidof kupdated`
4628         fi
4629 }
4630
4631 stop_writeback() {
4632         # setup the trap first, so someone cannot exit the test at the
4633         # exact wrong time and mess up a machine
4634         trap start_writeback EXIT
4635         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
4636         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4637                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
4638                 sysctl -w vm.dirty_writeback_centisecs=0
4639                 sysctl -w vm.dirty_writeback_centisecs=0
4640                 # save and increase /proc/sys/vm/dirty_ratio
4641                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
4642                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
4643                 # save and increase /proc/sys/vm/dirty_background_ratio
4644                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
4645                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
4646         else
4647                 # if file not here, we are a 2.4 kernel
4648                 kill -STOP `pidof kupdated`
4649         fi
4650 }
4651
4652 # ensure that all stripes have some grant before we test client-side cache
4653 setup_test42() {
4654         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
4655                 dd if=/dev/zero of=$i bs=4k count=1
4656                 rm $i
4657         done
4658 }
4659
4660 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
4661 # file truncation, and file removal.
4662 test_42a() {
4663         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4664
4665         setup_test42
4666         cancel_lru_locks $OSC
4667         stop_writeback
4668         sync; sleep 1; sync # just to be safe
4669         BEFOREWRITES=`count_ost_writes`
4670         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
4671         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
4672         AFTERWRITES=`count_ost_writes`
4673         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
4674                 error "$BEFOREWRITES < $AFTERWRITES"
4675         start_writeback
4676 }
4677 run_test 42a "ensure that we don't flush on close"
4678
4679 test_42b() {
4680         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4681
4682         setup_test42
4683         cancel_lru_locks $OSC
4684         stop_writeback
4685         sync
4686         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
4687         BEFOREWRITES=$(count_ost_writes)
4688         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
4689         AFTERWRITES=$(count_ost_writes)
4690         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4691                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
4692         fi
4693         BEFOREWRITES=$(count_ost_writes)
4694         sync || error "sync: $?"
4695         AFTERWRITES=$(count_ost_writes)
4696         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4697                 error "$BEFOREWRITES < $AFTERWRITES on sync"
4698         fi
4699         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
4700         start_writeback
4701         return 0
4702 }
4703 run_test 42b "test destroy of file with cached dirty data ======"
4704
4705 # if these tests just want to test the effect of truncation,
4706 # they have to be very careful.  consider:
4707 # - the first open gets a {0,EOF}PR lock
4708 # - the first write conflicts and gets a {0, count-1}PW
4709 # - the rest of the writes are under {count,EOF}PW
4710 # - the open for truncate tries to match a {0,EOF}PR
4711 #   for the filesize and cancels the PWs.
4712 # any number of fixes (don't get {0,EOF} on open, match
4713 # composite locks, do smarter file size management) fix
4714 # this, but for now we want these tests to verify that
4715 # the cancellation with truncate intent works, so we
4716 # start the file with a full-file pw lock to match against
4717 # until the truncate.
4718 trunc_test() {
4719         test=$1
4720         file=$DIR/$test
4721         offset=$2
4722         cancel_lru_locks $OSC
4723         stop_writeback
4724         # prime the file with 0,EOF PW to match
4725         touch $file
4726         $TRUNCATE $file 0
4727         sync; sync
4728         # now the real test..
4729         dd if=/dev/zero of=$file bs=1024 count=100
4730         BEFOREWRITES=`count_ost_writes`
4731         $TRUNCATE $file $offset
4732         cancel_lru_locks $OSC
4733         AFTERWRITES=`count_ost_writes`
4734         start_writeback
4735 }
4736
4737 test_42c() {
4738         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4739
4740         trunc_test 42c 1024
4741         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
4742                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
4743         rm $file
4744 }
4745 run_test 42c "test partial truncate of file with cached dirty data"
4746
4747 test_42d() {
4748         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4749
4750         trunc_test 42d 0
4751         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
4752                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
4753         rm $file
4754 }
4755 run_test 42d "test complete truncate of file with cached dirty data"
4756
4757 test_42e() { # bug22074
4758         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4759
4760         local TDIR=$DIR/${tdir}e
4761         local pages=16 # hardcoded 16 pages, don't change it.
4762         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
4763         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
4764         local max_dirty_mb
4765         local warmup_files
4766
4767         test_mkdir $DIR/${tdir}e
4768         $LFS setstripe -c 1 $TDIR
4769         createmany -o $TDIR/f $files
4770
4771         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
4772
4773         # we assume that with $OSTCOUNT files, at least one of them will
4774         # be allocated on OST0.
4775         warmup_files=$((OSTCOUNT * max_dirty_mb))
4776         createmany -o $TDIR/w $warmup_files
4777
4778         # write a large amount of data into one file and sync, to get good
4779         # avail_grant number from OST.
4780         for ((i=0; i<$warmup_files; i++)); do
4781                 idx=$($LFS getstripe -i $TDIR/w$i)
4782                 [ $idx -ne 0 ] && continue
4783                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
4784                 break
4785         done
4786         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
4787         sync
4788         $LCTL get_param $proc_osc0/cur_dirty_bytes
4789         $LCTL get_param $proc_osc0/cur_grant_bytes
4790
4791         # create as much dirty pages as we can while not to trigger the actual
4792         # RPCs directly. but depends on the env, VFS may trigger flush during this
4793         # period, hopefully we are good.
4794         for ((i=0; i<$warmup_files; i++)); do
4795                 idx=$($LFS getstripe -i $TDIR/w$i)
4796                 [ $idx -ne 0 ] && continue
4797                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
4798         done
4799         $LCTL get_param $proc_osc0/cur_dirty_bytes
4800         $LCTL get_param $proc_osc0/cur_grant_bytes
4801
4802         # perform the real test
4803         $LCTL set_param $proc_osc0/rpc_stats 0
4804         for ((;i<$files; i++)); do
4805                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
4806                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
4807         done
4808         sync
4809         $LCTL get_param $proc_osc0/rpc_stats
4810
4811         local percent=0
4812         local have_ppr=false
4813         $LCTL get_param $proc_osc0/rpc_stats |
4814                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
4815                         # skip lines until we are at the RPC histogram data
4816                         [ "$PPR" == "pages" ] && have_ppr=true && continue
4817                         $have_ppr || continue
4818
4819                         # we only want the percent stat for < 16 pages
4820                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
4821
4822                         percent=$((percent + WPCT))
4823                         if [[ $percent -gt 15 ]]; then
4824                                 error "less than 16-pages write RPCs" \
4825                                       "$percent% > 15%"
4826                                 break
4827                         fi
4828                 done
4829         rm -rf $TDIR
4830 }
4831 run_test 42e "verify sub-RPC writes are not done synchronously"
4832
4833 test_43A() { # was test_43
4834         test_mkdir $DIR/$tdir
4835         cp -p /bin/ls $DIR/$tdir/$tfile
4836         $MULTIOP $DIR/$tdir/$tfile Ow_c &
4837         pid=$!
4838         # give multiop a chance to open
4839         sleep 1
4840
4841         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
4842         kill -USR1 $pid
4843 }
4844 run_test 43A "execution of file opened for write should return -ETXTBSY"
4845
4846 test_43a() {
4847         test_mkdir $DIR/$tdir
4848         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4849         $DIR/$tdir/sleep 60 &
4850         SLEEP_PID=$!
4851         # Make sure exec of $tdir/sleep wins race with truncate
4852         sleep 1
4853         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
4854         kill $SLEEP_PID
4855 }
4856 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
4857
4858 test_43b() {
4859         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4860
4861         test_mkdir $DIR/$tdir
4862         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4863         $DIR/$tdir/sleep 60 &
4864         SLEEP_PID=$!
4865         # Make sure exec of $tdir/sleep wins race with truncate
4866         sleep 1
4867         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
4868         kill $SLEEP_PID
4869 }
4870 run_test 43b "truncate of file being executed should return -ETXTBSY"
4871
4872 test_43c() {
4873         local testdir="$DIR/$tdir"
4874         test_mkdir $testdir
4875         cp $SHELL $testdir/
4876         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
4877                 ( cd $testdir && md5sum -c )
4878 }
4879 run_test 43c "md5sum of copy into lustre"
4880
4881 test_44A() { # was test_44
4882         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4883
4884         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
4885         dd if=$DIR/f1 bs=4k count=1 > /dev/null
4886 }
4887 run_test 44A "zero length read from a sparse stripe"
4888
4889 test_44a() {
4890         local nstripe=$($LCTL lov_getconfig $DIR | grep default_stripe_count: |
4891                 awk '{ print $2 }')
4892         [ -z "$nstripe" ] && skip "can't get stripe info"
4893         [[ $nstripe -gt $OSTCOUNT ]] &&
4894                 skip "Wrong default_stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
4895
4896         local stride=$($LCTL lov_getconfig $DIR | grep default_stripe_size: |
4897                 awk '{ print $2 }')
4898         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
4899                 nstripe=$($LCTL lov_getconfig $DIR | grep obd_count: |
4900                         awk '{ print $2 }')
4901         fi
4902
4903         OFFSETS="0 $((stride/2)) $((stride-1))"
4904         for offset in $OFFSETS; do
4905                 for i in $(seq 0 $((nstripe-1))); do
4906                         local GLOBALOFFSETS=""
4907                         # size in Bytes
4908                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
4909                         local myfn=$DIR/d44a-$size
4910                         echo "--------writing $myfn at $size"
4911                         ll_sparseness_write $myfn $size ||
4912                                 error "ll_sparseness_write"
4913                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
4914                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4915                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4916
4917                         for j in $(seq 0 $((nstripe-1))); do
4918                                 # size in Bytes
4919                                 size=$((((j + $nstripe )*$stride + $offset)))
4920                                 ll_sparseness_write $myfn $size ||
4921                                         error "ll_sparseness_write"
4922                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
4923                         done
4924                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4925                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4926                         rm -f $myfn
4927                 done
4928         done
4929 }
4930 run_test 44a "test sparse pwrite ==============================="
4931
4932 dirty_osc_total() {
4933         tot=0
4934         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
4935                 tot=$(($tot + $d))
4936         done
4937         echo $tot
4938 }
4939 do_dirty_record() {
4940         before=`dirty_osc_total`
4941         echo executing "\"$*\""
4942         eval $*
4943         after=`dirty_osc_total`
4944         echo before $before, after $after
4945 }
4946 test_45() {
4947         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4948
4949         f="$DIR/f45"
4950         # Obtain grants from OST if it supports it
4951         echo blah > ${f}_grant
4952         stop_writeback
4953         sync
4954         do_dirty_record "echo blah > $f"
4955         [[ $before -eq $after ]] && error "write wasn't cached"
4956         do_dirty_record "> $f"
4957         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
4958         do_dirty_record "echo blah > $f"
4959         [[ $before -eq $after ]] && error "write wasn't cached"
4960         do_dirty_record "sync"
4961         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
4962         do_dirty_record "echo blah > $f"
4963         [[ $before -eq $after ]] && error "write wasn't cached"
4964         do_dirty_record "cancel_lru_locks osc"
4965         [[ $before -gt $after ]] ||
4966                 error "lock cancellation didn't lower dirty count"
4967         start_writeback
4968 }
4969 run_test 45 "osc io page accounting ============================"
4970
4971 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
4972 # test tickles a bug where re-dirtying a page was failing to be mapped to the
4973 # objects offset and an assert hit when an rpc was built with 1023's mapped
4974 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
4975 test_46() {
4976         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4977
4978         f="$DIR/f46"
4979         stop_writeback
4980         sync
4981         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
4982         sync
4983         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
4984         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
4985         sync
4986         start_writeback
4987 }
4988 run_test 46 "dirtying a previously written page ================"
4989
4990 # test_47 is removed "Device nodes check" is moved to test_28
4991
4992 test_48a() { # bug 2399
4993         [ "$mds1_FSTYPE" = "zfs" ] &&
4994         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
4995                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
4996
4997         test_mkdir $DIR/$tdir
4998         cd $DIR/$tdir
4999         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5000         test_mkdir $DIR/$tdir
5001         touch foo || error "'touch foo' failed after recreating cwd"
5002         test_mkdir bar
5003         touch .foo || error "'touch .foo' failed after recreating cwd"
5004         test_mkdir .bar
5005         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5006         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5007         cd . || error "'cd .' failed after recreating cwd"
5008         mkdir . && error "'mkdir .' worked after recreating cwd"
5009         rmdir . && error "'rmdir .' worked after recreating cwd"
5010         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5011         cd .. || error "'cd ..' failed after recreating cwd"
5012 }
5013 run_test 48a "Access renamed working dir (should return errors)="
5014
5015 test_48b() { # bug 2399
5016         rm -rf $DIR/$tdir
5017         test_mkdir $DIR/$tdir
5018         cd $DIR/$tdir
5019         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5020         touch foo && error "'touch foo' worked after removing cwd"
5021         mkdir foo && error "'mkdir foo' worked after removing cwd"
5022         touch .foo && error "'touch .foo' worked after removing cwd"
5023         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5024         ls . > /dev/null && error "'ls .' worked after removing cwd"
5025         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5026         mkdir . && error "'mkdir .' worked after removing cwd"
5027         rmdir . && error "'rmdir .' worked after removing cwd"
5028         ln -s . foo && error "'ln -s .' worked after removing cwd"
5029         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5030 }
5031 run_test 48b "Access removed working dir (should return errors)="
5032
5033 test_48c() { # bug 2350
5034         #lctl set_param debug=-1
5035         #set -vx
5036         rm -rf $DIR/$tdir
5037         test_mkdir -p $DIR/$tdir/dir
5038         cd $DIR/$tdir/dir
5039         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5040         $TRACE touch foo && error "touch foo worked after removing cwd"
5041         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5042         touch .foo && error "touch .foo worked after removing cwd"
5043         mkdir .foo && error "mkdir .foo worked after removing cwd"
5044         $TRACE ls . && error "'ls .' worked after removing cwd"
5045         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5046         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5047         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5048         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5049         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5050 }
5051 run_test 48c "Access removed working subdir (should return errors)"
5052
5053 test_48d() { # bug 2350
5054         #lctl set_param debug=-1
5055         #set -vx
5056         rm -rf $DIR/$tdir
5057         test_mkdir -p $DIR/$tdir/dir
5058         cd $DIR/$tdir/dir
5059         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5060         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5061         $TRACE touch foo && error "'touch foo' worked after removing parent"
5062         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5063         touch .foo && error "'touch .foo' worked after removing parent"
5064         mkdir .foo && error "mkdir .foo worked after removing parent"
5065         $TRACE ls . && error "'ls .' worked after removing parent"
5066         $TRACE ls .. && error "'ls ..' worked after removing parent"
5067         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5068         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5069         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5070         true
5071 }
5072 run_test 48d "Access removed parent subdir (should return errors)"
5073
5074 test_48e() { # bug 4134
5075         #lctl set_param debug=-1
5076         #set -vx
5077         rm -rf $DIR/$tdir
5078         test_mkdir -p $DIR/$tdir/dir
5079         cd $DIR/$tdir/dir
5080         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5081         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5082         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5083         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5084         # On a buggy kernel addition of "touch foo" after cd .. will
5085         # produce kernel oops in lookup_hash_it
5086         touch ../foo && error "'cd ..' worked after recreate parent"
5087         cd $DIR
5088         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5089 }
5090 run_test 48e "Access to recreated parent subdir (should return errors)"
5091
5092 test_49() { # LU-1030
5093         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5094         remote_ost_nodsh && skip "remote OST with nodsh"
5095
5096         # get ost1 size - $FSNAME-OST0000
5097         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5098                 awk '{ print $4 }')
5099         # write 800M at maximum
5100         [[ $ost1_size -lt 2 ]] && ost1_size=2
5101         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5102
5103         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5104         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5105         local dd_pid=$!
5106
5107         # change max_pages_per_rpc while writing the file
5108         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5109         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5110         # loop until dd process exits
5111         while ps ax -opid | grep -wq $dd_pid; do
5112                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5113                 sleep $((RANDOM % 5 + 1))
5114         done
5115         # restore original max_pages_per_rpc
5116         $LCTL set_param $osc1_mppc=$orig_mppc
5117         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5118 }
5119 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5120
5121 test_50() {
5122         # bug 1485
5123         test_mkdir $DIR/$tdir
5124         cd $DIR/$tdir
5125         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5126 }
5127 run_test 50 "special situations: /proc symlinks  ==============="
5128
5129 test_51a() {    # was test_51
5130         # bug 1516 - create an empty entry right after ".." then split dir
5131         test_mkdir -c1 $DIR/$tdir
5132         touch $DIR/$tdir/foo
5133         $MCREATE $DIR/$tdir/bar
5134         rm $DIR/$tdir/foo
5135         createmany -m $DIR/$tdir/longfile 201
5136         FNUM=202
5137         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5138                 $MCREATE $DIR/$tdir/longfile$FNUM
5139                 FNUM=$(($FNUM + 1))
5140                 echo -n "+"
5141         done
5142         echo
5143         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5144 }
5145 run_test 51a "special situations: split htree with empty entry =="
5146
5147 cleanup_print_lfs_df () {
5148         trap 0
5149         $LFS df
5150         $LFS df -i
5151 }
5152
5153 test_51b() {
5154         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5155
5156         local dir=$DIR/$tdir
5157         local nrdirs=$((65536 + 100))
5158
5159         # cleanup the directory
5160         rm -fr $dir
5161
5162         test_mkdir -c1 $dir
5163
5164         $LFS df
5165         $LFS df -i
5166         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5167         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5168         [[ $numfree -lt $nrdirs ]] &&
5169                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5170
5171         # need to check free space for the directories as well
5172         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5173         numfree=$(( blkfree / $(fs_inode_ksize) ))
5174         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5175
5176         trap cleanup_print_lfs_df EXIT
5177
5178         # create files
5179         createmany -d $dir/d $nrdirs || {
5180                 unlinkmany $dir/d $nrdirs
5181                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5182         }
5183
5184         # really created :
5185         nrdirs=$(ls -U $dir | wc -l)
5186
5187         # unlink all but 100 subdirectories, then check it still works
5188         local left=100
5189         local delete=$((nrdirs - left))
5190
5191         $LFS df
5192         $LFS df -i
5193
5194         # for ldiskfs the nlink count should be 1, but this is OSD specific
5195         # and so this is listed for informational purposes only
5196         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5197         unlinkmany -d $dir/d $delete ||
5198                 error "unlink of first $delete subdirs failed"
5199
5200         echo "nlink between: $(stat -c %h $dir)"
5201         local found=$(ls -U $dir | wc -l)
5202         [ $found -ne $left ] &&
5203                 error "can't find subdirs: found only $found, expected $left"
5204
5205         unlinkmany -d $dir/d $delete $left ||
5206                 error "unlink of second $left subdirs failed"
5207         # regardless of whether the backing filesystem tracks nlink accurately
5208         # or not, the nlink count shouldn't be more than "." and ".." here
5209         local after=$(stat -c %h $dir)
5210         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5211                 echo "nlink after: $after"
5212
5213         cleanup_print_lfs_df
5214 }
5215 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5216
5217 test_51d() {
5218         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5219         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5220
5221         test_mkdir $DIR/$tdir
5222         createmany -o $DIR/$tdir/t- 1000
5223         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5224         for N in $(seq 0 $((OSTCOUNT - 1))); do
5225                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
5226                         END { printf("%0.0f", objs) }' $TMP/$tfile)
5227                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5228                         '($1 == '$N') { objs += 1 } \
5229                         END { printf("%0.0f", objs) }')
5230                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
5231         done
5232         unlinkmany $DIR/$tdir/t- 1000
5233
5234         NLAST=0
5235         for N in $(seq 1 $((OSTCOUNT - 1))); do
5236                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
5237                         error "OST $N has less objects vs OST $NLAST" \
5238                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5239                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
5240                         error "OST $N has less objects vs OST $NLAST" \
5241                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5242
5243                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
5244                         error "OST $N has less #0 objects vs OST $NLAST" \
5245                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5246                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
5247                         error "OST $N has less #0 objects vs OST $NLAST" \
5248                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5249                 NLAST=$N
5250         done
5251         rm -f $TMP/$tfile
5252 }
5253 run_test 51d "check object distribution"
5254
5255 test_51e() {
5256         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5257                 skip_env "ldiskfs only test"
5258         fi
5259
5260         test_mkdir -c1 $DIR/$tdir
5261         test_mkdir -c1 $DIR/$tdir/d0
5262
5263         touch $DIR/$tdir/d0/foo
5264         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5265                 error "file exceed 65000 nlink limit!"
5266         unlinkmany $DIR/$tdir/d0/f- 65001
5267         return 0
5268 }
5269 run_test 51e "check file nlink limit"
5270
5271 test_51f() {
5272         test_mkdir $DIR/$tdir
5273
5274         local max=100000
5275         local ulimit_old=$(ulimit -n)
5276         local spare=20 # number of spare fd's for scripts/libraries, etc.
5277         local mdt=$($LFS getstripe -m $DIR/$tdir)
5278         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5279
5280         echo "MDT$mdt numfree=$numfree, max=$max"
5281         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5282         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5283                 while ! ulimit -n $((numfree + spare)); do
5284                         numfree=$((numfree * 3 / 4))
5285                 done
5286                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5287         else
5288                 echo "left ulimit at $ulimit_old"
5289         fi
5290
5291         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5292                 unlinkmany $DIR/$tdir/f $numfree
5293                 error "create+open $numfree files in $DIR/$tdir failed"
5294         }
5295         ulimit -n $ulimit_old
5296
5297         # if createmany exits at 120s there will be fewer than $numfree files
5298         unlinkmany $DIR/$tdir/f $numfree || true
5299 }
5300 run_test 51f "check many open files limit"
5301
5302 test_52a() {
5303         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5304         test_mkdir $DIR/$tdir
5305         touch $DIR/$tdir/foo
5306         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5307         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5308         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5309         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5310         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5311                                         error "link worked"
5312         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5313         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5314         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5315                                                      error "lsattr"
5316         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5317         cp -r $DIR/$tdir $TMP/
5318         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5319 }
5320 run_test 52a "append-only flag test (should return errors)"
5321
5322 test_52b() {
5323         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5324         test_mkdir $DIR/$tdir
5325         touch $DIR/$tdir/foo
5326         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5327         cat test > $DIR/$tdir/foo && error "cat test worked"
5328         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5329         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5330         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5331                                         error "link worked"
5332         echo foo >> $DIR/$tdir/foo && error "echo worked"
5333         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5334         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5335         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5336         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5337                                                         error "lsattr"
5338         chattr -i $DIR/$tdir/foo || error "chattr failed"
5339
5340         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5341 }
5342 run_test 52b "immutable flag test (should return errors) ======="
5343
5344 test_53() {
5345         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5346         remote_mds_nodsh && skip "remote MDS with nodsh"
5347         remote_ost_nodsh && skip "remote OST with nodsh"
5348
5349         local param
5350         local param_seq
5351         local ostname
5352         local mds_last
5353         local mds_last_seq
5354         local ost_last
5355         local ost_last_seq
5356         local ost_last_id
5357         local ostnum
5358         local node
5359         local found=false
5360         local support_last_seq=true
5361
5362         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5363                 support_last_seq=false
5364
5365         # only test MDT0000
5366         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5367         local value
5368         for value in $(do_facet $SINGLEMDS \
5369                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5370                 param=$(echo ${value[0]} | cut -d "=" -f1)
5371                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5372
5373                 if $support_last_seq; then
5374                         param_seq=$(echo $param |
5375                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5376                         mds_last_seq=$(do_facet $SINGLEMDS \
5377                                        $LCTL get_param -n $param_seq)
5378                 fi
5379                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5380
5381                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5382                 node=$(facet_active_host ost$((ostnum+1)))
5383                 param="obdfilter.$ostname.last_id"
5384                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5385                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5386                         ost_last_id=$ost_last
5387
5388                         if $support_last_seq; then
5389                                 ost_last_id=$(echo $ost_last |
5390                                               awk -F':' '{print $2}' |
5391                                               sed -e "s/^0x//g")
5392                                 ost_last_seq=$(echo $ost_last |
5393                                                awk -F':' '{print $1}')
5394                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5395                         fi
5396
5397                         if [[ $ost_last_id != $mds_last ]]; then
5398                                 error "$ost_last_id != $mds_last"
5399                         else
5400                                 found=true
5401                                 break
5402                         fi
5403                 done
5404         done
5405         $found || error "can not match last_seq/last_id for $mdtosc"
5406         return 0
5407 }
5408 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5409
5410 test_54a() {
5411         perl -MSocket -e ';' || skip "no Socket perl module installed"
5412
5413         $SOCKETSERVER $DIR/socket ||
5414                 error "$SOCKETSERVER $DIR/socket failed: $?"
5415         $SOCKETCLIENT $DIR/socket ||
5416                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5417         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5418 }
5419 run_test 54a "unix domain socket test =========================="
5420
5421 test_54b() {
5422         f="$DIR/f54b"
5423         mknod $f c 1 3
5424         chmod 0666 $f
5425         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5426 }
5427 run_test 54b "char device works in lustre ======================"
5428
5429 find_loop_dev() {
5430         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5431         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5432         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5433
5434         for i in $(seq 3 7); do
5435                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5436                 LOOPDEV=$LOOPBASE$i
5437                 LOOPNUM=$i
5438                 break
5439         done
5440 }
5441
5442 cleanup_54c() {
5443         local rc=0
5444         loopdev="$DIR/loop54c"
5445
5446         trap 0
5447         $UMOUNT $DIR/$tdir || rc=$?
5448         losetup -d $loopdev || true
5449         losetup -d $LOOPDEV || true
5450         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5451         return $rc
5452 }
5453
5454 test_54c() {
5455         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5456
5457         loopdev="$DIR/loop54c"
5458
5459         find_loop_dev
5460         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5461         trap cleanup_54c EXIT
5462         mknod $loopdev b 7 $LOOPNUM
5463         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5464         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5465         losetup $loopdev $DIR/$tfile ||
5466                 error "can't set up $loopdev for $DIR/$tfile"
5467         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5468         test_mkdir $DIR/$tdir
5469         mount -t ext2 $loopdev $DIR/$tdir ||
5470                 error "error mounting $loopdev on $DIR/$tdir"
5471         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5472                 error "dd write"
5473         df $DIR/$tdir
5474         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5475                 error "dd read"
5476         cleanup_54c
5477 }
5478 run_test 54c "block device works in lustre ====================="
5479
5480 test_54d() {
5481         f="$DIR/f54d"
5482         string="aaaaaa"
5483         mknod $f p
5484         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5485 }
5486 run_test 54d "fifo device works in lustre ======================"
5487
5488 test_54e() {
5489         f="$DIR/f54e"
5490         string="aaaaaa"
5491         cp -aL /dev/console $f
5492         echo $string > $f || error "echo $string to $f failed"
5493 }
5494 run_test 54e "console/tty device works in lustre ======================"
5495
5496 test_56a() {
5497         local numfiles=3
5498         local dir=$DIR/$tdir
5499
5500         rm -rf $dir
5501         test_mkdir -p $dir/dir
5502         for i in $(seq $numfiles); do
5503                 touch $dir/file$i
5504                 touch $dir/dir/file$i
5505         done
5506
5507         local numcomp=$($LFS getstripe --component-count $dir)
5508
5509         [[ $numcomp == 0 ]] && numcomp=1
5510
5511         # test lfs getstripe with --recursive
5512         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5513
5514         [[ $filenum -eq $((numfiles * 2)) ]] ||
5515                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5516         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5517         [[ $filenum -eq $numfiles ]] ||
5518                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5519         echo "$LFS getstripe showed obdidx or l_ost_idx"
5520
5521         # test lfs getstripe with file instead of dir
5522         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5523         [[ $filenum -eq 1 ]] ||
5524                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5525         echo "$LFS getstripe file1 passed"
5526
5527         #test lfs getstripe with --verbose
5528         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5529         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5530                 error "$LFS getstripe --verbose $dir: "\
5531                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5532         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5533                 error "$LFS getstripe $dir: showed lmm_magic"
5534
5535         #test lfs getstripe with -v prints lmm_fid
5536         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5537         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5538                 error "$LFS getstripe -v $dir: "\
5539                       "got $filenum want $((numfiles * numcomp)) lmm_fid"
5540         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5541                 error "$LFS getstripe $dir: showed lmm_fid by default"
5542         echo "$LFS getstripe --verbose passed"
5543
5544         #check for FID information
5545         local fid1=$($LFS getstripe --fid $dir/file1)
5546         local fid2=$($LFS getstripe --verbose $dir/file1 |
5547                      awk '/lmm_fid: / { print $2; exit; }')
5548         local fid3=$($LFS path2fid $dir/file1)
5549
5550         [ "$fid1" != "$fid2" ] &&
5551                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5552         [ "$fid1" != "$fid3" ] &&
5553                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5554         echo "$LFS getstripe --fid passed"
5555
5556         #test lfs getstripe with --obd
5557         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
5558                 error "$LFS getstripe --obd wrong_uuid: should return error"
5559
5560         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5561
5562         local ostidx=1
5563         local obduuid=$(ostuuid_from_index $ostidx)
5564         local found=$($LFS getstripe -r --obd $obduuid $dir |
5565                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
5566
5567         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
5568         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
5569                 ((filenum--))
5570         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
5571                 ((filenum--))
5572
5573         [[ $found -eq $filenum ]] ||
5574                 error "$LFS getstripe --obd: found $found expect $filenum"
5575         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
5576                 sed '/^[         ]*'${ostidx}'[  ]/d' |
5577                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
5578                 error "$LFS getstripe --obd: should not show file on other obd"
5579         echo "$LFS getstripe --obd passed"
5580 }
5581 run_test 56a "check $LFS getstripe"
5582
5583 test_56b() {
5584         local dir=$DIR/$tdir
5585         local numdirs=3
5586
5587         test_mkdir $dir
5588         for i in $(seq $numdirs); do
5589                 test_mkdir $dir/dir$i
5590         done
5591
5592         # test lfs getdirstripe default mode is non-recursion, which is
5593         # different from lfs getstripe
5594         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
5595
5596         [[ $dircnt -eq 1 ]] ||
5597                 error "$LFS getdirstripe: found $dircnt, not 1"
5598         dircnt=$($LFS getdirstripe --recursive $dir |
5599                 grep -c lmv_stripe_count)
5600         [[ $dircnt -eq $((numdirs + 1)) ]] ||
5601                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
5602 }
5603 run_test 56b "check $LFS getdirstripe"
5604
5605 test_56c() {
5606         remote_ost_nodsh && skip "remote OST with nodsh"
5607
5608         local ost_idx=0
5609         local ost_name=$(ostname_from_index $ost_idx)
5610         local old_status=$(ost_dev_status $ost_idx)
5611
5612         [[ -z "$old_status" ]] ||
5613                 skip_env "OST $ost_name is in $old_status status"
5614
5615         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
5616         [[ $OST1_VERSION -ge $(version_code 2.12.55) ]] && do_facet ost1 \
5617                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
5618         sleep_maxage
5619
5620         local new_status=$(ost_dev_status $ost_idx)
5621
5622         [[ "$new_status" =~ "D" ]] ||
5623                 error "$ost_name status is '$new_status', missing 'D'"
5624         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
5625                 [[ "$new_status" =~ "N" ]] ||
5626                         error "$ost_name status is '$new_status', missing 'N'"
5627         fi
5628
5629         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
5630         [[ $OST1_VERSION -ge $(version_code 2.12.55) ]] && do_facet ost1 \
5631                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
5632         sleep_maxage
5633
5634         new_status=$(ost_dev_status $ost_idx)
5635         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
5636                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
5637 }
5638 run_test 56c "check 'lfs df' showing device status"
5639
5640 NUMFILES=3
5641 NUMDIRS=3
5642 setup_56() {
5643         local local_tdir="$1"
5644         local local_numfiles="$2"
5645         local local_numdirs="$3"
5646         local dir_params="$4"
5647         local dir_stripe_params="$5"
5648
5649         if [ ! -d "$local_tdir" ] ; then
5650                 test_mkdir -p $dir_stripe_params $local_tdir
5651                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
5652                 for i in $(seq $local_numfiles) ; do
5653                         touch $local_tdir/file$i
5654                 done
5655                 for i in $(seq $local_numdirs) ; do
5656                         test_mkdir $dir_stripe_params $local_tdir/dir$i
5657                         for j in $(seq $local_numfiles) ; do
5658                                 touch $local_tdir/dir$i/file$j
5659                         done
5660                 done
5661         fi
5662 }
5663
5664 setup_56_special() {
5665         local local_tdir=$1
5666         local local_numfiles=$2
5667         local local_numdirs=$3
5668
5669         setup_56 $local_tdir $local_numfiles $local_numdirs
5670
5671         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
5672                 for i in $(seq $local_numfiles) ; do
5673                         mknod $local_tdir/loop${i}b b 7 $i
5674                         mknod $local_tdir/null${i}c c 1 3
5675                         ln -s $local_tdir/file1 $local_tdir/link${i}
5676                 done
5677                 for i in $(seq $local_numdirs) ; do
5678                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
5679                         mknod $local_tdir/dir$i/null${i}c c 1 3
5680                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
5681                 done
5682         fi
5683 }
5684
5685 test_56g() {
5686         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5687         local expected=$(($NUMDIRS + 2))
5688
5689         setup_56 $dir $NUMFILES $NUMDIRS
5690
5691         # test lfs find with -name
5692         for i in $(seq $NUMFILES) ; do
5693                 local nums=$($LFS find -name "*$i" $dir | wc -l)
5694
5695                 [ $nums -eq $expected ] ||
5696                         error "lfs find -name '*$i' $dir wrong: "\
5697                               "found $nums, expected $expected"
5698         done
5699 }
5700 run_test 56g "check lfs find -name"
5701
5702 test_56h() {
5703         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5704         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
5705
5706         setup_56 $dir $NUMFILES $NUMDIRS
5707
5708         # test lfs find with ! -name
5709         for i in $(seq $NUMFILES) ; do
5710                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
5711
5712                 [ $nums -eq $expected ] ||
5713                         error "lfs find ! -name '*$i' $dir wrong: "\
5714                               "found $nums, expected $expected"
5715         done
5716 }
5717 run_test 56h "check lfs find ! -name"
5718
5719 test_56i() {
5720         local dir=$DIR/$tdir
5721
5722         test_mkdir $dir
5723
5724         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
5725         local out=$($cmd)
5726
5727         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
5728 }
5729 run_test 56i "check 'lfs find -ost UUID' skips directories"
5730
5731 test_56j() {
5732         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5733
5734         setup_56_special $dir $NUMFILES $NUMDIRS
5735
5736         local expected=$((NUMDIRS + 1))
5737         local cmd="$LFS find -type d $dir"
5738         local nums=$($cmd | wc -l)
5739
5740         [ $nums -eq $expected ] ||
5741                 error "'$cmd' wrong: found $nums, expected $expected"
5742 }
5743 run_test 56j "check lfs find -type d"
5744
5745 test_56k() {
5746         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5747
5748         setup_56_special $dir $NUMFILES $NUMDIRS
5749
5750         local expected=$(((NUMDIRS + 1) * NUMFILES))
5751         local cmd="$LFS find -type f $dir"
5752         local nums=$($cmd | wc -l)
5753
5754         [ $nums -eq $expected ] ||
5755                 error "'$cmd' wrong: found $nums, expected $expected"
5756 }
5757 run_test 56k "check lfs find -type f"
5758
5759 test_56l() {
5760         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5761
5762         setup_56_special $dir $NUMFILES $NUMDIRS
5763
5764         local expected=$((NUMDIRS + NUMFILES))
5765         local cmd="$LFS find -type b $dir"
5766         local nums=$($cmd | wc -l)
5767
5768         [ $nums -eq $expected ] ||
5769                 error "'$cmd' wrong: found $nums, expected $expected"
5770 }
5771 run_test 56l "check lfs find -type b"
5772
5773 test_56m() {
5774         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5775
5776         setup_56_special $dir $NUMFILES $NUMDIRS
5777
5778         local expected=$((NUMDIRS + NUMFILES))
5779         local cmd="$LFS find -type c $dir"
5780         local nums=$($cmd | wc -l)
5781         [ $nums -eq $expected ] ||
5782                 error "'$cmd' wrong: found $nums, expected $expected"
5783 }
5784 run_test 56m "check lfs find -type c"
5785
5786 test_56n() {
5787         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5788         setup_56_special $dir $NUMFILES $NUMDIRS
5789
5790         local expected=$((NUMDIRS + NUMFILES))
5791         local cmd="$LFS find -type l $dir"
5792         local nums=$($cmd | wc -l)
5793
5794         [ $nums -eq $expected ] ||
5795                 error "'$cmd' wrong: found $nums, expected $expected"
5796 }
5797 run_test 56n "check lfs find -type l"
5798
5799 test_56o() {
5800         local dir=$DIR/$tdir
5801
5802         setup_56 $dir $NUMFILES $NUMDIRS
5803         utime $dir/file1 > /dev/null || error "utime (1)"
5804         utime $dir/file2 > /dev/null || error "utime (2)"
5805         utime $dir/dir1 > /dev/null || error "utime (3)"
5806         utime $dir/dir2 > /dev/null || error "utime (4)"
5807         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
5808         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
5809
5810         local expected=4
5811         local nums=$($LFS find -mtime +0 $dir | wc -l)
5812
5813         [ $nums -eq $expected ] ||
5814                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
5815
5816         expected=12
5817         cmd="$LFS find -mtime 0 $dir"
5818         nums=$($cmd | wc -l)
5819         [ $nums -eq $expected ] ||
5820                 error "'$cmd' wrong: found $nums, expected $expected"
5821 }
5822 run_test 56o "check lfs find -mtime for old files"
5823
5824 test_56ob() {
5825         local dir=$DIR/$tdir
5826         local expected=1
5827         local count=0
5828
5829         # just to make sure there is something that won't be found
5830         test_mkdir $dir
5831         touch $dir/$tfile.now
5832
5833         for age in year week day hour min; do
5834                 count=$((count + 1))
5835
5836                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
5837                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
5838                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
5839
5840                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
5841                 local nums=$($cmd | wc -l)
5842                 [ $nums -eq $expected ] ||
5843                         error "'$cmd' wrong: found $nums, expected $expected"
5844
5845                 cmd="$LFS find $dir -atime $count${age:0:1}"
5846                 nums=$($cmd | wc -l)
5847                 [ $nums -eq $expected ] ||
5848                         error "'$cmd' wrong: found $nums, expected $expected"
5849         done
5850
5851         sleep 2
5852         cmd="$LFS find $dir -ctime +1s -type f"
5853         nums=$($cmd | wc -l)
5854         (( $nums == $count * 2 + 1)) ||
5855                 error "'$cmd' wrong: found $nums, expected $((expected*2+1))"
5856 }
5857 run_test 56ob "check lfs find -atime -mtime -ctime with units"
5858
5859 test_newerXY_base() {
5860         local x=$1
5861         local y=$2
5862         local dir=$DIR/$tdir
5863         local ref
5864         local negref
5865
5866         if [ $y == "t" ]; then
5867                 ref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
5868         else
5869                 ref=$DIR/$tfile.newer
5870                 touch $ref || error "touch $ref failed"
5871         fi
5872         sleep 2
5873         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
5874         sleep 2
5875         if [ $y == "t" ]; then
5876                 negref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
5877         else
5878                 negref=$DIR/$tfile.newerneg
5879                 touch $negref || error "touch $negref failed"
5880         fi
5881
5882         local cmd="$LFS find $dir -newer$x$y $ref"
5883         local nums=$(eval $cmd | wc -l)
5884         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
5885
5886         [ $nums -eq $expected ] ||
5887                 error "'$cmd' wrong: found $nums, expected $expected"
5888
5889         cmd="$LFS find $dir ! -newer$x$y $negref"
5890         nums=$(eval $cmd | wc -l)
5891         [ $nums -eq $expected ] ||
5892                 error "'$cmd' wrong: found $nums, expected $expected"
5893
5894         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
5895         nums=$(eval $cmd | wc -l)
5896         [ $nums -eq $expected ] ||
5897                 error "'$cmd' wrong: found $nums, expected $expected"
5898
5899         rm -rf $DIR/*
5900 }
5901
5902 test_56oc() {
5903         test_newerXY_base "a" "a"
5904         test_newerXY_base "a" "m"
5905         test_newerXY_base "a" "c"
5906         test_newerXY_base "m" "a"
5907         test_newerXY_base "m" "m"
5908         test_newerXY_base "m" "c"
5909         test_newerXY_base "c" "a"
5910         test_newerXY_base "c" "m"
5911         test_newerXY_base "c" "c"
5912         test_newerXY_base "a" "t"
5913         test_newerXY_base "m" "t"
5914         test_newerXY_base "c" "t"
5915 }
5916 run_test 56oc "check lfs find -newerXY work"
5917
5918 test_56p() {
5919         [ $RUNAS_ID -eq $UID ] &&
5920                 skip_env "RUNAS_ID = UID = $UID -- skipping"
5921
5922         local dir=$DIR/$tdir
5923
5924         setup_56 $dir $NUMFILES $NUMDIRS
5925         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
5926
5927         local expected=$NUMFILES
5928         local cmd="$LFS find -uid $RUNAS_ID $dir"
5929         local nums=$($cmd | wc -l)
5930
5931         [ $nums -eq $expected ] ||
5932                 error "'$cmd' wrong: found $nums, expected $expected"
5933
5934         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
5935         cmd="$LFS find ! -uid $RUNAS_ID $dir"
5936         nums=$($cmd | wc -l)
5937         [ $nums -eq $expected ] ||
5938                 error "'$cmd' wrong: found $nums, expected $expected"
5939 }
5940 run_test 56p "check lfs find -uid and ! -uid"
5941
5942 test_56q() {
5943         [ $RUNAS_ID -eq $UID ] &&
5944                 skip_env "RUNAS_ID = UID = $UID -- skipping"
5945
5946         local dir=$DIR/$tdir
5947
5948         setup_56 $dir $NUMFILES $NUMDIRS
5949         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
5950
5951         local expected=$NUMFILES
5952         local cmd="$LFS find -gid $RUNAS_GID $dir"
5953         local nums=$($cmd | wc -l)
5954
5955         [ $nums -eq $expected ] ||
5956                 error "'$cmd' wrong: found $nums, expected $expected"
5957
5958         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
5959         cmd="$LFS find ! -gid $RUNAS_GID $dir"
5960         nums=$($cmd | wc -l)
5961         [ $nums -eq $expected ] ||
5962                 error "'$cmd' wrong: found $nums, expected $expected"
5963 }
5964 run_test 56q "check lfs find -gid and ! -gid"
5965
5966 test_56r() {
5967         local dir=$DIR/$tdir
5968
5969         setup_56 $dir $NUMFILES $NUMDIRS
5970
5971         local expected=12
5972         local cmd="$LFS find -size 0 -type f -lazy $dir"
5973         local nums=$($cmd | wc -l)
5974
5975         [ $nums -eq $expected ] ||
5976                 error "'$cmd' wrong: found $nums, expected $expected"
5977         cmd="$LFS find -size 0 -type f $dir"
5978         nums=$($cmd | wc -l)
5979         [ $nums -eq $expected ] ||
5980                 error "'$cmd' wrong: found $nums, expected $expected"
5981
5982         expected=0
5983         cmd="$LFS find ! -size 0 -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 0 -type f $dir"
5988         nums=$($cmd | wc -l)
5989         [ $nums -eq $expected ] ||
5990                 error "'$cmd' wrong: found $nums, expected $expected"
5991
5992         echo "test" > $dir/$tfile
5993         echo "test2" > $dir/$tfile.2 && sync
5994         expected=1
5995         cmd="$LFS find -size 5 -type f -lazy $dir"
5996         nums=$($cmd | wc -l)
5997         [ $nums -eq $expected ] ||
5998                 error "'$cmd' wrong: found $nums, expected $expected"
5999         cmd="$LFS find -size 5 -type f $dir"
6000         nums=$($cmd | wc -l)
6001         [ $nums -eq $expected ] ||
6002                 error "'$cmd' wrong: found $nums, expected $expected"
6003
6004         expected=1
6005         cmd="$LFS find -size +5 -type f -lazy $dir"
6006         nums=$($cmd | wc -l)
6007         [ $nums -eq $expected ] ||
6008                 error "'$cmd' wrong: found $nums, expected $expected"
6009         cmd="$LFS find -size +5 -type f $dir"
6010         nums=$($cmd | wc -l)
6011         [ $nums -eq $expected ] ||
6012                 error "'$cmd' wrong: found $nums, expected $expected"
6013
6014         expected=2
6015         cmd="$LFS find -size +0 -type f -lazy $dir"
6016         nums=$($cmd | wc -l)
6017         [ $nums -eq $expected ] ||
6018                 error "'$cmd' wrong: found $nums, expected $expected"
6019         cmd="$LFS find -size +0 -type f $dir"
6020         nums=$($cmd | wc -l)
6021         [ $nums -eq $expected ] ||
6022                 error "'$cmd' wrong: found $nums, expected $expected"
6023
6024         expected=2
6025         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6026         nums=$($cmd | wc -l)
6027         [ $nums -eq $expected ] ||
6028                 error "'$cmd' wrong: found $nums, expected $expected"
6029         cmd="$LFS find ! -size -5 -type f $dir"
6030         nums=$($cmd | wc -l)
6031         [ $nums -eq $expected ] ||
6032                 error "'$cmd' wrong: found $nums, expected $expected"
6033
6034         expected=12
6035         cmd="$LFS find -size -5 -type f -lazy $dir"
6036         nums=$($cmd | wc -l)
6037         [ $nums -eq $expected ] ||
6038                 error "'$cmd' wrong: found $nums, expected $expected"
6039         cmd="$LFS find -size -5 -type f $dir"
6040         nums=$($cmd | wc -l)
6041         [ $nums -eq $expected ] ||
6042                 error "'$cmd' wrong: found $nums, expected $expected"
6043 }
6044 run_test 56r "check lfs find -size works"
6045
6046 test_56ra() {
6047         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6048                 skip "MDS < 2.12.58 doesn't return LSOM data"
6049         local dir=$DIR/$tdir
6050
6051         [[ $OSC == "mdc" ]] && skip "DoM files" && return
6052
6053         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6054
6055         cancel_lru_locks $OSC
6056
6057         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6058         local expected=12
6059         local cmd="$LFS find -size 0 -type f -lazy $dir"
6060         local nums=$($cmd | wc -l)
6061
6062         [ $nums -eq $expected ] ||
6063                 error "'$cmd' wrong: found $nums, expected $expected"
6064
6065         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6066         [ $rpcs_before -eq $rpcs_after ] ||
6067                 error "'$cmd' should not send glimpse RPCs to OST"
6068         cmd="$LFS find -size 0 -type f $dir"
6069         nums=$($cmd | wc -l)
6070         [ $nums -eq $expected ] ||
6071                 error "'$cmd' wrong: found $nums, expected $expected"
6072         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6073         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6074         $LCTL get_param osc.*.stats
6075         [ $rpcs_after -eq $((rpcs_before + 12)) ] ||
6076                 error "'$cmd' should send 12 glimpse RPCs to OST"
6077
6078         cancel_lru_locks $OSC
6079         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6080         expected=0
6081         cmd="$LFS find ! -size 0 -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         $LCTL get_param mdc.*.stats
6087         [ $rpcs_before -eq $rpcs_after ] ||
6088                 error "'$cmd' should not send glimpse RPCs to OST"
6089         cmd="$LFS find ! -size 0 -type f $dir"
6090         nums=$($cmd | wc -l)
6091         [ $nums -eq $expected ] ||
6092                 error "'$cmd' wrong: found $nums, expected $expected"
6093         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6094         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6095         [ $rpcs_after -eq $((rpcs_before + 12)) ] ||
6096                 error "'$cmd' should send 12 glimpse RPCs to OST"
6097
6098         echo "test" > $dir/$tfile
6099         echo "test2" > $dir/$tfile.2 && sync
6100         cancel_lru_locks $OSC
6101         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6102         expected=1
6103         cmd="$LFS find -size 5 -type f -lazy $dir"
6104         nums=$($cmd | wc -l)
6105         [ $nums -eq $expected ] ||
6106                 error "'$cmd' wrong: found $nums, expected $expected"
6107         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6108         [ $rpcs_before -eq $rpcs_after ] ||
6109                 error "'$cmd' should not send glimpse RPCs to OST"
6110         cmd="$LFS find -size 5 -type f $dir"
6111         nums=$($cmd | wc -l)
6112         [ $nums -eq $expected ] ||
6113                 error "'$cmd' wrong: found $nums, expected $expected"
6114         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6115         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6116         [ $rpcs_after -eq $((rpcs_before + 14)) ] ||
6117                 error "'$cmd' should send 14 glimpse RPCs to OST"
6118
6119         cancel_lru_locks $OSC
6120         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6121         expected=1
6122         cmd="$LFS find -size +5 -type f -lazy $dir"
6123         nums=$($cmd | wc -l)
6124         [ $nums -eq $expected ] ||
6125                 error "'$cmd' wrong: found $nums, expected $expected"
6126         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6127         [ $rpcs_before -eq $rpcs_after ] ||
6128                 error "'$cmd' should not send glimpse RPCs to OST"
6129         cmd="$LFS find -size +5 -type f $dir"
6130         nums=$($cmd | wc -l)
6131         [ $nums -eq $expected ] ||
6132                 error "'$cmd' wrong: found $nums, expected $expected"
6133         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6134         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6135         [ $rpcs_after -eq $((rpcs_before + 14)) ] ||
6136                 error "'$cmd' should send 14 glimpse RPCs to OST"
6137
6138         cancel_lru_locks $OSC
6139         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6140         expected=2
6141         cmd="$LFS find -size +0 -type f -lazy $dir"
6142         nums=$($cmd | wc -l)
6143         [ $nums -eq $expected ] ||
6144                 error "'$cmd' wrong: found $nums, expected $expected"
6145         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6146         [ $rpcs_before -eq $rpcs_after ] ||
6147                 error "'$cmd' should not send glimpse RPCs to OST"
6148         cmd="$LFS find -size +0 -type f $dir"
6149         nums=$($cmd | wc -l)
6150         [ $nums -eq $expected ] ||
6151                 error "'$cmd' wrong: found $nums, expected $expected"
6152         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6153         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6154         [ $rpcs_after -eq $((rpcs_before + 14)) ] ||
6155                 error "'$cmd' should send 14 glimpse RPCs to OST"
6156
6157         cancel_lru_locks $OSC
6158         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6159         expected=2
6160         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6161         nums=$($cmd | wc -l)
6162         [ $nums -eq $expected ] ||
6163                 error "'$cmd' wrong: found $nums, expected $expected"
6164         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6165         [ $rpcs_before -eq $rpcs_after ] ||
6166                 error "'$cmd' should not send glimpse RPCs to OST"
6167         cmd="$LFS find ! -size -5 -type f $dir"
6168         nums=$($cmd | wc -l)
6169         [ $nums -eq $expected ] ||
6170                 error "'$cmd' wrong: found $nums, expected $expected"
6171         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6172         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6173         [ $rpcs_after -eq $((rpcs_before + 14)) ] ||
6174                 error "'$cmd' should send 14 glimpse RPCs to OST"
6175
6176         cancel_lru_locks $OSC
6177         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6178         expected=12
6179         cmd="$LFS find -size -5 -type f -lazy $dir"
6180         nums=$($cmd | wc -l)
6181         [ $nums -eq $expected ] ||
6182                 error "'$cmd' wrong: found $nums, expected $expected"
6183         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6184         [ $rpcs_before -eq $rpcs_after ] ||
6185                 error "'$cmd' should not send glimpse RPCs to OST"
6186         cmd="$LFS find -size -5 -type f $dir"
6187         nums=$($cmd | wc -l)
6188         [ $nums -eq $expected ] ||
6189                 error "'$cmd' wrong: found $nums, expected $expected"
6190         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6191         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6192         [ $rpcs_after -eq $((rpcs_before + 14)) ] ||
6193                 error "'$cmd' should send 14 glimpse RPCs to OST"
6194 }
6195 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6196
6197 test_56rb() {
6198         local dir=$DIR/$tdir
6199         local tmp=$TMP/$tfile.log
6200         local mdt_idx;
6201
6202         test_mkdir -p $dir || error "failed to mkdir $dir"
6203         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6204                 error "failed to setstripe $dir/$tfile"
6205         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6206
6207         stack_trap "rm -f $tmp" EXIT
6208         $LFS find --size +100K --ost 0 $dir 2>&1 | tee $tmp
6209         [ -z "$(cat $tmp | grep "obd_uuid: ")" ] ||
6210                 error "failed to find --size +100K --ost 0 $dir"
6211         $LFS find --size +100K --mdt $mdt_idx $dir 2>&1 | tee $tmp
6212         [ -z "$(cat $tmp | grep "obd_uuid: ")" ] ||
6213                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6214 }
6215 run_test 56rb "check lfs find --size --ost/--mdt works"
6216
6217 test_56s() { # LU-611 #LU-9369
6218         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6219
6220         local dir=$DIR/$tdir
6221         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6222
6223         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6224         for i in $(seq $NUMDIRS); do
6225                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6226         done
6227
6228         local expected=$NUMDIRS
6229         local cmd="$LFS find -c $OSTCOUNT $dir"
6230         local nums=$($cmd | wc -l)
6231
6232         [ $nums -eq $expected ] || {
6233                 $LFS getstripe -R $dir
6234                 error "'$cmd' wrong: found $nums, expected $expected"
6235         }
6236
6237         expected=$((NUMDIRS + onestripe))
6238         cmd="$LFS find -stripe-count +0 -type f $dir"
6239         nums=$($cmd | wc -l)
6240         [ $nums -eq $expected ] || {
6241                 $LFS getstripe -R $dir
6242                 error "'$cmd' wrong: found $nums, expected $expected"
6243         }
6244
6245         expected=$onestripe
6246         cmd="$LFS find -stripe-count 1 -type f $dir"
6247         nums=$($cmd | wc -l)
6248         [ $nums -eq $expected ] || {
6249                 $LFS getstripe -R $dir
6250                 error "'$cmd' wrong: found $nums, expected $expected"
6251         }
6252
6253         cmd="$LFS find -stripe-count -2 -type f $dir"
6254         nums=$($cmd | wc -l)
6255         [ $nums -eq $expected ] || {
6256                 $LFS getstripe -R $dir
6257                 error "'$cmd' wrong: found $nums, expected $expected"
6258         }
6259
6260         expected=0
6261         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6262         nums=$($cmd | wc -l)
6263         [ $nums -eq $expected ] || {
6264                 $LFS getstripe -R $dir
6265                 error "'$cmd' wrong: found $nums, expected $expected"
6266         }
6267 }
6268 run_test 56s "check lfs find -stripe-count works"
6269
6270 test_56t() { # LU-611 #LU-9369
6271         local dir=$DIR/$tdir
6272
6273         setup_56 $dir 0 $NUMDIRS
6274         for i in $(seq $NUMDIRS); do
6275                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6276         done
6277
6278         local expected=$NUMDIRS
6279         local cmd="$LFS find -S 8M $dir"
6280         local nums=$($cmd | wc -l)
6281
6282         [ $nums -eq $expected ] || {
6283                 $LFS getstripe -R $dir
6284                 error "'$cmd' wrong: found $nums, expected $expected"
6285         }
6286         rm -rf $dir
6287
6288         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6289
6290         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6291
6292         expected=$(((NUMDIRS + 1) * NUMFILES))
6293         cmd="$LFS find -stripe-size 512k -type f $dir"
6294         nums=$($cmd | wc -l)
6295         [ $nums -eq $expected ] ||
6296                 error "'$cmd' wrong: found $nums, expected $expected"
6297
6298         cmd="$LFS find -stripe-size +320k -type f $dir"
6299         nums=$($cmd | wc -l)
6300         [ $nums -eq $expected ] ||
6301                 error "'$cmd' wrong: found $nums, expected $expected"
6302
6303         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6304         cmd="$LFS find -stripe-size +200k -type f $dir"
6305         nums=$($cmd | wc -l)
6306         [ $nums -eq $expected ] ||
6307                 error "'$cmd' wrong: found $nums, expected $expected"
6308
6309         cmd="$LFS find -stripe-size -640k -type f $dir"
6310         nums=$($cmd | wc -l)
6311         [ $nums -eq $expected ] ||
6312                 error "'$cmd' wrong: found $nums, expected $expected"
6313
6314         expected=4
6315         cmd="$LFS find -stripe-size 256k -type f $dir"
6316         nums=$($cmd | wc -l)
6317         [ $nums -eq $expected ] ||
6318                 error "'$cmd' wrong: found $nums, expected $expected"
6319
6320         cmd="$LFS find -stripe-size -320k -type f $dir"
6321         nums=$($cmd | wc -l)
6322         [ $nums -eq $expected ] ||
6323                 error "'$cmd' wrong: found $nums, expected $expected"
6324
6325         expected=0
6326         cmd="$LFS find -stripe-size 1024k -type f $dir"
6327         nums=$($cmd | wc -l)
6328         [ $nums -eq $expected ] ||
6329                 error "'$cmd' wrong: found $nums, expected $expected"
6330 }
6331 run_test 56t "check lfs find -stripe-size works"
6332
6333 test_56u() { # LU-611
6334         local dir=$DIR/$tdir
6335
6336         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6337
6338         if [[ $OSTCOUNT -gt 1 ]]; then
6339                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6340                 onestripe=4
6341         else
6342                 onestripe=0
6343         fi
6344
6345         local expected=$(((NUMDIRS + 1) * NUMFILES))
6346         local cmd="$LFS find -stripe-index 0 -type f $dir"
6347         local nums=$($cmd | wc -l)
6348
6349         [ $nums -eq $expected ] ||
6350                 error "'$cmd' wrong: found $nums, expected $expected"
6351
6352         expected=$onestripe
6353         cmd="$LFS find -stripe-index 1 -type f $dir"
6354         nums=$($cmd | wc -l)
6355         [ $nums -eq $expected ] ||
6356                 error "'$cmd' wrong: found $nums, expected $expected"
6357
6358         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6359         nums=$($cmd | wc -l)
6360         [ $nums -eq $expected ] ||
6361                 error "'$cmd' wrong: found $nums, expected $expected"
6362
6363         expected=0
6364         # This should produce an error and not return any files
6365         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
6366         nums=$($cmd 2>/dev/null | wc -l)
6367         [ $nums -eq $expected ] ||
6368                 error "'$cmd' wrong: found $nums, expected $expected"
6369
6370         if [[ $OSTCOUNT -gt 1 ]]; then
6371                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
6372                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
6373                 nums=$($cmd | wc -l)
6374                 [ $nums -eq $expected ] ||
6375                         error "'$cmd' wrong: found $nums, expected $expected"
6376         fi
6377 }
6378 run_test 56u "check lfs find -stripe-index works"
6379
6380 test_56v() {
6381         local mdt_idx=0
6382         local dir=$DIR/$tdir
6383
6384         setup_56 $dir $NUMFILES $NUMDIRS
6385
6386         UUID=$(mdtuuid_from_index $mdt_idx $dir)
6387         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
6388
6389         for file in $($LFS find -m $UUID $dir); do
6390                 file_midx=$($LFS getstripe -m $file)
6391                 [ $file_midx -eq $mdt_idx ] ||
6392                         error "lfs find -m $UUID != getstripe -m $file_midx"
6393         done
6394 }
6395 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
6396
6397 test_56w() {
6398         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6399         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6400
6401         local dir=$DIR/$tdir
6402
6403         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
6404
6405         local stripe_size=$($LFS getstripe -S -d $dir) ||
6406                 error "$LFS getstripe -S -d $dir failed"
6407         stripe_size=${stripe_size%% *}
6408
6409         local file_size=$((stripe_size * OSTCOUNT))
6410         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
6411         local required_space=$((file_num * file_size))
6412         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
6413                            head -n1)
6414         [[ $free_space -le $((required_space / 1024)) ]] &&
6415                 skip_env "need $required_space, have $free_space kbytes"
6416
6417         local dd_bs=65536
6418         local dd_count=$((file_size / dd_bs))
6419
6420         # write data into the files
6421         local i
6422         local j
6423         local file
6424
6425         for i in $(seq $NUMFILES); do
6426                 file=$dir/file$i
6427                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6428                         error "write data into $file failed"
6429         done
6430         for i in $(seq $NUMDIRS); do
6431                 for j in $(seq $NUMFILES); do
6432                         file=$dir/dir$i/file$j
6433                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6434                                 error "write data into $file failed"
6435                 done
6436         done
6437
6438         # $LFS_MIGRATE will fail if hard link migration is unsupported
6439         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
6440                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
6441                         error "creating links to $dir/dir1/file1 failed"
6442         fi
6443
6444         local expected=-1
6445
6446         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
6447
6448         # lfs_migrate file
6449         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
6450
6451         echo "$cmd"
6452         eval $cmd || error "$cmd failed"
6453
6454         check_stripe_count $dir/file1 $expected
6455
6456         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
6457         then
6458                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
6459                 # OST 1 if it is on OST 0. This file is small enough to
6460                 # be on only one stripe.
6461                 file=$dir/migr_1_ost
6462                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
6463                         error "write data into $file failed"
6464                 local obdidx=$($LFS getstripe -i $file)
6465                 local oldmd5=$(md5sum $file)
6466                 local newobdidx=0
6467
6468                 [[ $obdidx -eq 0 ]] && newobdidx=1
6469                 cmd="$LFS migrate -i $newobdidx $file"
6470                 echo $cmd
6471                 eval $cmd || error "$cmd failed"
6472
6473                 local realobdix=$($LFS getstripe -i $file)
6474                 local newmd5=$(md5sum $file)
6475
6476                 [[ $newobdidx -ne $realobdix ]] &&
6477                         error "new OST is different (was=$obdidx, "\
6478                               "wanted=$newobdidx, got=$realobdix)"
6479                 [[ "$oldmd5" != "$newmd5" ]] &&
6480                         error "md5sum differ: $oldmd5, $newmd5"
6481         fi
6482
6483         # lfs_migrate dir
6484         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
6485         echo "$cmd"
6486         eval $cmd || error "$cmd failed"
6487
6488         for j in $(seq $NUMFILES); do
6489                 check_stripe_count $dir/dir1/file$j $expected
6490         done
6491
6492         # lfs_migrate works with lfs find
6493         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
6494              $LFS_MIGRATE -y -c $expected"
6495         echo "$cmd"
6496         eval $cmd || error "$cmd failed"
6497
6498         for i in $(seq 2 $NUMFILES); do
6499                 check_stripe_count $dir/file$i $expected
6500         done
6501         for i in $(seq 2 $NUMDIRS); do
6502                 for j in $(seq $NUMFILES); do
6503                 check_stripe_count $dir/dir$i/file$j $expected
6504                 done
6505         done
6506 }
6507 run_test 56w "check lfs_migrate -c stripe_count works"
6508
6509 test_56wb() {
6510         local file1=$DIR/$tdir/file1
6511         local create_pool=false
6512         local initial_pool=$($LFS getstripe -p $DIR)
6513         local pool_list=()
6514         local pool=""
6515
6516         echo -n "Creating test dir..."
6517         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6518         echo "done."
6519
6520         echo -n "Creating test file..."
6521         touch $file1 || error "cannot create file"
6522         echo "done."
6523
6524         echo -n "Detecting existing pools..."
6525         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
6526
6527         if [ ${#pool_list[@]} -gt 0 ]; then
6528                 echo "${pool_list[@]}"
6529                 for thispool in "${pool_list[@]}"; do
6530                         if [[ -z "$initial_pool" ||
6531                               "$initial_pool" != "$thispool" ]]; then
6532                                 pool="$thispool"
6533                                 echo "Using existing pool '$pool'"
6534                                 break
6535                         fi
6536                 done
6537         else
6538                 echo "none detected."
6539         fi
6540         if [ -z "$pool" ]; then
6541                 pool=${POOL:-testpool}
6542                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
6543                 echo -n "Creating pool '$pool'..."
6544                 create_pool=true
6545                 pool_add $pool &> /dev/null ||
6546                         error "pool_add failed"
6547                 echo "done."
6548
6549                 echo -n "Adding target to pool..."
6550                 pool_add_targets $pool 0 0 1 &> /dev/null ||
6551                         error "pool_add_targets failed"
6552                 echo "done."
6553         fi
6554
6555         echo -n "Setting pool using -p option..."
6556         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
6557                 error "migrate failed rc = $?"
6558         echo "done."
6559
6560         echo -n "Verifying test file is in pool after migrating..."
6561         [ "$($LFS getstripe -p $file1)" = $pool ] ||
6562                 error "file was not migrated to pool $pool"
6563         echo "done."
6564
6565         echo -n "Removing test file from pool '$pool'..."
6566         # "lfs migrate $file" won't remove the file from the pool
6567         # until some striping information is changed.
6568         $LFS migrate -c 1 $file1 &> /dev/null ||
6569                 error "cannot remove from pool"
6570         [ "$($LFS getstripe -p $file1)" ] &&
6571                 error "pool still set"
6572         echo "done."
6573
6574         echo -n "Setting pool using --pool option..."
6575         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
6576                 error "migrate failed rc = $?"
6577         echo "done."
6578
6579         # Clean up
6580         rm -f $file1
6581         if $create_pool; then
6582                 destroy_test_pools 2> /dev/null ||
6583                         error "destroy test pools failed"
6584         fi
6585 }
6586 run_test 56wb "check lfs_migrate pool support"
6587
6588 test_56wc() {
6589         local file1="$DIR/$tdir/file1"
6590         local parent_ssize
6591         local parent_scount
6592         local cur_ssize
6593         local cur_scount
6594         local orig_ssize
6595
6596         echo -n "Creating test dir..."
6597         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6598         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
6599                 error "cannot set stripe by '-S 1M -c 1'"
6600         echo "done"
6601
6602         echo -n "Setting initial stripe for test file..."
6603         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
6604                 error "cannot set stripe"
6605         cur_ssize=$($LFS getstripe -S "$file1")
6606         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
6607         echo "done."
6608
6609         # File currently set to -S 512K -c 1
6610
6611         # Ensure -c and -S options are rejected when -R is set
6612         echo -n "Verifying incompatible options are detected..."
6613         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
6614                 error "incompatible -c and -R options not detected"
6615         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
6616                 error "incompatible -S and -R options not detected"
6617         echo "done."
6618
6619         # Ensure unrecognized options are passed through to 'lfs migrate'
6620         echo -n "Verifying -S option is passed through to lfs migrate..."
6621         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
6622                 error "migration failed"
6623         cur_ssize=$($LFS getstripe -S "$file1")
6624         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
6625         echo "done."
6626
6627         # File currently set to -S 1M -c 1
6628
6629         # Ensure long options are supported
6630         echo -n "Verifying long options supported..."
6631         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
6632                 error "long option without argument not supported"
6633         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
6634                 error "long option with argument not supported"
6635         cur_ssize=$($LFS getstripe -S "$file1")
6636         [ $cur_ssize -eq 524288 ] ||
6637                 error "migrate --stripe-size $cur_ssize != 524288"
6638         echo "done."
6639
6640         # File currently set to -S 512K -c 1
6641
6642         if [ "$OSTCOUNT" -gt 1 ]; then
6643                 echo -n "Verifying explicit stripe count can be set..."
6644                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
6645                         error "migrate failed"
6646                 cur_scount=$($LFS getstripe -c "$file1")
6647                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
6648                 echo "done."
6649         fi
6650
6651         # File currently set to -S 512K -c 1 or -S 512K -c 2
6652
6653         # Ensure parent striping is used if -R is set, and no stripe
6654         # count or size is specified
6655         echo -n "Setting stripe for parent directory..."
6656         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6657                 error "cannot set stripe '-S 2M -c 1'"
6658         echo "done."
6659
6660         echo -n "Verifying restripe option uses parent stripe settings..."
6661         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
6662         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
6663         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
6664                 error "migrate failed"
6665         cur_ssize=$($LFS getstripe -S "$file1")
6666         [ $cur_ssize -eq $parent_ssize ] ||
6667                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
6668         cur_scount=$($LFS getstripe -c "$file1")
6669         [ $cur_scount -eq $parent_scount ] ||
6670                 error "migrate -R stripe_count $cur_scount != $parent_scount"
6671         echo "done."
6672
6673         # File currently set to -S 1M -c 1
6674
6675         # Ensure striping is preserved if -R is not set, and no stripe
6676         # count or size is specified
6677         echo -n "Verifying striping size preserved when not specified..."
6678         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
6679         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6680                 error "cannot set stripe on parent directory"
6681         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6682                 error "migrate failed"
6683         cur_ssize=$($LFS getstripe -S "$file1")
6684         [ $cur_ssize -eq $orig_ssize ] ||
6685                 error "migrate by default $cur_ssize != $orig_ssize"
6686         echo "done."
6687
6688         # Ensure file name properly detected when final option has no argument
6689         echo -n "Verifying file name properly detected..."
6690         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6691                 error "file name interpreted as option argument"
6692         echo "done."
6693
6694         # Clean up
6695         rm -f "$file1"
6696 }
6697 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
6698
6699 test_56wd() {
6700         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6701
6702         local file1=$DIR/$tdir/file1
6703
6704         echo -n "Creating test dir..."
6705         test_mkdir $DIR/$tdir || error "cannot create dir"
6706         echo "done."
6707
6708         echo -n "Creating test file..."
6709         touch $file1
6710         echo "done."
6711
6712         # Ensure 'lfs migrate' will fail by using a non-existent option,
6713         # and make sure rsync is not called to recover
6714         echo -n "Make sure --no-rsync option works..."
6715         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
6716                 grep -q 'refusing to fall back to rsync' ||
6717                 error "rsync was called with --no-rsync set"
6718         echo "done."
6719
6720         # Ensure rsync is called without trying 'lfs migrate' first
6721         echo -n "Make sure --rsync option works..."
6722         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
6723                 grep -q 'falling back to rsync' &&
6724                 error "lfs migrate was called with --rsync set"
6725         echo "done."
6726
6727         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
6728         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
6729                 grep -q 'at the same time' ||
6730                 error "--rsync and --no-rsync accepted concurrently"
6731         echo "done."
6732
6733         # Clean up
6734         rm -f $file1
6735 }
6736 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
6737
6738 test_56x() {
6739         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6740         check_swap_layouts_support
6741
6742         local dir=$DIR/$tdir
6743         local ref1=/etc/passwd
6744         local file1=$dir/file1
6745
6746         test_mkdir $dir || error "creating dir $dir"
6747         $LFS setstripe -c 2 $file1
6748         cp $ref1 $file1
6749         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
6750         stripe=$($LFS getstripe -c $file1)
6751         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6752         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6753
6754         # clean up
6755         rm -f $file1
6756 }
6757 run_test 56x "lfs migration support"
6758
6759 test_56xa() {
6760         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6761         check_swap_layouts_support
6762
6763         local dir=$DIR/$tdir/$testnum
6764
6765         test_mkdir -p $dir
6766
6767         local ref1=/etc/passwd
6768         local file1=$dir/file1
6769
6770         $LFS setstripe -c 2 $file1
6771         cp $ref1 $file1
6772         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
6773
6774         local stripe=$($LFS getstripe -c $file1)
6775
6776         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6777         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6778
6779         # clean up
6780         rm -f $file1
6781 }
6782 run_test 56xa "lfs migration --block support"
6783
6784 check_migrate_links() {
6785         local dir="$1"
6786         local file1="$dir/file1"
6787         local begin="$2"
6788         local count="$3"
6789         local runas="$4"
6790         local total_count=$(($begin + $count - 1))
6791         local symlink_count=10
6792         local uniq_count=10
6793
6794         if [ ! -f "$file1" ]; then
6795                 echo -n "creating initial file..."
6796                 $LFS setstripe -c 1 -S "512k" "$file1" ||
6797                         error "cannot setstripe initial file"
6798                 echo "done"
6799
6800                 echo -n "creating symlinks..."
6801                 for s in $(seq 1 $symlink_count); do
6802                         ln -s "$file1" "$dir/slink$s" ||
6803                                 error "cannot create symlinks"
6804                 done
6805                 echo "done"
6806
6807                 echo -n "creating nonlinked files..."
6808                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
6809                         error "cannot create nonlinked files"
6810                 echo "done"
6811         fi
6812
6813         # create hard links
6814         if [ ! -f "$dir/file$total_count" ]; then
6815                 echo -n "creating hard links $begin:$total_count..."
6816                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
6817                         /dev/null || error "cannot create hard links"
6818                 echo "done"
6819         fi
6820
6821         echo -n "checking number of hard links listed in xattrs..."
6822         local fid=$($LFS getstripe -F "$file1")
6823         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
6824
6825         echo "${#paths[*]}"
6826         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
6827                         skip "hard link list has unexpected size, skipping test"
6828         fi
6829         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
6830                         error "link names should exceed xattrs size"
6831         fi
6832
6833         echo -n "migrating files..."
6834         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
6835         local rc=$?
6836         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
6837         echo "done"
6838
6839         # make sure all links have been properly migrated
6840         echo -n "verifying files..."
6841         fid=$($LFS getstripe -F "$file1") ||
6842                 error "cannot get fid for file $file1"
6843         for i in $(seq 2 $total_count); do
6844                 local fid2=$($LFS getstripe -F $dir/file$i)
6845
6846                 [ "$fid2" == "$fid" ] ||
6847                         error "migrated hard link has mismatched FID"
6848         done
6849
6850         # make sure hard links were properly detected, and migration was
6851         # performed only once for the entire link set; nonlinked files should
6852         # also be migrated
6853         local actual=$(grep -c 'done' <<< "$migrate_out")
6854         local expected=$(($uniq_count + 1))
6855
6856         [ "$actual" -eq  "$expected" ] ||
6857                 error "hard links individually migrated ($actual != $expected)"
6858
6859         # make sure the correct number of hard links are present
6860         local hardlinks=$(stat -c '%h' "$file1")
6861
6862         [ $hardlinks -eq $total_count ] ||
6863                 error "num hard links $hardlinks != $total_count"
6864         echo "done"
6865
6866         return 0
6867 }
6868
6869 test_56xb() {
6870         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
6871                 skip "Need MDS version at least 2.10.55"
6872
6873         local dir="$DIR/$tdir"
6874
6875         test_mkdir "$dir" || error "cannot create dir $dir"
6876
6877         echo "testing lfs migrate mode when all links fit within xattrs"
6878         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
6879
6880         echo "testing rsync mode when all links fit within xattrs"
6881         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
6882
6883         echo "testing lfs migrate mode when all links do not fit within xattrs"
6884         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
6885
6886         echo "testing rsync mode when all links do not fit within xattrs"
6887         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
6888
6889         chown -R $RUNAS_ID $dir
6890         echo "testing non-root lfs migrate mode when not all links are in xattr"
6891         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
6892
6893         # clean up
6894         rm -rf $dir
6895 }
6896 run_test 56xb "lfs migration hard link support"
6897
6898 test_56xc() {
6899         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6900
6901         local dir="$DIR/$tdir"
6902
6903         test_mkdir "$dir" || error "cannot create dir $dir"
6904
6905         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
6906         echo -n "Setting initial stripe for 20MB test file..."
6907         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
6908                 error "cannot setstripe 20MB file"
6909         echo "done"
6910         echo -n "Sizing 20MB test file..."
6911         truncate "$dir/20mb" 20971520 || error "cannot create 20MB test file"
6912         echo "done"
6913         echo -n "Verifying small file autostripe count is 1..."
6914         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
6915                 error "cannot migrate 20MB file"
6916         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
6917                 error "cannot get stripe for $dir/20mb"
6918         [ $stripe_count -eq 1 ] ||
6919                 error "unexpected stripe count $stripe_count for 20MB file"
6920         rm -f "$dir/20mb"
6921         echo "done"
6922
6923         # Test 2: File is small enough to fit within the available space on
6924         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
6925         # have at least an additional 1KB for each desired stripe for test 3
6926         echo -n "Setting stripe for 1GB test file..."
6927         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
6928         echo "done"
6929         echo -n "Sizing 1GB test file..."
6930         # File size is 1GB + 3KB
6931         truncate "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
6932         echo "done"
6933
6934         # need at least 512MB per OST for 1GB file to fit in 2 stripes
6935         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
6936         if (( avail > 524288 * OSTCOUNT )); then
6937                 echo -n "Migrating 1GB file..."
6938                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
6939                         error "cannot migrate 1GB file"
6940                 echo "done"
6941                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
6942                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
6943                         error "cannot getstripe for 1GB file"
6944                 [ $stripe_count -eq 2 ] ||
6945                         error "unexpected stripe count $stripe_count != 2"
6946                 echo "done"
6947         fi
6948
6949         # Test 3: File is too large to fit within the available space on
6950         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
6951         if [ $OSTCOUNT -ge 3 ]; then
6952                 # The required available space is calculated as
6953                 # file size (1GB + 3KB) / OST count (3).
6954                 local kb_per_ost=349526
6955
6956                 echo -n "Migrating 1GB file with limit..."
6957                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
6958                         error "cannot migrate 1GB file with limit"
6959                 echo "done"
6960
6961                 stripe_count=$($LFS getstripe -c "$dir/1gb")
6962                 echo -n "Verifying 1GB autostripe count with limited space..."
6963                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
6964                         error "unexpected stripe count $stripe_count (min 3)"
6965                 echo "done"
6966         fi
6967
6968         # clean up
6969         rm -rf $dir
6970 }
6971 run_test 56xc "lfs migration autostripe"
6972
6973 test_56xd() {
6974         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6975
6976         local dir=$DIR/$tdir
6977         local f_mgrt=$dir/$tfile.mgrt
6978         local f_yaml=$dir/$tfile.yaml
6979         local f_copy=$dir/$tfile.copy
6980         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
6981         local layout_copy="-c 2 -S 2M -i 1"
6982         local yamlfile=$dir/yamlfile
6983         local layout_before;
6984         local layout_after;
6985
6986         test_mkdir "$dir" || error "cannot create dir $dir"
6987         $LFS setstripe $layout_yaml $f_yaml ||
6988                 error "cannot setstripe $f_yaml with layout $layout_yaml"
6989         $LFS getstripe --yaml $f_yaml > $yamlfile
6990         $LFS setstripe $layout_copy $f_copy ||
6991                 error "cannot setstripe $f_copy with layout $layout_copy"
6992         touch $f_mgrt
6993         dd if=/dev/zero of=$f_mgrt bs=1M count=4
6994
6995         # 1. test option --yaml
6996         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
6997                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
6998         layout_before=$(get_layout_param $f_yaml)
6999         layout_after=$(get_layout_param $f_mgrt)
7000         [ "$layout_after" == "$layout_before" ] ||
7001                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7002
7003         # 2. test option --copy
7004         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7005                 error "cannot migrate $f_mgrt with --copy $f_copy"
7006         layout_before=$(get_layout_param $f_copy)
7007         layout_after=$(get_layout_param $f_mgrt)
7008         [ "$layout_after" == "$layout_before" ] ||
7009                 error "lfs_migrate --copy: $layout_after != $layout_before"
7010 }
7011 run_test 56xd "check lfs_migrate --yaml and --copy support"
7012
7013 test_56xe() {
7014         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7015
7016         local dir=$DIR/$tdir
7017         local f_comp=$dir/$tfile
7018         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7019         local layout_before=""
7020         local layout_after=""
7021
7022         test_mkdir "$dir" || error "cannot create dir $dir"
7023         $LFS setstripe $layout $f_comp ||
7024                 error "cannot setstripe $f_comp with layout $layout"
7025         layout_before=$(get_layout_param $f_comp)
7026         dd if=/dev/zero of=$f_comp bs=1M count=4
7027
7028         # 1. migrate a comp layout file by lfs_migrate
7029         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7030         layout_after=$(get_layout_param $f_comp)
7031         [ "$layout_before" == "$layout_after" ] ||
7032                 error "lfs_migrate: $layout_before != $layout_after"
7033
7034         # 2. migrate a comp layout file by lfs migrate
7035         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7036         layout_after=$(get_layout_param $f_comp)
7037         [ "$layout_before" == "$layout_after" ] ||
7038                 error "lfs migrate: $layout_before != $layout_after"
7039 }
7040 run_test 56xe "migrate a composite layout file"
7041
7042 test_56y() {
7043         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7044                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7045
7046         local res=""
7047         local dir=$DIR/$tdir
7048         local f1=$dir/file1
7049         local f2=$dir/file2
7050
7051         test_mkdir -p $dir || error "creating dir $dir"
7052         touch $f1 || error "creating std file $f1"
7053         $MULTIOP $f2 H2c || error "creating released file $f2"
7054
7055         # a directory can be raid0, so ask only for files
7056         res=$($LFS find $dir -L raid0 -type f | wc -l)
7057         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7058
7059         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7060         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7061
7062         # only files can be released, so no need to force file search
7063         res=$($LFS find $dir -L released)
7064         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7065
7066         res=$($LFS find $dir -type f \! -L released)
7067         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7068 }
7069 run_test 56y "lfs find -L raid0|released"
7070
7071 test_56z() { # LU-4824
7072         # This checks to make sure 'lfs find' continues after errors
7073         # There are two classes of errors that should be caught:
7074         # - If multiple paths are provided, all should be searched even if one
7075         #   errors out
7076         # - If errors are encountered during the search, it should not terminate
7077         #   early
7078         local dir=$DIR/$tdir
7079         local i
7080
7081         test_mkdir $dir
7082         for i in d{0..9}; do
7083                 test_mkdir $dir/$i
7084                 touch $dir/$i/$tfile
7085         done
7086         $LFS find $DIR/non_existent_dir $dir &&
7087                 error "$LFS find did not return an error"
7088         # Make a directory unsearchable. This should NOT be the last entry in
7089         # directory order.  Arbitrarily pick the 6th entry
7090         chmod 700 $($LFS find $dir -type d | sed '6!d')
7091
7092         $RUNAS $LFS find $DIR/non_existent $dir
7093         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7094
7095         # The user should be able to see 10 directories and 9 files
7096         (( count == 19 )) ||
7097                 error "$LFS find found $count != 19 entries after error"
7098 }
7099 run_test 56z "lfs find should continue after an error"
7100
7101 test_56aa() { # LU-5937
7102         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7103
7104         local dir=$DIR/$tdir
7105
7106         mkdir $dir
7107         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7108
7109         createmany -o $dir/striped_dir/${tfile}- 1024
7110         local dirs=$($LFS find --size +8k $dir/)
7111
7112         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7113 }
7114 run_test 56aa "lfs find --size under striped dir"
7115
7116 test_56ab() { # LU-10705
7117         test_mkdir $DIR/$tdir
7118         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7119         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7120         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7121         # Flush writes to ensure valid blocks.  Need to be more thorough for
7122         # ZFS, since blocks are not allocated/returned to client immediately.
7123         sync_all_data
7124         wait_zfs_commit ost1 2
7125         cancel_lru_locks osc
7126         ls -ls $DIR/$tdir
7127
7128         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7129
7130         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7131
7132         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7133         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7134
7135         rm -f $DIR/$tdir/$tfile.[123]
7136 }
7137 run_test 56ab "lfs find --blocks"
7138
7139 test_56ba() {
7140         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
7141                 skip "Need MDS version at least 2.10.50"
7142
7143         # Create composite files with one component
7144         local dir=$DIR/$tdir
7145
7146         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
7147         # Create composite files with three components
7148         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
7149         # Create non-composite files
7150         createmany -o $dir/${tfile}- 10
7151
7152         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
7153
7154         [[ $nfiles == 10 ]] ||
7155                 error "lfs find -E 1M found $nfiles != 10 files"
7156
7157         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
7158         [[ $nfiles == 25 ]] ||
7159                 error "lfs find ! -E 1M found $nfiles != 25 files"
7160
7161         # All files have a component that starts at 0
7162         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
7163         [[ $nfiles == 35 ]] ||
7164                 error "lfs find --component-start 0 - $nfiles != 35 files"
7165
7166         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
7167         [[ $nfiles == 15 ]] ||
7168                 error "lfs find --component-start 2M - $nfiles != 15 files"
7169
7170         # All files created here have a componenet that does not starts at 2M
7171         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
7172         [[ $nfiles == 35 ]] ||
7173                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
7174
7175         # Find files with a specified number of components
7176         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
7177         [[ $nfiles == 15 ]] ||
7178                 error "lfs find --component-count 3 - $nfiles != 15 files"
7179
7180         # Remember non-composite files have a component count of zero
7181         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
7182         [[ $nfiles == 10 ]] ||
7183                 error "lfs find --component-count 0 - $nfiles != 10 files"
7184
7185         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
7186         [[ $nfiles == 20 ]] ||
7187                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
7188
7189         # All files have a flag called "init"
7190         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
7191         [[ $nfiles == 35 ]] ||
7192                 error "lfs find --component-flags init - $nfiles != 35 files"
7193
7194         # Multi-component files will have a component not initialized
7195         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
7196         [[ $nfiles == 15 ]] ||
7197                 error "lfs find !--component-flags init - $nfiles != 15 files"
7198
7199         rm -rf $dir
7200
7201 }
7202 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
7203
7204 test_56ca() {
7205         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
7206                 skip "Need MDS version at least 2.10.57"
7207
7208         local td=$DIR/$tdir
7209         local tf=$td/$tfile
7210         local dir
7211         local nfiles
7212         local cmd
7213         local i
7214         local j
7215
7216         # create mirrored directories and mirrored files
7217         mkdir $td || error "mkdir $td failed"
7218         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
7219         createmany -o $tf- 10 || error "create $tf- failed"
7220
7221         for i in $(seq 2); do
7222                 dir=$td/dir$i
7223                 mkdir $dir || error "mkdir $dir failed"
7224                 $LFS mirror create -N$((3 + i)) $dir ||
7225                         error "create mirrored dir $dir failed"
7226                 createmany -o $dir/$tfile- 10 ||
7227                         error "create $dir/$tfile- failed"
7228         done
7229
7230         # change the states of some mirrored files
7231         echo foo > $tf-6
7232         for i in $(seq 2); do
7233                 dir=$td/dir$i
7234                 for j in $(seq 4 9); do
7235                         echo foo > $dir/$tfile-$j
7236                 done
7237         done
7238
7239         # find mirrored files with specific mirror count
7240         cmd="$LFS find --mirror-count 3 --type f $td"
7241         nfiles=$($cmd | wc -l)
7242         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
7243
7244         cmd="$LFS find ! --mirror-count 3 --type f $td"
7245         nfiles=$($cmd | wc -l)
7246         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
7247
7248         cmd="$LFS find --mirror-count +2 --type f $td"
7249         nfiles=$($cmd | wc -l)
7250         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7251
7252         cmd="$LFS find --mirror-count -6 --type f $td"
7253         nfiles=$($cmd | wc -l)
7254         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7255
7256         # find mirrored files with specific file state
7257         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
7258         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
7259
7260         cmd="$LFS find --mirror-state=ro --type f $td"
7261         nfiles=$($cmd | wc -l)
7262         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
7263
7264         cmd="$LFS find ! --mirror-state=ro --type f $td"
7265         nfiles=$($cmd | wc -l)
7266         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7267
7268         cmd="$LFS find --mirror-state=wp --type f $td"
7269         nfiles=$($cmd | wc -l)
7270         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7271
7272         cmd="$LFS find ! --mirror-state=sp --type f $td"
7273         nfiles=$($cmd | wc -l)
7274         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7275 }
7276 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
7277
7278 test_57a() {
7279         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7280         # note test will not do anything if MDS is not local
7281         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7282                 skip_env "ldiskfs only test"
7283         fi
7284         remote_mds_nodsh && skip "remote MDS with nodsh"
7285
7286         local MNTDEV="osd*.*MDT*.mntdev"
7287         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
7288         [ -z "$DEV" ] && error "can't access $MNTDEV"
7289         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
7290                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
7291                         error "can't access $DEV"
7292                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
7293                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
7294                 rm $TMP/t57a.dump
7295         done
7296 }
7297 run_test 57a "verify MDS filesystem created with large inodes =="
7298
7299 test_57b() {
7300         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7301         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7302                 skip_env "ldiskfs only test"
7303         fi
7304         remote_mds_nodsh && skip "remote MDS with nodsh"
7305
7306         local dir=$DIR/$tdir
7307         local filecount=100
7308         local file1=$dir/f1
7309         local fileN=$dir/f$filecount
7310
7311         rm -rf $dir || error "removing $dir"
7312         test_mkdir -c1 $dir
7313         local mdtidx=$($LFS getstripe -m $dir)
7314         local mdtname=MDT$(printf %04x $mdtidx)
7315         local facet=mds$((mdtidx + 1))
7316
7317         echo "mcreating $filecount files"
7318         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
7319
7320         # verify that files do not have EAs yet
7321         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
7322                 error "$file1 has an EA"
7323         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
7324                 error "$fileN has an EA"
7325
7326         sync
7327         sleep 1
7328         df $dir  #make sure we get new statfs data
7329         local mdsfree=$(do_facet $facet \
7330                         lctl get_param -n osd*.*$mdtname.kbytesfree)
7331         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7332         local file
7333
7334         echo "opening files to create objects/EAs"
7335         for file in $(seq -f $dir/f%g 1 $filecount); do
7336                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
7337                         error "opening $file"
7338         done
7339
7340         # verify that files have EAs now
7341         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
7342         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
7343
7344         sleep 1  #make sure we get new statfs data
7345         df $dir
7346         local mdsfree2=$(do_facet $facet \
7347                          lctl get_param -n osd*.*$mdtname.kbytesfree)
7348         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7349
7350         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
7351                 if [ "$mdsfree" != "$mdsfree2" ]; then
7352                         error "MDC before $mdcfree != after $mdcfree2"
7353                 else
7354                         echo "MDC before $mdcfree != after $mdcfree2"
7355                         echo "unable to confirm if MDS has large inodes"
7356                 fi
7357         fi
7358         rm -rf $dir
7359 }
7360 run_test 57b "default LOV EAs are stored inside large inodes ==="
7361
7362 test_58() {
7363         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7364         [ -z "$(which wiretest 2>/dev/null)" ] &&
7365                         skip_env "could not find wiretest"
7366
7367         wiretest
7368 }
7369 run_test 58 "verify cross-platform wire constants =============="
7370
7371 test_59() {
7372         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7373
7374         echo "touch 130 files"
7375         createmany -o $DIR/f59- 130
7376         echo "rm 130 files"
7377         unlinkmany $DIR/f59- 130
7378         sync
7379         # wait for commitment of removal
7380         wait_delete_completed
7381 }
7382 run_test 59 "verify cancellation of llog records async ========="
7383
7384 TEST60_HEAD="test_60 run $RANDOM"
7385 test_60a() {
7386         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7387         remote_mgs_nodsh && skip "remote MGS with nodsh"
7388         do_facet mgs "! which run-llog.sh &> /dev/null" &&
7389                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
7390                         skip_env "missing subtest run-llog.sh"
7391
7392         log "$TEST60_HEAD - from kernel mode"
7393         do_facet mgs "$LCTL dk > /dev/null"
7394         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
7395         do_facet mgs $LCTL dk > $TMP/$tfile
7396
7397         # LU-6388: test llog_reader
7398         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
7399         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
7400         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
7401                         skip_env "missing llog_reader"
7402         local fstype=$(facet_fstype mgs)
7403         [ $fstype != ldiskfs -a $fstype != zfs ] &&
7404                 skip_env "Only for ldiskfs or zfs type mgs"
7405
7406         local mntpt=$(facet_mntpt mgs)
7407         local mgsdev=$(mgsdevname 1)
7408         local fid_list
7409         local fid
7410         local rec_list
7411         local rec
7412         local rec_type
7413         local obj_file
7414         local path
7415         local seq
7416         local oid
7417         local pass=true
7418
7419         #get fid and record list
7420         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
7421                 tail -n 4))
7422         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
7423                 tail -n 4))
7424         #remount mgs as ldiskfs or zfs type
7425         stop mgs || error "stop mgs failed"
7426         mount_fstype mgs || error "remount mgs failed"
7427         for ((i = 0; i < ${#fid_list[@]}; i++)); do
7428                 fid=${fid_list[i]}
7429                 rec=${rec_list[i]}
7430                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
7431                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
7432                 oid=$((16#$oid))
7433
7434                 case $fstype in
7435                         ldiskfs )
7436                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
7437                         zfs )
7438                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
7439                 esac
7440                 echo "obj_file is $obj_file"
7441                 do_facet mgs $llog_reader $obj_file
7442
7443                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
7444                         awk '{ print $3 }' | sed -e "s/^type=//g")
7445                 if [ $rec_type != $rec ]; then
7446                         echo "FAILED test_60a wrong record type $rec_type," \
7447                               "should be $rec"
7448                         pass=false
7449                         break
7450                 fi
7451
7452                 #check obj path if record type is LLOG_LOGID_MAGIC
7453                 if [ "$rec" == "1064553b" ]; then
7454                         path=$(do_facet mgs $llog_reader $obj_file |
7455                                 grep "path=" | awk '{ print $NF }' |
7456                                 sed -e "s/^path=//g")
7457                         if [ $obj_file != $mntpt/$path ]; then
7458                                 echo "FAILED test_60a wrong obj path" \
7459                                       "$montpt/$path, should be $obj_file"
7460                                 pass=false
7461                                 break
7462                         fi
7463                 fi
7464         done
7465         rm -f $TMP/$tfile
7466         #restart mgs before "error", otherwise it will block the next test
7467         stop mgs || error "stop mgs failed"
7468         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
7469         $pass || error "test failed, see FAILED test_60a messages for specifics"
7470 }
7471 run_test 60a "llog_test run from kernel module and test llog_reader"
7472
7473 test_60b() { # bug 6411
7474         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7475
7476         dmesg > $DIR/$tfile
7477         LLOG_COUNT=$(do_facet mgs dmesg |
7478                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
7479                           /llog_[a-z]*.c:[0-9]/ {
7480                                 if (marker)
7481                                         from_marker++
7482                                 from_begin++
7483                           }
7484                           END {
7485                                 if (marker)
7486                                         print from_marker
7487                                 else
7488                                         print from_begin
7489                           }")
7490
7491         [[ $LLOG_COUNT -gt 120 ]] &&
7492                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
7493 }
7494 run_test 60b "limit repeated messages from CERROR/CWARN"
7495
7496 test_60c() {
7497         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7498
7499         echo "create 5000 files"
7500         createmany -o $DIR/f60c- 5000
7501 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
7502         lctl set_param fail_loc=0x80000137
7503         unlinkmany $DIR/f60c- 5000
7504         lctl set_param fail_loc=0
7505 }
7506 run_test 60c "unlink file when mds full"
7507
7508 test_60d() {
7509         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7510
7511         SAVEPRINTK=$(lctl get_param -n printk)
7512         # verify "lctl mark" is even working"
7513         MESSAGE="test message ID $RANDOM $$"
7514         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7515         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
7516
7517         lctl set_param printk=0 || error "set lnet.printk failed"
7518         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
7519         MESSAGE="new test message ID $RANDOM $$"
7520         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
7521         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7522         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
7523
7524         lctl set_param -n printk="$SAVEPRINTK"
7525 }
7526 run_test 60d "test printk console message masking"
7527
7528 test_60e() {
7529         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7530         remote_mds_nodsh && skip "remote MDS with nodsh"
7531
7532         touch $DIR/$tfile
7533 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
7534         do_facet mds1 lctl set_param fail_loc=0x15b
7535         rm $DIR/$tfile
7536 }
7537 run_test 60e "no space while new llog is being created"
7538
7539 test_60g() {
7540         local pid
7541         local i
7542
7543         test_mkdir -c $MDSCOUNT $DIR/$tdir
7544
7545         (
7546                 local index=0
7547                 while true; do
7548                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
7549                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
7550                                 2>/dev/null
7551                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
7552                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
7553                         index=$((index + 1))
7554                 done
7555         ) &
7556
7557         pid=$!
7558
7559         for i in {0..100}; do
7560                 # define OBD_FAIL_OSD_TXN_START    0x19a
7561                 local index=$((i % MDSCOUNT + 1))
7562
7563                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
7564                         > /dev/null
7565                 usleep 100
7566         done
7567
7568         kill -9 $pid
7569
7570         for i in $(seq $MDSCOUNT); do
7571                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
7572         done
7573
7574         mkdir $DIR/$tdir/new || error "mkdir failed"
7575         rmdir $DIR/$tdir/new || error "rmdir failed"
7576
7577         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
7578                 -t namespace
7579         for i in $(seq $MDSCOUNT); do
7580                 wait_update_facet mds$i "$LCTL get_param -n \
7581                         mdd.$(facet_svc mds$i).lfsck_namespace |
7582                         awk '/^status/ { print \\\$2 }'" "completed"
7583         done
7584
7585         ls -R $DIR/$tdir || error "ls failed"
7586         rm -rf $DIR/$tdir || error "rmdir failed"
7587 }
7588 run_test 60g "transaction abort won't cause MDT hung"
7589
7590 test_60h() {
7591         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
7592                 skip "Need MDS version at least 2.12.52"
7593         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
7594
7595         local f
7596
7597         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
7598         #define OBD_FAIL_MDS_STRIPE_FID          0x189
7599         for fail_loc in 0x80000188 0x80000189; do
7600                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
7601                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
7602                         error "mkdir $dir-$fail_loc failed"
7603                 for i in {0..10}; do
7604                         # create may fail on missing stripe
7605                         echo $i > $DIR/$tdir-$fail_loc/$i
7606                 done
7607                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7608                         error "getdirstripe $tdir-$fail_loc failed"
7609                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
7610                         error "migrate $tdir-$fail_loc failed"
7611                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7612                         error "getdirstripe $tdir-$fail_loc failed"
7613                 pushd $DIR/$tdir-$fail_loc
7614                 for f in *; do
7615                         echo $f | cmp $f - || error "$f data mismatch"
7616                 done
7617                 popd
7618                 rm -rf $DIR/$tdir-$fail_loc
7619         done
7620 }
7621 run_test 60h "striped directory with missing stripes can be accessed"
7622
7623 test_61a() {
7624         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7625
7626         f="$DIR/f61"
7627         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
7628         cancel_lru_locks osc
7629         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
7630         sync
7631 }
7632 run_test 61a "mmap() writes don't make sync hang ================"
7633
7634 test_61b() {
7635         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
7636 }
7637 run_test 61b "mmap() of unstriped file is successful"
7638
7639 # bug 2330 - insufficient obd_match error checking causes LBUG
7640 test_62() {
7641         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7642
7643         f="$DIR/f62"
7644         echo foo > $f
7645         cancel_lru_locks osc
7646         lctl set_param fail_loc=0x405
7647         cat $f && error "cat succeeded, expect -EIO"
7648         lctl set_param fail_loc=0
7649 }
7650 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
7651 # match every page all of the time.
7652 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
7653
7654 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
7655 # Though this test is irrelevant anymore, it helped to reveal some
7656 # other grant bugs (LU-4482), let's keep it.
7657 test_63a() {   # was test_63
7658         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7659
7660         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
7661
7662         for i in `seq 10` ; do
7663                 dd if=/dev/zero of=$DIR/f63 bs=8k &
7664                 sleep 5
7665                 kill $!
7666                 sleep 1
7667         done
7668
7669         rm -f $DIR/f63 || true
7670 }
7671 run_test 63a "Verify oig_wait interruption does not crash ======="
7672
7673 # bug 2248 - async write errors didn't return to application on sync
7674 # bug 3677 - async write errors left page locked
7675 test_63b() {
7676         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7677
7678         debugsave
7679         lctl set_param debug=-1
7680
7681         # ensure we have a grant to do async writes
7682         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
7683         rm $DIR/$tfile
7684
7685         sync    # sync lest earlier test intercept the fail_loc
7686
7687         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
7688         lctl set_param fail_loc=0x80000406
7689         $MULTIOP $DIR/$tfile Owy && \
7690                 error "sync didn't return ENOMEM"
7691         sync; sleep 2; sync     # do a real sync this time to flush page
7692         lctl get_param -n llite.*.dump_page_cache | grep locked && \
7693                 error "locked page left in cache after async error" || true
7694         debugrestore
7695 }
7696 run_test 63b "async write errors should be returned to fsync ==="
7697
7698 test_64a () {
7699         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7700
7701         lfs df $DIR
7702         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
7703 }
7704 run_test 64a "verify filter grant calculations (in kernel) ====="
7705
7706 test_64b () {
7707         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7708
7709         sh oos.sh $MOUNT || error "oos.sh failed: $?"
7710 }
7711 run_test 64b "check out-of-space detection on client"
7712
7713 test_64c() {
7714         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
7715 }
7716 run_test 64c "verify grant shrink"
7717
7718 # this does exactly what osc_request.c:osc_announce_cached() does in
7719 # order to calculate max amount of grants to ask from server
7720 want_grant() {
7721         local tgt=$1
7722
7723         local nrpages=$($LCTL get_param -n osc.${tgt}.max_pages_per_rpc)
7724         local rpc_in_flight=$($LCTL get_param -n osc.${tgt}.max_rpcs_in_flight)
7725
7726         ((rpc_in_flight ++));
7727         nrpages=$((nrpages * rpc_in_flight))
7728
7729         local dirty_max_pages=$($LCTL get_param -n osc.${tgt}.max_dirty_mb)
7730
7731         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
7732
7733         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
7734         local undirty=$((nrpages * PAGE_SIZE))
7735
7736         local max_extent_pages
7737         max_extent_pages=$($LCTL get_param osc.${tgt}.import |
7738             grep grant_max_extent_size | awk '{print $2}')
7739         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
7740         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
7741         local grant_extent_tax
7742         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
7743             grep grant_extent_tax | awk '{print $2}')
7744
7745         undirty=$((undirty + nrextents * grant_extent_tax))
7746
7747         echo $undirty
7748 }
7749
7750 # this is size of unit for grant allocation. It should be equal to
7751 # what tgt_grant.c:tgt_grant_chunk() calculates
7752 grant_chunk() {
7753         local tgt=$1
7754         local max_brw_size
7755         local grant_extent_tax
7756
7757         max_brw_size=$($LCTL get_param osc.${tgt}.import |
7758             grep max_brw_size | awk '{print $2}')
7759
7760         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
7761             grep grant_extent_tax | awk '{print $2}')
7762
7763         echo $(((max_brw_size + grant_extent_tax) * 2))
7764 }
7765
7766 test_64d() {
7767         [ $OST1_VERSION -lt $(version_code 2.10.56) ] &&
7768                 skip "OST < 2.10.55 doesn't limit grants enough"
7769
7770         local tgt=$($LCTL dl | grep "0000-osc-[^mM]" | awk '{print $4}')
7771         local file=$DIR/$tfile
7772
7773         [[ $($LCTL get_param osc.${tgt}.import |
7774              grep "connect_flags:.*grant_param") ]] ||
7775                 skip "no grant_param connect flag"
7776
7777         local olddebug=$($LCTL get_param -n debug 2> /dev/null)
7778
7779         $LCTL set_param debug="$OLDDEBUG" 2> /dev/null || true
7780
7781         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
7782         stack_trap "rm -f $file" EXIT
7783
7784         $LFS setstripe $file -i 0 -c 1
7785         dd if=/dev/zero of=$file bs=1M count=1000 &
7786         ddpid=$!
7787
7788         while true
7789         do
7790                 local cur_grant=$($LCTL get_param -n osc.${tgt}.cur_grant_bytes)
7791                 if [[ $cur_grant -gt $max_cur_granted ]]
7792                 then
7793                         kill $ddpid
7794                         error "cur_grant $cur_grant > $max_cur_granted"
7795                 fi
7796                 kill -0 $ddpid
7797                 [[ $? -ne 0 ]] && break;
7798                 sleep 2
7799         done
7800
7801         rm -f $DIR/$tfile
7802         wait_delete_completed
7803         $LCTL set_param debug="$olddebug" 2> /dev/null || true
7804 }
7805 run_test 64d "check grant limit exceed"
7806
7807 # bug 1414 - set/get directories' stripe info
7808 test_65a() {
7809         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7810
7811         test_mkdir $DIR/$tdir
7812         touch $DIR/$tdir/f1
7813         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
7814 }
7815 run_test 65a "directory with no stripe info"
7816
7817 test_65b() {
7818         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7819
7820         test_mkdir $DIR/$tdir
7821         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7822
7823         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
7824                                                 error "setstripe"
7825         touch $DIR/$tdir/f2
7826         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
7827 }
7828 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
7829
7830 test_65c() {
7831         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7832         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
7833
7834         test_mkdir $DIR/$tdir
7835         local stripesize=$($LFS getstripe -S $DIR/$tdir)
7836
7837         $LFS setstripe -S $((stripesize * 4)) -i 1 \
7838                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
7839         touch $DIR/$tdir/f3
7840         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
7841 }
7842 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
7843
7844 test_65d() {
7845         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7846
7847         test_mkdir $DIR/$tdir
7848         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
7849         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7850
7851         if [[ $STRIPECOUNT -le 0 ]]; then
7852                 sc=1
7853         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
7854                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
7855                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
7856         else
7857                 sc=$(($STRIPECOUNT - 1))
7858         fi
7859         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
7860         touch $DIR/$tdir/f4 $DIR/$tdir/f5
7861         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
7862                 error "lverify failed"
7863 }
7864 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
7865
7866 test_65e() {
7867         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7868
7869         test_mkdir $DIR/$tdir
7870
7871         $LFS setstripe $DIR/$tdir || error "setstripe"
7872         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
7873                                         error "no stripe info failed"
7874         touch $DIR/$tdir/f6
7875         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
7876 }
7877 run_test 65e "directory setstripe defaults"
7878
7879 test_65f() {
7880         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7881
7882         test_mkdir $DIR/${tdir}f
7883         $RUNAS $LFS setstripe $DIR/${tdir}f &&
7884                 error "setstripe succeeded" || true
7885 }
7886 run_test 65f "dir setstripe permission (should return error) ==="
7887
7888 test_65g() {
7889         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7890
7891         test_mkdir $DIR/$tdir
7892         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7893
7894         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
7895                 error "setstripe -S failed"
7896         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
7897         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
7898                 error "delete default stripe failed"
7899 }
7900 run_test 65g "directory setstripe -d"
7901
7902 test_65h() {
7903         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7904
7905         test_mkdir $DIR/$tdir
7906         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7907
7908         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
7909                 error "setstripe -S failed"
7910         test_mkdir $DIR/$tdir/dd1
7911         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
7912                 error "stripe info inherit failed"
7913 }
7914 run_test 65h "directory stripe info inherit ===================="
7915
7916 test_65i() {
7917         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7918
7919         save_layout_restore_at_exit $MOUNT
7920
7921         # bug6367: set non-default striping on root directory
7922         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
7923
7924         # bug12836: getstripe on -1 default directory striping
7925         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
7926
7927         # bug12836: getstripe -v on -1 default directory striping
7928         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
7929
7930         # bug12836: new find on -1 default directory striping
7931         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
7932 }
7933 run_test 65i "various tests to set root directory striping"
7934
7935 test_65j() { # bug6367
7936         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7937
7938         sync; sleep 1
7939
7940         # if we aren't already remounting for each test, do so for this test
7941         if [ "$I_MOUNTED" = "yes" ]; then
7942                 cleanup || error "failed to unmount"
7943                 setup
7944         fi
7945
7946         save_layout_restore_at_exit $MOUNT
7947
7948         $LFS setstripe -d $MOUNT || error "setstripe failed"
7949 }
7950 run_test 65j "set default striping on root directory (bug 6367)="
7951
7952 cleanup_65k() {
7953         rm -rf $DIR/$tdir
7954         wait_delete_completed
7955         do_facet $SINGLEMDS "lctl set_param -n \
7956                 osp.$ost*MDT0000.max_create_count=$max_count"
7957         do_facet $SINGLEMDS "lctl set_param -n \
7958                 osp.$ost*MDT0000.create_count=$count"
7959         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
7960         echo $INACTIVE_OSC "is Activate"
7961
7962         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
7963 }
7964
7965 test_65k() { # bug11679
7966         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7967         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7968         remote_mds_nodsh && skip "remote MDS with nodsh"
7969
7970         local disable_precreate=true
7971         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
7972                 disable_precreate=false
7973
7974         echo "Check OST status: "
7975         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
7976                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
7977
7978         for OSC in $MDS_OSCS; do
7979                 echo $OSC "is active"
7980                 do_facet $SINGLEMDS lctl --device %$OSC activate
7981         done
7982
7983         for INACTIVE_OSC in $MDS_OSCS; do
7984                 local ost=$(osc_to_ost $INACTIVE_OSC)
7985                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
7986                                lov.*md*.target_obd |
7987                                awk -F: /$ost/'{ print $1 }' | head -n 1)
7988
7989                 mkdir -p $DIR/$tdir
7990                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
7991                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
7992
7993                 echo "Deactivate: " $INACTIVE_OSC
7994                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
7995
7996                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
7997                               osp.$ost*MDT0000.create_count")
7998                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
7999                                   osp.$ost*MDT0000.max_create_count")
8000                 $disable_precreate &&
8001                         do_facet $SINGLEMDS "lctl set_param -n \
8002                                 osp.$ost*MDT0000.max_create_count=0"
8003
8004                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
8005                         [ -f $DIR/$tdir/$idx ] && continue
8006                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
8007                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
8008                                 { cleanup_65k;
8009                                   error "setstripe $idx should succeed"; }
8010                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
8011                 done
8012                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
8013                 rmdir $DIR/$tdir
8014
8015                 do_facet $SINGLEMDS "lctl set_param -n \
8016                         osp.$ost*MDT0000.max_create_count=$max_count"
8017                 do_facet $SINGLEMDS "lctl set_param -n \
8018                         osp.$ost*MDT0000.create_count=$count"
8019                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8020                 echo $INACTIVE_OSC "is Activate"
8021
8022                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8023         done
8024 }
8025 run_test 65k "validate manual striping works properly with deactivated OSCs"
8026
8027 test_65l() { # bug 12836
8028         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8029
8030         test_mkdir -p $DIR/$tdir/test_dir
8031         $LFS setstripe -c -1 $DIR/$tdir/test_dir
8032         $LFS find -mtime -1 $DIR/$tdir >/dev/null
8033 }
8034 run_test 65l "lfs find on -1 stripe dir ========================"
8035
8036 test_65m() {
8037         local layout=$(save_layout $MOUNT)
8038         $RUNAS $LFS setstripe -c 2 $MOUNT && {
8039                 restore_layout $MOUNT $layout
8040                 error "setstripe should fail by non-root users"
8041         }
8042         true
8043 }
8044 run_test 65m "normal user can't set filesystem default stripe"
8045
8046 test_65n() {
8047         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
8048         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
8049                 skip "Need MDS version at least 2.12.50"
8050         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8051
8052         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8053         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
8054         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
8055
8056         local root_layout=$(save_layout $MOUNT)
8057         stack_trap "restore_layout $MOUNT $root_layout" EXIT
8058
8059         # new subdirectory under root directory should not inherit
8060         # the default layout from root
8061         local dir1=$MOUNT/$tdir-1
8062         mkdir $dir1 || error "mkdir $dir1 failed"
8063         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
8064                 error "$dir1 shouldn't have LOV EA"
8065
8066         # delete the default layout on root directory
8067         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
8068
8069         local dir2=$MOUNT/$tdir-2
8070         mkdir $dir2 || error "mkdir $dir2 failed"
8071         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
8072                 error "$dir2 shouldn't have LOV EA"
8073
8074         # set a new striping pattern on root directory
8075         local def_stripe_size=$($LFS getstripe -S $MOUNT)
8076         local new_def_stripe_size=$((def_stripe_size * 2))
8077         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
8078                 error "set stripe size on $MOUNT failed"
8079
8080         # new file created in $dir2 should inherit the new stripe size from
8081         # the filesystem default
8082         local file2=$dir2/$tfile-2
8083         touch $file2 || error "touch $file2 failed"
8084
8085         local file2_stripe_size=$($LFS getstripe -S $file2)
8086         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
8087                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
8088
8089         local dir3=$MOUNT/$tdir-3
8090         mkdir $dir3 || error "mkdir $dir3 failed"
8091         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
8092         # the root layout, which is the actual default layout that will be used
8093         # when new files are created in $dir3.
8094         local dir3_layout=$(get_layout_param $dir3)
8095         local root_dir_layout=$(get_layout_param $MOUNT)
8096         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
8097                 error "$dir3 should show the default layout from $MOUNT"
8098
8099         # set OST pool on root directory
8100         local pool=$TESTNAME
8101         pool_add $pool || error "add $pool failed"
8102         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8103                 error "add targets to $pool failed"
8104
8105         $LFS setstripe -p $pool $MOUNT ||
8106                 error "set OST pool on $MOUNT failed"
8107
8108         # new file created in $dir3 should inherit the pool from
8109         # the filesystem default
8110         local file3=$dir3/$tfile-3
8111         touch $file3 || error "touch $file3 failed"
8112
8113         local file3_pool=$($LFS getstripe -p $file3)
8114         [[ "$file3_pool" = "$pool" ]] ||
8115                 error "$file3 didn't inherit OST pool $pool"
8116
8117         local dir4=$MOUNT/$tdir-4
8118         mkdir $dir4 || error "mkdir $dir4 failed"
8119         local dir4_layout=$(get_layout_param $dir4)
8120         root_dir_layout=$(get_layout_param $MOUNT)
8121         echo "$LFS getstripe -d $dir4"
8122         $LFS getstripe -d $dir4
8123         echo "$LFS getstripe -d $MOUNT"
8124         $LFS getstripe -d $MOUNT
8125         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
8126                 error "$dir4 should show the default layout from $MOUNT"
8127
8128         # new file created in $dir4 should inherit the pool from
8129         # the filesystem default
8130         local file4=$dir4/$tfile-4
8131         touch $file4 || error "touch $file4 failed"
8132
8133         local file4_pool=$($LFS getstripe -p $file4)
8134         [[ "$file4_pool" = "$pool" ]] ||
8135                 error "$file4 didn't inherit OST pool $pool"
8136
8137         # new subdirectory under non-root directory should inherit
8138         # the default layout from its parent directory
8139         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
8140                 error "set directory layout on $dir4 failed"
8141
8142         local dir5=$dir4/$tdir-5
8143         mkdir $dir5 || error "mkdir $dir5 failed"
8144
8145         dir4_layout=$(get_layout_param $dir4)
8146         local dir5_layout=$(get_layout_param $dir5)
8147         [[ "$dir4_layout" = "$dir5_layout" ]] ||
8148                 error "$dir5 should inherit the default layout from $dir4"
8149
8150         # though subdir under ROOT doesn't inherit default layout, but
8151         # its sub dir/file should be created with default layout.
8152         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
8153         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
8154                 skip "Need MDS version at least 2.12.59"
8155
8156         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
8157         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
8158         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
8159
8160         if [ $default_lmv_hash == "none" ]; then
8161                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
8162         else
8163                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
8164                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
8165         fi
8166
8167         $LFS setdirstripe -D -c 2 $MOUNT ||
8168                 error "setdirstripe -D -c 2 failed"
8169         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
8170         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
8171         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
8172 }
8173 run_test 65n "don't inherit default layout from root for new subdirectories"
8174
8175 # bug 2543 - update blocks count on client
8176 test_66() {
8177         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8178
8179         COUNT=${COUNT:-8}
8180         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
8181         sync; sync_all_data; sync; sync_all_data
8182         cancel_lru_locks osc
8183         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
8184         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
8185 }
8186 run_test 66 "update inode blocks count on client ==============="
8187
8188 meminfo() {
8189         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
8190 }
8191
8192 swap_used() {
8193         swapon -s | awk '($1 == "'$1'") { print $4 }'
8194 }
8195
8196 # bug5265, obdfilter oa2dentry return -ENOENT
8197 # #define OBD_FAIL_SRV_ENOENT 0x217
8198 test_69() {
8199         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8200         remote_ost_nodsh && skip "remote OST with nodsh"
8201
8202         f="$DIR/$tfile"
8203         $LFS setstripe -c 1 -i 0 $f
8204
8205         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
8206
8207         do_facet ost1 lctl set_param fail_loc=0x217
8208         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
8209         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
8210
8211         do_facet ost1 lctl set_param fail_loc=0
8212         $DIRECTIO write $f 0 2 || error "write error"
8213
8214         cancel_lru_locks osc
8215         $DIRECTIO read $f 0 1 || error "read error"
8216
8217         do_facet ost1 lctl set_param fail_loc=0x217
8218         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
8219
8220         do_facet ost1 lctl set_param fail_loc=0
8221         rm -f $f
8222 }
8223 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
8224
8225 test_71() {
8226         test_mkdir $DIR/$tdir
8227         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
8228         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
8229 }
8230 run_test 71 "Running dbench on lustre (don't segment fault) ===="
8231
8232 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
8233         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8234         [ "$RUNAS_ID" = "$UID" ] &&
8235                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8236         # Check that testing environment is properly set up. Skip if not
8237         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
8238                 skip_env "User $RUNAS_ID does not exist - skipping"
8239
8240         touch $DIR/$tfile
8241         chmod 777 $DIR/$tfile
8242         chmod ug+s $DIR/$tfile
8243         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
8244                 error "$RUNAS dd $DIR/$tfile failed"
8245         # See if we are still setuid/sgid
8246         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8247                 error "S/gid is not dropped on write"
8248         # Now test that MDS is updated too
8249         cancel_lru_locks mdc
8250         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8251                 error "S/gid is not dropped on MDS"
8252         rm -f $DIR/$tfile
8253 }
8254 run_test 72a "Test that remove suid works properly (bug5695) ===="
8255
8256 test_72b() { # bug 24226 -- keep mode setting when size is not changing
8257         local perm
8258
8259         [ "$RUNAS_ID" = "$UID" ] &&
8260                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8261         [ "$RUNAS_ID" -eq 0 ] &&
8262                 skip_env "RUNAS_ID = 0 -- skipping"
8263         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8264         # Check that testing environment is properly set up. Skip if not
8265         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
8266                 skip_env "User $RUNAS_ID does not exist - skipping"
8267
8268         touch $DIR/${tfile}-f{g,u}
8269         test_mkdir $DIR/${tfile}-dg
8270         test_mkdir $DIR/${tfile}-du
8271         chmod 770 $DIR/${tfile}-{f,d}{g,u}
8272         chmod g+s $DIR/${tfile}-{f,d}g
8273         chmod u+s $DIR/${tfile}-{f,d}u
8274         for perm in 777 2777 4777; do
8275                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
8276                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
8277                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
8278                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
8279         done
8280         true
8281 }
8282 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
8283
8284 # bug 3462 - multiple simultaneous MDC requests
8285 test_73() {
8286         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8287
8288         test_mkdir $DIR/d73-1
8289         test_mkdir $DIR/d73-2
8290         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
8291         pid1=$!
8292
8293         lctl set_param fail_loc=0x80000129
8294         $MULTIOP $DIR/d73-1/f73-2 Oc &
8295         sleep 1
8296         lctl set_param fail_loc=0
8297
8298         $MULTIOP $DIR/d73-2/f73-3 Oc &
8299         pid3=$!
8300
8301         kill -USR1 $pid1
8302         wait $pid1 || return 1
8303
8304         sleep 25
8305
8306         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
8307         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
8308         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
8309
8310         rm -rf $DIR/d73-*
8311 }
8312 run_test 73 "multiple MDC requests (should not deadlock)"
8313
8314 test_74a() { # bug 6149, 6184
8315         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8316
8317         touch $DIR/f74a
8318         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8319         #
8320         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8321         # will spin in a tight reconnection loop
8322         $LCTL set_param fail_loc=0x8000030e
8323         # get any lock that won't be difficult - lookup works.
8324         ls $DIR/f74a
8325         $LCTL set_param fail_loc=0
8326         rm -f $DIR/f74a
8327         true
8328 }
8329 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
8330
8331 test_74b() { # bug 13310
8332         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8333
8334         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8335         #
8336         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8337         # will spin in a tight reconnection loop
8338         $LCTL set_param fail_loc=0x8000030e
8339         # get a "difficult" lock
8340         touch $DIR/f74b
8341         $LCTL set_param fail_loc=0
8342         rm -f $DIR/f74b
8343         true
8344 }
8345 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
8346
8347 test_74c() {
8348         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8349
8350         #define OBD_FAIL_LDLM_NEW_LOCK
8351         $LCTL set_param fail_loc=0x319
8352         touch $DIR/$tfile && error "touch successful"
8353         $LCTL set_param fail_loc=0
8354         true
8355 }
8356 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
8357
8358 num_inodes() {
8359         awk '/lustre_inode_cache/ {print $2; exit}' /proc/slabinfo
8360 }
8361
8362 test_76() { # Now for bug 20433, added originally in bug 1443
8363         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8364
8365         cancel_lru_locks osc
8366         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
8367         local before=$(num_inodes)
8368         local count=$((512 * cpus))
8369         [ "$SLOW" = "no" ] && count=$((64 * cpus))
8370
8371         echo "before inodes: $before"
8372         for i in $(seq $count); do
8373                 touch $DIR/$tfile
8374                 rm -f $DIR/$tfile
8375         done
8376         cancel_lru_locks osc
8377         local after=$(num_inodes)
8378         echo "after inodes: $after"
8379         while (( after > before + 8 * ${cpus:-1} )); do
8380                 sleep 1
8381                 after=$(num_inodes)
8382                 wait=$((wait + 1))
8383                 (( wait % 5 == 0 )) && echo "wait $wait seconds inodes: $after"
8384                 if (( wait > 30 )); then
8385                         error "inode slab grew from $before to $after"
8386                 fi
8387         done
8388 }
8389 run_test 76 "confirm clients recycle inodes properly ===="
8390
8391
8392 export ORIG_CSUM=""
8393 set_checksums()
8394 {
8395         # Note: in sptlrpc modes which enable its own bulk checksum, the
8396         # original crc32_le bulk checksum will be automatically disabled,
8397         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
8398         # will be checked by sptlrpc code against sptlrpc bulk checksum.
8399         # In this case set_checksums() will not be no-op, because sptlrpc
8400         # bulk checksum will be enabled all through the test.
8401
8402         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
8403         lctl set_param -n osc.*.checksums $1
8404         return 0
8405 }
8406
8407 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8408                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
8409 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8410                              tr -d [] | head -n1)}
8411 set_checksum_type()
8412 {
8413         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
8414         rc=$?
8415         log "set checksum type to $1, rc = $rc"
8416         return $rc
8417 }
8418
8419 get_osc_checksum_type()
8420 {
8421         # arugment 1: OST name, like OST0000
8422         ost=$1
8423         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
8424                         sed 's/.*\[\(.*\)\].*/\1/g')
8425         rc=$?
8426         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
8427         echo $checksum_type
8428 }
8429
8430 F77_TMP=$TMP/f77-temp
8431 F77SZ=8
8432 setup_f77() {
8433         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
8434                 error "error writing to $F77_TMP"
8435 }
8436
8437 test_77a() { # bug 10889
8438         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8439         $GSS && skip_env "could not run with gss"
8440
8441         [ ! -f $F77_TMP ] && setup_f77
8442         set_checksums 1
8443         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
8444         set_checksums 0
8445         rm -f $DIR/$tfile
8446 }
8447 run_test 77a "normal checksum read/write operation"
8448
8449 test_77b() { # bug 10889
8450         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8451         $GSS && skip_env "could not run with gss"
8452
8453         [ ! -f $F77_TMP ] && setup_f77
8454         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8455         $LCTL set_param fail_loc=0x80000409
8456         set_checksums 1
8457
8458         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8459                 error "dd error: $?"
8460         $LCTL set_param fail_loc=0
8461
8462         for algo in $CKSUM_TYPES; do
8463                 cancel_lru_locks osc
8464                 set_checksum_type $algo
8465                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8466                 $LCTL set_param fail_loc=0x80000408
8467                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
8468                 $LCTL set_param fail_loc=0
8469         done
8470         set_checksums 0
8471         set_checksum_type $ORIG_CSUM_TYPE
8472         rm -f $DIR/$tfile
8473 }
8474 run_test 77b "checksum error on client write, read"
8475
8476 cleanup_77c() {
8477         trap 0
8478         set_checksums 0
8479         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
8480         $check_ost &&
8481                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
8482         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
8483         $check_ost && [ -n "$ost_file_prefix" ] &&
8484                 do_facet ost1 rm -f ${ost_file_prefix}\*
8485 }
8486
8487 test_77c() {
8488         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8489         $GSS && skip_env "could not run with gss"
8490         remote_ost_nodsh && skip "remote OST with nodsh"
8491
8492         local bad1
8493         local osc_file_prefix
8494         local osc_file
8495         local check_ost=false
8496         local ost_file_prefix
8497         local ost_file
8498         local orig_cksum
8499         local dump_cksum
8500         local fid
8501
8502         # ensure corruption will occur on first OSS/OST
8503         $LFS setstripe -i 0 $DIR/$tfile
8504
8505         [ ! -f $F77_TMP ] && setup_f77
8506         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8507                 error "dd write error: $?"
8508         fid=$($LFS path2fid $DIR/$tfile)
8509
8510         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
8511         then
8512                 check_ost=true
8513                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
8514                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
8515         else
8516                 echo "OSS do not support bulk pages dump upon error"
8517         fi
8518
8519         osc_file_prefix=$($LCTL get_param -n debug_path)
8520         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
8521
8522         trap cleanup_77c EXIT
8523
8524         set_checksums 1
8525         # enable bulk pages dump upon error on Client
8526         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
8527         # enable bulk pages dump upon error on OSS
8528         $check_ost &&
8529                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
8530
8531         # flush Client cache to allow next read to reach OSS
8532         cancel_lru_locks osc
8533
8534         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
8535         $LCTL set_param fail_loc=0x80000408
8536         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
8537         $LCTL set_param fail_loc=0
8538
8539         rm -f $DIR/$tfile
8540
8541         # check cksum dump on Client
8542         osc_file=$(ls ${osc_file_prefix}*)
8543         [ -n "$osc_file" ] || error "no checksum dump file on Client"
8544         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
8545         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
8546         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
8547         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
8548                      cksum)
8549         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
8550         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8551                 error "dump content does not match on Client"
8552
8553         $check_ost || skip "No need to check cksum dump on OSS"
8554
8555         # check cksum dump on OSS
8556         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
8557         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
8558         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
8559         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
8560         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8561                 error "dump content does not match on OSS"
8562
8563         cleanup_77c
8564 }
8565 run_test 77c "checksum error on client read with debug"
8566
8567 test_77d() { # bug 10889
8568         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8569         $GSS && skip_env "could not run with gss"
8570
8571         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8572         $LCTL set_param fail_loc=0x80000409
8573         set_checksums 1
8574         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8575                 error "direct write: rc=$?"
8576         $LCTL set_param fail_loc=0
8577         set_checksums 0
8578
8579         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8580         $LCTL set_param fail_loc=0x80000408
8581         set_checksums 1
8582         cancel_lru_locks osc
8583         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8584                 error "direct read: rc=$?"
8585         $LCTL set_param fail_loc=0
8586         set_checksums 0
8587 }
8588 run_test 77d "checksum error on OST direct write, read"
8589
8590 test_77f() { # bug 10889
8591         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8592         $GSS && skip_env "could not run with gss"
8593
8594         set_checksums 1
8595         for algo in $CKSUM_TYPES; do
8596                 cancel_lru_locks osc
8597                 set_checksum_type $algo
8598                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8599                 $LCTL set_param fail_loc=0x409
8600                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
8601                         error "direct write succeeded"
8602                 $LCTL set_param fail_loc=0
8603         done
8604         set_checksum_type $ORIG_CSUM_TYPE
8605         set_checksums 0
8606 }
8607 run_test 77f "repeat checksum error on write (expect error)"
8608
8609 test_77g() { # bug 10889
8610         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8611         $GSS && skip_env "could not run with gss"
8612         remote_ost_nodsh && skip "remote OST with nodsh"
8613
8614         [ ! -f $F77_TMP ] && setup_f77
8615
8616         local file=$DIR/$tfile
8617         stack_trap "rm -f $file" EXIT
8618
8619         $LFS setstripe -c 1 -i 0 $file
8620         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
8621         do_facet ost1 lctl set_param fail_loc=0x8000021a
8622         set_checksums 1
8623         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
8624                 error "write error: rc=$?"
8625         do_facet ost1 lctl set_param fail_loc=0
8626         set_checksums 0
8627
8628         cancel_lru_locks osc
8629         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
8630         do_facet ost1 lctl set_param fail_loc=0x8000021b
8631         set_checksums 1
8632         cmp $F77_TMP $file || error "file compare failed"
8633         do_facet ost1 lctl set_param fail_loc=0
8634         set_checksums 0
8635 }
8636 run_test 77g "checksum error on OST write, read"
8637
8638 test_77k() { # LU-10906
8639         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8640         $GSS && skip_env "could not run with gss"
8641
8642         local cksum_param="osc.$FSNAME*.checksums"
8643         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
8644         local checksum
8645         local i
8646
8647         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
8648         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM" EXIT
8649         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM" \
8650                 EXIT
8651
8652         for i in 0 1; do
8653                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
8654                         error "failed to set checksum=$i on MGS"
8655                 wait_update $HOSTNAME "$get_checksum" $i
8656                 #remount
8657                 echo "remount client, checksum should be $i"
8658                 remount_client $MOUNT || error "failed to remount client"
8659                 checksum=$(eval $get_checksum)
8660                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
8661         done
8662         # remove persistent param to avoid races with checksum mountopt below
8663         do_facet mgs $LCTL set_param -P -d $cksum_param ||
8664                 error "failed to delete checksum on MGS"
8665
8666         for opt in "checksum" "nochecksum"; do
8667                 #remount with mount option
8668                 echo "remount client with option $opt, checksum should be $i"
8669                 umount_client $MOUNT || error "failed to umount client"
8670                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
8671                         error "failed to mount client with option '$opt'"
8672                 checksum=$(eval $get_checksum)
8673                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
8674                 i=$((i - 1))
8675         done
8676
8677         remount_client $MOUNT || error "failed to remount client"
8678 }
8679 run_test 77k "enable/disable checksum correctly"
8680
8681 test_77l() {
8682         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8683         $GSS && skip_env "could not run with gss"
8684
8685         set_checksums 1
8686         stack_trap "set_checksums $ORIG_CSUM" EXIT
8687         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
8688
8689         set_checksum_type invalid && error "unexpected success of invalid checksum type"
8690
8691         $LFS setstripe -c 1 -i 0 $DIR/$tfile
8692         for algo in $CKSUM_TYPES; do
8693                 set_checksum_type $algo || error "fail to set checksum type $algo"
8694                 osc_algo=$(get_osc_checksum_type OST0000)
8695                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
8696
8697                 # no locks, no reqs to let the connection idle
8698                 cancel_lru_locks osc
8699                 lru_resize_disable osc
8700                 wait_osc_import_state client ost1 IDLE
8701
8702                 # ensure ost1 is connected
8703                 stat $DIR/$tfile >/dev/null || error "can't stat"
8704                 wait_osc_import_state client ost1 FULL
8705
8706                 osc_algo=$(get_osc_checksum_type OST0000)
8707                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
8708         done
8709         return 0
8710 }
8711 run_test 77l "preferred checksum type is remembered after reconnected"
8712
8713 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
8714 rm -f $F77_TMP
8715 unset F77_TMP
8716
8717 cleanup_test_78() {
8718         trap 0
8719         rm -f $DIR/$tfile
8720 }
8721
8722 test_78() { # bug 10901
8723         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8724         remote_ost || skip_env "local OST"
8725
8726         NSEQ=5
8727         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
8728         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
8729         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
8730         echo "MemTotal: $MEMTOTAL"
8731
8732         # reserve 256MB of memory for the kernel and other running processes,
8733         # and then take 1/2 of the remaining memory for the read/write buffers.
8734         if [ $MEMTOTAL -gt 512 ] ;then
8735                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
8736         else
8737                 # for those poor memory-starved high-end clusters...
8738                 MEMTOTAL=$((MEMTOTAL / 2))
8739         fi
8740         echo "Mem to use for directio: $MEMTOTAL"
8741
8742         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
8743         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
8744         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
8745         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
8746                 head -n1)
8747         echo "Smallest OST: $SMALLESTOST"
8748         [[ $SMALLESTOST -lt 10240 ]] &&
8749                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
8750
8751         trap cleanup_test_78 EXIT
8752
8753         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
8754                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
8755
8756         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
8757         echo "File size: $F78SIZE"
8758         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
8759         for i in $(seq 1 $NSEQ); do
8760                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
8761                 echo directIO rdwr round $i of $NSEQ
8762                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
8763         done
8764
8765         cleanup_test_78
8766 }
8767 run_test 78 "handle large O_DIRECT writes correctly ============"
8768
8769 test_79() { # bug 12743
8770         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8771
8772         wait_delete_completed
8773
8774         BKTOTAL=$(calc_osc_kbytes kbytestotal)
8775         BKFREE=$(calc_osc_kbytes kbytesfree)
8776         BKAVAIL=$(calc_osc_kbytes kbytesavail)
8777
8778         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
8779         DFTOTAL=`echo $STRING | cut -d, -f1`
8780         DFUSED=`echo $STRING  | cut -d, -f2`
8781         DFAVAIL=`echo $STRING | cut -d, -f3`
8782         DFFREE=$(($DFTOTAL - $DFUSED))
8783
8784         ALLOWANCE=$((64 * $OSTCOUNT))
8785
8786         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
8787            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
8788                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
8789         fi
8790         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
8791            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
8792                 error "df free($DFFREE) mismatch OST free($BKFREE)"
8793         fi
8794         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
8795            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
8796                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
8797         fi
8798 }
8799 run_test 79 "df report consistency check ======================="
8800
8801 test_80() { # bug 10718
8802         remote_ost_nodsh && skip "remote OST with nodsh"
8803         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8804
8805         # relax strong synchronous semantics for slow backends like ZFS
8806         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
8807                 local soc="obdfilter.*.sync_lock_cancel"
8808                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
8809
8810                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
8811                 if [ -z "$save" ]; then
8812                         soc="obdfilter.*.sync_on_lock_cancel"
8813                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
8814                 fi
8815
8816                 if [ "$save" != "never" ]; then
8817                         local hosts=$(comma_list $(osts_nodes))
8818
8819                         do_nodes $hosts $LCTL set_param $soc=never
8820                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
8821                 fi
8822         fi
8823
8824         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
8825         sync; sleep 1; sync
8826         local before=$(date +%s)
8827         cancel_lru_locks osc
8828         local after=$(date +%s)
8829         local diff=$((after - before))
8830         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
8831
8832         rm -f $DIR/$tfile
8833 }
8834 run_test 80 "Page eviction is equally fast at high offsets too"
8835
8836 test_81a() { # LU-456
8837         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8838         remote_ost_nodsh && skip "remote OST with nodsh"
8839
8840         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
8841         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
8842         do_facet ost1 lctl set_param fail_loc=0x80000228
8843
8844         # write should trigger a retry and success
8845         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8846         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
8847         RC=$?
8848         if [ $RC -ne 0 ] ; then
8849                 error "write should success, but failed for $RC"
8850         fi
8851 }
8852 run_test 81a "OST should retry write when get -ENOSPC ==============="
8853
8854 test_81b() { # LU-456
8855         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8856         remote_ost_nodsh && skip "remote OST with nodsh"
8857
8858         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
8859         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
8860         do_facet ost1 lctl set_param fail_loc=0x228
8861
8862         # write should retry several times and return -ENOSPC finally
8863         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8864         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
8865         RC=$?
8866         ENOSPC=28
8867         if [ $RC -ne $ENOSPC ] ; then
8868                 error "dd should fail for -ENOSPC, but succeed."
8869         fi
8870 }
8871 run_test 81b "OST should return -ENOSPC when retry still fails ======="
8872
8873 test_82() { # LU-1031
8874         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10
8875         local gid1=14091995
8876         local gid2=16022000
8877
8878         multiop_bg_pause $DIR/$tfile OG${gid1}_g${gid1}c || return 1
8879         local MULTIPID1=$!
8880         multiop_bg_pause $DIR/$tfile O_G${gid2}r10g${gid2}c || return 2
8881         local MULTIPID2=$!
8882         kill -USR1 $MULTIPID2
8883         sleep 2
8884         if [[ `ps h -o comm -p $MULTIPID2` == "" ]]; then
8885                 error "First grouplock does not block second one"
8886         else
8887                 echo "Second grouplock blocks first one"
8888         fi
8889         kill -USR1 $MULTIPID1
8890         wait $MULTIPID1
8891         wait $MULTIPID2
8892 }
8893 run_test 82 "Basic grouplock test"
8894
8895 test_99() {
8896         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
8897
8898         test_mkdir $DIR/$tdir.cvsroot
8899         chown $RUNAS_ID $DIR/$tdir.cvsroot
8900
8901         cd $TMP
8902         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
8903
8904         cd /etc/init.d
8905         # some versions of cvs import exit(1) when asked to import links or
8906         # files they can't read.  ignore those files.
8907         local toignore=$(find . -type l -printf '-I %f\n' -o \
8908                          ! -perm /4 -printf '-I %f\n')
8909         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
8910                 $tdir.reposname vtag rtag
8911
8912         cd $DIR
8913         test_mkdir $DIR/$tdir.reposname
8914         chown $RUNAS_ID $DIR/$tdir.reposname
8915         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
8916
8917         cd $DIR/$tdir.reposname
8918         $RUNAS touch foo99
8919         $RUNAS cvs add -m 'addmsg' foo99
8920         $RUNAS cvs update
8921         $RUNAS cvs commit -m 'nomsg' foo99
8922         rm -fr $DIR/$tdir.cvsroot
8923 }
8924 run_test 99 "cvs strange file/directory operations"
8925
8926 test_100() {
8927         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8928         [[ "$NETTYPE" =~ tcp ]] ||
8929                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
8930         remote_ost_nodsh && skip "remote OST with nodsh"
8931         remote_mds_nodsh && skip "remote MDS with nodsh"
8932         remote_servers ||
8933                 skip "useless for local single node setup"
8934
8935         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
8936                 [ "$PROT" != "tcp" ] && continue
8937                 RPORT=$(echo $REMOTE | cut -d: -f2)
8938                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
8939
8940                 rc=0
8941                 LPORT=`echo $LOCAL | cut -d: -f2`
8942                 if [ $LPORT -ge 1024 ]; then
8943                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
8944                         netstat -tna
8945                         error_exit "local: $LPORT > 1024, remote: $RPORT"
8946                 fi
8947         done
8948         [ "$rc" = 0 ] || error_exit "privileged port not found" )
8949 }
8950 run_test 100 "check local port using privileged port ==========="
8951
8952 function get_named_value()
8953 {
8954     local tag
8955
8956     tag=$1
8957     while read ;do
8958         line=$REPLY
8959         case $line in
8960         $tag*)
8961             echo $line | sed "s/^$tag[ ]*//"
8962             break
8963             ;;
8964         esac
8965     done
8966 }
8967
8968 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
8969                    awk '/^max_cached_mb/ { print $2 }')
8970
8971 cleanup_101a() {
8972         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
8973         trap 0
8974 }
8975
8976 test_101a() {
8977         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8978
8979         local s
8980         local discard
8981         local nreads=10000
8982         local cache_limit=32
8983
8984         $LCTL set_param -n osc.*-osc*.rpc_stats 0
8985         trap cleanup_101a EXIT
8986         $LCTL set_param -n llite.*.read_ahead_stats 0
8987         $LCTL set_param -n llite.*.max_cached_mb $cache_limit
8988
8989         #
8990         # randomly read 10000 of 64K chunks from file 3x 32MB in size
8991         #
8992         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
8993         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
8994
8995         discard=0
8996         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
8997                 get_named_value 'read but discarded' | cut -d" " -f1); do
8998                         discard=$(($discard + $s))
8999         done
9000         cleanup_101a
9001
9002         $LCTL get_param osc.*-osc*.rpc_stats
9003         $LCTL get_param llite.*.read_ahead_stats
9004
9005         # Discard is generally zero, but sometimes a few random reads line up
9006         # and trigger larger readahead, which is wasted & leads to discards.
9007         if [[ $(($discard)) -gt $nreads ]]; then
9008                 error "too many ($discard) discarded pages"
9009         fi
9010         rm -f $DIR/$tfile || true
9011 }
9012 run_test 101a "check read-ahead for random reads"
9013
9014 setup_test101bc() {
9015         test_mkdir $DIR/$tdir
9016         local ssize=$1
9017         local FILE_LENGTH=$2
9018         STRIPE_OFFSET=0
9019
9020         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
9021
9022         local list=$(comma_list $(osts_nodes))
9023         set_osd_param $list '' read_cache_enable 0
9024         set_osd_param $list '' writethrough_cache_enable 0
9025
9026         trap cleanup_test101bc EXIT
9027         # prepare the read-ahead file
9028         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
9029
9030         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
9031                                 count=$FILE_SIZE_MB 2> /dev/null
9032
9033 }
9034
9035 cleanup_test101bc() {
9036         trap 0
9037         rm -rf $DIR/$tdir
9038         rm -f $DIR/$tfile
9039
9040         local list=$(comma_list $(osts_nodes))
9041         set_osd_param $list '' read_cache_enable 1
9042         set_osd_param $list '' writethrough_cache_enable 1
9043 }
9044
9045 calc_total() {
9046         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
9047 }
9048
9049 ra_check_101() {
9050         local READ_SIZE=$1
9051         local STRIPE_SIZE=$2
9052         local FILE_LENGTH=$3
9053         local RA_INC=1048576
9054         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
9055         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
9056                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
9057         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
9058                         get_named_value 'read but discarded' |
9059                         cut -d" " -f1 | calc_total)
9060         if [[ $DISCARD -gt $discard_limit ]]; then
9061                 $LCTL get_param llite.*.read_ahead_stats
9062                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
9063         else
9064                 echo "Read-ahead success for size ${READ_SIZE}"
9065         fi
9066 }
9067
9068 test_101b() {
9069         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9070         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9071
9072         local STRIPE_SIZE=1048576
9073         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
9074
9075         if [ $SLOW == "yes" ]; then
9076                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
9077         else
9078                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
9079         fi
9080
9081         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
9082
9083         # prepare the read-ahead file
9084         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9085         cancel_lru_locks osc
9086         for BIDX in 2 4 8 16 32 64 128 256
9087         do
9088                 local BSIZE=$((BIDX*4096))
9089                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
9090                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
9091                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
9092                 $LCTL set_param -n llite.*.read_ahead_stats 0
9093                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
9094                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
9095                 cancel_lru_locks osc
9096                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
9097         done
9098         cleanup_test101bc
9099         true
9100 }
9101 run_test 101b "check stride-io mode read-ahead ================="
9102
9103 test_101c() {
9104         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9105
9106         local STRIPE_SIZE=1048576
9107         local FILE_LENGTH=$((STRIPE_SIZE*100))
9108         local nreads=10000
9109         local rsize=65536
9110         local osc_rpc_stats
9111
9112         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9113
9114         cancel_lru_locks osc
9115         $LCTL set_param osc.*.rpc_stats 0
9116         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
9117         $LCTL get_param osc.*.rpc_stats
9118         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
9119                 local stats=$($LCTL get_param -n $osc_rpc_stats)
9120                 local lines=$(echo "$stats" | awk 'END {print NR;}')
9121                 local size
9122
9123                 if [ $lines -le 20 ]; then
9124                         echo "continue debug"
9125                         continue
9126                 fi
9127                 for size in 1 2 4 8; do
9128                         local rpc=$(echo "$stats" |
9129                                     awk '($1 == "'$size':") {print $2; exit; }')
9130                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
9131                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
9132                 done
9133                 echo "$osc_rpc_stats check passed!"
9134         done
9135         cleanup_test101bc
9136         true
9137 }
9138 run_test 101c "check stripe_size aligned read-ahead ================="
9139
9140 test_101d() {
9141         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9142
9143         local file=$DIR/$tfile
9144         local sz_MB=${FILESIZE_101d:-80}
9145         local ra_MB=${READAHEAD_MB:-40}
9146
9147         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
9148         [ $free_MB -lt $sz_MB ] &&
9149                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
9150
9151         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
9152         $LFS setstripe -c -1 $file || error "setstripe failed"
9153
9154         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
9155         echo Cancel LRU locks on lustre client to flush the client cache
9156         cancel_lru_locks osc
9157
9158         echo Disable read-ahead
9159         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9160         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9161         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_RA" EXIT
9162         $LCTL get_param -n llite.*.max_read_ahead_mb
9163
9164         echo Reading the test file $file with read-ahead disabled
9165         local sz_KB=$((sz_MB * 1024 / 4))
9166         local raOFF=$(do_and_time "dd if=$file of=/dev/null bs=4k count=$sz_KB")
9167
9168         echo Cancel LRU locks on lustre client to flush the client cache
9169         cancel_lru_locks osc
9170         echo Enable read-ahead with ${ra_MB}MB
9171         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
9172
9173         echo Reading the test file $file with read-ahead enabled
9174         local raON=$(do_and_time "dd if=$file of=/dev/null bs=4k count=$sz_KB")
9175
9176         echo "read-ahead disabled time read $raOFF"
9177         echo "read-ahead enabled time read $raON"
9178
9179         rm -f $file
9180         wait_delete_completed
9181
9182         [ $raOFF -le 1 ] || [ $raON -lt $raOFF ] ||
9183                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
9184 }
9185 run_test 101d "file read with and without read-ahead enabled"
9186
9187 test_101e() {
9188         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9189
9190         local file=$DIR/$tfile
9191         local size_KB=500  #KB
9192         local count=100
9193         local bsize=1024
9194
9195         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
9196         local need_KB=$((count * size_KB))
9197         [[ $free_KB -le $need_KB ]] &&
9198                 skip_env "Need free space $need_KB, have $free_KB"
9199
9200         echo "Creating $count ${size_KB}K test files"
9201         for ((i = 0; i < $count; i++)); do
9202                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
9203         done
9204
9205         echo "Cancel LRU locks on lustre client to flush the client cache"
9206         cancel_lru_locks $OSC
9207
9208         echo "Reset readahead stats"
9209         $LCTL set_param -n llite.*.read_ahead_stats 0
9210
9211         for ((i = 0; i < $count; i++)); do
9212                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
9213         done
9214
9215         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9216                      get_named_value 'misses' | cut -d" " -f1 | calc_total)
9217
9218         for ((i = 0; i < $count; i++)); do
9219                 rm -rf $file.$i 2>/dev/null
9220         done
9221
9222         #10000 means 20% reads are missing in readahead
9223         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
9224 }
9225 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
9226
9227 test_101f() {
9228         which iozone || skip_env "no iozone installed"
9229
9230         local old_debug=$($LCTL get_param debug)
9231         old_debug=${old_debug#*=}
9232         $LCTL set_param debug="reada mmap"
9233
9234         # create a test file
9235         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
9236
9237         echo Cancel LRU locks on lustre client to flush the client cache
9238         cancel_lru_locks osc
9239
9240         echo Reset readahead stats
9241         $LCTL set_param -n llite.*.read_ahead_stats 0
9242
9243         echo mmap read the file with small block size
9244         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
9245                 > /dev/null 2>&1
9246
9247         echo checking missing pages
9248         $LCTL get_param llite.*.read_ahead_stats
9249         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9250                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9251
9252         $LCTL set_param debug="$old_debug"
9253         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
9254         rm -f $DIR/$tfile
9255 }
9256 run_test 101f "check mmap read performance"
9257
9258 test_101g_brw_size_test() {
9259         local mb=$1
9260         local pages=$((mb * 1048576 / PAGE_SIZE))
9261         local file=$DIR/$tfile
9262
9263         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
9264                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
9265         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
9266                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
9267                         return 2
9268         done
9269
9270         stack_trap "rm -f $file" EXIT
9271         $LCTL set_param -n osc.*.rpc_stats=0
9272
9273         # 10 RPCs should be enough for the test
9274         local count=10
9275         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
9276                 { error "dd write ${mb} MB blocks failed"; return 3; }
9277         cancel_lru_locks osc
9278         dd of=/dev/null if=$file bs=${mb}M count=$count ||
9279                 { error "dd write ${mb} MB blocks failed"; return 4; }
9280
9281         # calculate number of full-sized read and write RPCs
9282         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
9283                 sed -n '/pages per rpc/,/^$/p' |
9284                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
9285                 END { print reads,writes }'))
9286         [ ${rpcs[0]} -ne $count ] && error "${rpcs[0]} != $count read RPCs" &&
9287                 return 5
9288         [ ${rpcs[1]} -ne $count ] && error "${rpcs[1]} != $count write RPCs" &&
9289                 return 6
9290
9291         return 0
9292 }
9293
9294 test_101g() {
9295         remote_ost_nodsh && skip "remote OST with nodsh"
9296
9297         local rpcs
9298         local osts=$(get_facets OST)
9299         local list=$(comma_list $(osts_nodes))
9300         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9301         local brw_size="obdfilter.*.brw_size"
9302
9303         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9304
9305         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
9306
9307         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
9308                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
9309                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
9310            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
9311                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
9312                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
9313
9314                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
9315                         suffix="M"
9316
9317                 if [[ $orig_mb -lt 16 ]]; then
9318                         save_lustre_params $osts "$brw_size" > $p
9319                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
9320                                 error "set 16MB RPC size failed"
9321
9322                         echo "remount client to enable new RPC size"
9323                         remount_client $MOUNT || error "remount_client failed"
9324                 fi
9325
9326                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
9327                 # should be able to set brw_size=12, but no rpc_stats for that
9328                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
9329         fi
9330
9331         test_101g_brw_size_test 4 || error "4MB RPC test failed"
9332
9333         if [[ $orig_mb -lt 16 ]]; then
9334                 restore_lustre_params < $p
9335                 remount_client $MOUNT || error "remount_client restore failed"
9336         fi
9337
9338         rm -f $p $DIR/$tfile
9339 }
9340 run_test 101g "Big bulk(4/16 MiB) readahead"
9341
9342 test_101h() {
9343         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9344
9345         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
9346                 error "dd 70M file failed"
9347         echo Cancel LRU locks on lustre client to flush the client cache
9348         cancel_lru_locks osc
9349
9350         echo "Reset readahead stats"
9351         $LCTL set_param -n llite.*.read_ahead_stats 0
9352
9353         echo "Read 10M of data but cross 64M bundary"
9354         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
9355         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9356                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9357         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
9358         rm -f $p $DIR/$tfile
9359 }
9360 run_test 101h "Readahead should cover current read window"
9361
9362 test_101i() {
9363         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
9364                 error "dd 10M file failed"
9365
9366         local max_per_file_mb=$($LCTL get_param -n \
9367                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
9368         cancel_lru_locks osc
9369         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
9370         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
9371                 error "set max_read_ahead_per_file_mb to 1 failed"
9372
9373         echo "Reset readahead stats"
9374         $LCTL set_param llite.*.read_ahead_stats=0
9375
9376         dd if=$DIR/$tfile of=/dev/null bs=2M
9377
9378         $LCTL get_param llite.*.read_ahead_stats
9379         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9380                      awk '/misses/ { print $2 }')
9381         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
9382         rm -f $DIR/$tfile
9383 }
9384 run_test 101i "allow current readahead to exceed reservation"
9385
9386 test_101j() {
9387         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
9388                 error "setstripe $DIR/$tfile failed"
9389         local file_size=$((1048576 * 16))
9390         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9391         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
9392
9393         echo Disable read-ahead
9394         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9395
9396         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
9397         for blk in $PAGE_SIZE 1048576 $file_size; do
9398                 cancel_lru_locks osc
9399                 echo "Reset readahead stats"
9400                 $LCTL set_param -n llite.*.read_ahead_stats=0
9401                 local count=$(($file_size / $blk))
9402                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
9403                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9404                              get_named_value 'failed to fast read' |
9405                              cut -d" " -f1 | calc_total)
9406                 $LCTL get_param -n llite.*.read_ahead_stats
9407                 [ $miss -eq $count ] || error "expected $count got $miss"
9408         done
9409
9410         rm -f $p $DIR/$tfile
9411 }
9412 run_test 101j "A complete read block should be submitted when no RA"
9413
9414 setup_test102() {
9415         test_mkdir $DIR/$tdir
9416         chown $RUNAS_ID $DIR/$tdir
9417         STRIPE_SIZE=65536
9418         STRIPE_OFFSET=1
9419         STRIPE_COUNT=$OSTCOUNT
9420         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
9421
9422         trap cleanup_test102 EXIT
9423         cd $DIR
9424         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
9425         cd $DIR/$tdir
9426         for num in 1 2 3 4; do
9427                 for count in $(seq 1 $STRIPE_COUNT); do
9428                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
9429                                 local size=`expr $STRIPE_SIZE \* $num`
9430                                 local file=file"$num-$idx-$count"
9431                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
9432                         done
9433                 done
9434         done
9435
9436         cd $DIR
9437         $1 tar cf $TMP/f102.tar $tdir --xattrs
9438 }
9439
9440 cleanup_test102() {
9441         trap 0
9442         rm -f $TMP/f102.tar
9443         rm -rf $DIR/d0.sanity/d102
9444 }
9445
9446 test_102a() {
9447         [ "$UID" != 0 ] && skip "must run as root"
9448         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
9449                 skip_env "must have user_xattr"
9450
9451         [ -z "$(which setfattr 2>/dev/null)" ] &&
9452                 skip_env "could not find setfattr"
9453
9454         local testfile=$DIR/$tfile
9455
9456         touch $testfile
9457         echo "set/get xattr..."
9458         setfattr -n trusted.name1 -v value1 $testfile ||
9459                 error "setfattr -n trusted.name1=value1 $testfile failed"
9460         getfattr -n trusted.name1 $testfile 2> /dev/null |
9461           grep "trusted.name1=.value1" ||
9462                 error "$testfile missing trusted.name1=value1"
9463
9464         setfattr -n user.author1 -v author1 $testfile ||
9465                 error "setfattr -n user.author1=author1 $testfile failed"
9466         getfattr -n user.author1 $testfile 2> /dev/null |
9467           grep "user.author1=.author1" ||
9468                 error "$testfile missing trusted.author1=author1"
9469
9470         echo "listxattr..."
9471         setfattr -n trusted.name2 -v value2 $testfile ||
9472                 error "$testfile unable to set trusted.name2"
9473         setfattr -n trusted.name3 -v value3 $testfile ||
9474                 error "$testfile unable to set trusted.name3"
9475         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
9476             grep "trusted.name" | wc -l) -eq 3 ] ||
9477                 error "$testfile missing 3 trusted.name xattrs"
9478
9479         setfattr -n user.author2 -v author2 $testfile ||
9480                 error "$testfile unable to set user.author2"
9481         setfattr -n user.author3 -v author3 $testfile ||
9482                 error "$testfile unable to set user.author3"
9483         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
9484             grep "user.author" | wc -l) -eq 3 ] ||
9485                 error "$testfile missing 3 user.author xattrs"
9486
9487         echo "remove xattr..."
9488         setfattr -x trusted.name1 $testfile ||
9489                 error "$testfile error deleting trusted.name1"
9490         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
9491                 error "$testfile did not delete trusted.name1 xattr"
9492
9493         setfattr -x user.author1 $testfile ||
9494                 error "$testfile error deleting user.author1"
9495         echo "set lustre special xattr ..."
9496         $LFS setstripe -c1 $testfile
9497         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
9498                 awk -F "=" '/trusted.lov/ { print $2 }' )
9499         setfattr -n "trusted.lov" -v $lovea $testfile ||
9500                 error "$testfile doesn't ignore setting trusted.lov again"
9501         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
9502                 error "$testfile allow setting invalid trusted.lov"
9503         rm -f $testfile
9504 }
9505 run_test 102a "user xattr test =================================="
9506
9507 test_102b() {
9508         [ -z "$(which setfattr 2>/dev/null)" ] &&
9509                 skip_env "could not find setfattr"
9510         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9511
9512         # b10930: get/set/list trusted.lov xattr
9513         echo "get/set/list trusted.lov xattr ..."
9514         local testfile=$DIR/$tfile
9515         $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
9516                 error "setstripe failed"
9517         local STRIPECOUNT=$($LFS getstripe -c $testfile) ||
9518                 error "getstripe failed"
9519         getfattr -d -m "^trusted" $testfile 2>/dev/null | grep "trusted.lov" ||
9520                 error "can't get trusted.lov from $testfile"
9521
9522         local testfile2=${testfile}2
9523         local value=$(getfattr -n trusted.lov $testfile 2>/dev/null |
9524                         grep "trusted.lov" | sed -e 's/[^=]\+=//')
9525
9526         $MCREATE $testfile2
9527         setfattr -n trusted.lov -v $value $testfile2
9528         local stripe_size=$($LFS getstripe -S $testfile2)
9529         local stripe_count=$($LFS getstripe -c $testfile2)
9530         [[ $stripe_size -eq 65536 ]] ||
9531                 error "stripe size $stripe_size != 65536"
9532         [[ $stripe_count -eq $STRIPECOUNT ]] ||
9533                 error "stripe count $stripe_count != $STRIPECOUNT"
9534         rm -f $DIR/$tfile
9535 }
9536 run_test 102b "getfattr/setfattr for trusted.lov EAs ============"
9537
9538 test_102c() {
9539         [ -z "$(which setfattr 2>/dev/null)" ] &&
9540                 skip_env "could not find setfattr"
9541         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9542
9543         # b10930: get/set/list lustre.lov xattr
9544         echo "get/set/list lustre.lov xattr ..."
9545         test_mkdir $DIR/$tdir
9546         chown $RUNAS_ID $DIR/$tdir
9547         local testfile=$DIR/$tdir/$tfile
9548         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
9549                 error "setstripe failed"
9550         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
9551                 error "getstripe failed"
9552         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
9553         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
9554
9555         local testfile2=${testfile}2
9556         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
9557                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
9558
9559         $RUNAS $MCREATE $testfile2
9560         $RUNAS setfattr -n lustre.lov -v $value $testfile2
9561         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
9562         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
9563         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
9564         [ $stripe_count -eq $STRIPECOUNT ] ||
9565                 error "stripe count $stripe_count != $STRIPECOUNT"
9566 }
9567 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
9568
9569 compare_stripe_info1() {
9570         local stripe_index_all_zero=true
9571
9572         for num in 1 2 3 4; do
9573                 for count in $(seq 1 $STRIPE_COUNT); do
9574                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
9575                                 local size=$((STRIPE_SIZE * num))
9576                                 local file=file"$num-$offset-$count"
9577                                 stripe_size=$($LFS getstripe -S $PWD/$file)
9578                                 [[ $stripe_size -ne $size ]] &&
9579                                     error "$file: size $stripe_size != $size"
9580                                 stripe_count=$($LFS getstripe -c $PWD/$file)
9581                                 # allow fewer stripes to be created, ORI-601
9582                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
9583                                     error "$file: count $stripe_count != $count"
9584                                 stripe_index=$($LFS getstripe -i $PWD/$file)
9585                                 [[ $stripe_index -ne 0 ]] &&
9586                                         stripe_index_all_zero=false
9587                         done
9588                 done
9589         done
9590         $stripe_index_all_zero &&
9591                 error "all files are being extracted starting from OST index 0"
9592         return 0
9593 }
9594
9595 have_xattrs_include() {
9596         tar --help | grep -q xattrs-include &&
9597                 echo --xattrs-include="lustre.*"
9598 }
9599
9600 test_102d() {
9601         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9602         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9603
9604         XINC=$(have_xattrs_include)
9605         setup_test102
9606         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
9607         cd $DIR/$tdir/$tdir
9608         compare_stripe_info1
9609 }
9610 run_test 102d "tar restore stripe info from tarfile,not keep osts"
9611
9612 test_102f() {
9613         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9614         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9615
9616         XINC=$(have_xattrs_include)
9617         setup_test102
9618         test_mkdir $DIR/$tdir.restore
9619         cd $DIR
9620         tar cf - --xattrs $tdir | tar xf - \
9621                 -C $DIR/$tdir.restore --xattrs $XINC
9622         cd $DIR/$tdir.restore/$tdir
9623         compare_stripe_info1
9624 }
9625 run_test 102f "tar copy files, not keep osts"
9626
9627 grow_xattr() {
9628         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
9629                 skip "must have user_xattr"
9630         [ -z "$(which setfattr 2>/dev/null)" ] &&
9631                 skip_env "could not find setfattr"
9632         [ -z "$(which getfattr 2>/dev/null)" ] &&
9633                 skip_env "could not find getfattr"
9634
9635         local xsize=${1:-1024}  # in bytes
9636         local file=$DIR/$tfile
9637         local value="$(generate_string $xsize)"
9638         local xbig=trusted.big
9639         local toobig=$2
9640
9641         touch $file
9642         log "save $xbig on $file"
9643         if [ -z "$toobig" ]
9644         then
9645                 setfattr -n $xbig -v $value $file ||
9646                         error "saving $xbig on $file failed"
9647         else
9648                 setfattr -n $xbig -v $value $file &&
9649                         error "saving $xbig on $file succeeded"
9650                 return 0
9651         fi
9652
9653         local orig=$(get_xattr_value $xbig $file)
9654         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
9655
9656         local xsml=trusted.sml
9657         log "save $xsml on $file"
9658         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
9659
9660         local new=$(get_xattr_value $xbig $file)
9661         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
9662
9663         log "grow $xsml on $file"
9664         setfattr -n $xsml -v "$value" $file ||
9665                 error "growing $xsml on $file failed"
9666
9667         new=$(get_xattr_value $xbig $file)
9668         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
9669         log "$xbig still valid after growing $xsml"
9670
9671         rm -f $file
9672 }
9673
9674 test_102h() { # bug 15777
9675         grow_xattr 1024
9676 }
9677 run_test 102h "grow xattr from inside inode to external block"
9678
9679 test_102ha() {
9680         large_xattr_enabled || skip_env "ea_inode feature disabled"
9681
9682         echo "setting xattr of max xattr size: $(max_xattr_size)"
9683         grow_xattr $(max_xattr_size)
9684
9685         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
9686         echo "This should fail:"
9687         grow_xattr $(($(max_xattr_size) + 10)) 1
9688 }
9689 run_test 102ha "grow xattr from inside inode to external inode"
9690
9691 test_102i() { # bug 17038
9692         [ -z "$(which getfattr 2>/dev/null)" ] &&
9693                 skip "could not find getfattr"
9694
9695         touch $DIR/$tfile
9696         ln -s $DIR/$tfile $DIR/${tfile}link
9697         getfattr -n trusted.lov $DIR/$tfile ||
9698                 error "lgetxattr on $DIR/$tfile failed"
9699         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
9700                 grep -i "no such attr" ||
9701                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
9702         rm -f $DIR/$tfile $DIR/${tfile}link
9703 }
9704 run_test 102i "lgetxattr test on symbolic link ============"
9705
9706 test_102j() {
9707         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9708         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9709
9710         XINC=$(have_xattrs_include)
9711         setup_test102 "$RUNAS"
9712         chown $RUNAS_ID $DIR/$tdir
9713         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
9714         cd $DIR/$tdir/$tdir
9715         compare_stripe_info1 "$RUNAS"
9716 }
9717 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
9718
9719 test_102k() {
9720         [ -z "$(which setfattr 2>/dev/null)" ] &&
9721                 skip "could not find setfattr"
9722
9723         touch $DIR/$tfile
9724         # b22187 just check that does not crash for regular file.
9725         setfattr -n trusted.lov $DIR/$tfile
9726         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
9727         local test_kdir=$DIR/$tdir
9728         test_mkdir $test_kdir
9729         local default_size=$($LFS getstripe -S $test_kdir)
9730         local default_count=$($LFS getstripe -c $test_kdir)
9731         local default_offset=$($LFS getstripe -i $test_kdir)
9732         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
9733                 error 'dir setstripe failed'
9734         setfattr -n trusted.lov $test_kdir
9735         local stripe_size=$($LFS getstripe -S $test_kdir)
9736         local stripe_count=$($LFS getstripe -c $test_kdir)
9737         local stripe_offset=$($LFS getstripe -i $test_kdir)
9738         [ $stripe_size -eq $default_size ] ||
9739                 error "stripe size $stripe_size != $default_size"
9740         [ $stripe_count -eq $default_count ] ||
9741                 error "stripe count $stripe_count != $default_count"
9742         [ $stripe_offset -eq $default_offset ] ||
9743                 error "stripe offset $stripe_offset != $default_offset"
9744         rm -rf $DIR/$tfile $test_kdir
9745 }
9746 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
9747
9748 test_102l() {
9749         [ -z "$(which getfattr 2>/dev/null)" ] &&
9750                 skip "could not find getfattr"
9751
9752         # LU-532 trusted. xattr is invisible to non-root
9753         local testfile=$DIR/$tfile
9754
9755         touch $testfile
9756
9757         echo "listxattr as user..."
9758         chown $RUNAS_ID $testfile
9759         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
9760             grep -q "trusted" &&
9761                 error "$testfile trusted xattrs are user visible"
9762
9763         return 0;
9764 }
9765 run_test 102l "listxattr size test =================================="
9766
9767 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
9768         local path=$DIR/$tfile
9769         touch $path
9770
9771         listxattr_size_check $path || error "listattr_size_check $path failed"
9772 }
9773 run_test 102m "Ensure listxattr fails on small bufffer ========"
9774
9775 cleanup_test102
9776
9777 getxattr() { # getxattr path name
9778         # Return the base64 encoding of the value of xattr name on path.
9779         local path=$1
9780         local name=$2
9781
9782         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
9783         # file: $path
9784         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
9785         #
9786         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
9787
9788         getfattr --absolute-names --encoding=base64 --name=$name $path |
9789                 awk -F= -v name=$name '$1 == name {
9790                         print substr($0, index($0, "=") + 1);
9791         }'
9792 }
9793
9794 test_102n() { # LU-4101 mdt: protect internal xattrs
9795         [ -z "$(which setfattr 2>/dev/null)" ] &&
9796                 skip "could not find setfattr"
9797         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
9798         then
9799                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
9800         fi
9801
9802         local file0=$DIR/$tfile.0
9803         local file1=$DIR/$tfile.1
9804         local xattr0=$TMP/$tfile.0
9805         local xattr1=$TMP/$tfile.1
9806         local namelist="lov lma lmv link fid version som hsm"
9807         local name
9808         local value
9809
9810         rm -rf $file0 $file1 $xattr0 $xattr1
9811         touch $file0 $file1
9812
9813         # Get 'before' xattrs of $file1.
9814         getfattr --absolute-names --dump --match=- $file1 > $xattr0
9815
9816         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
9817                 namelist+=" lfsck_namespace"
9818         for name in $namelist; do
9819                 # Try to copy xattr from $file0 to $file1.
9820                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
9821
9822                 setfattr --name=trusted.$name --value="$value" $file1 ||
9823                         error "setxattr 'trusted.$name' failed"
9824
9825                 # Try to set a garbage xattr.
9826                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
9827
9828                 if [[ x$name == "xlov" ]]; then
9829                         setfattr --name=trusted.lov --value="$value" $file1 &&
9830                         error "setxattr invalid 'trusted.lov' success"
9831                 else
9832                         setfattr --name=trusted.$name --value="$value" $file1 ||
9833                                 error "setxattr invalid 'trusted.$name' failed"
9834                 fi
9835
9836                 # Try to remove the xattr from $file1. We don't care if this
9837                 # appears to succeed or fail, we just don't want there to be
9838                 # any changes or crashes.
9839                 setfattr --remove=$trusted.$name $file1 2> /dev/null
9840         done
9841
9842         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
9843         then
9844                 name="lfsck_ns"
9845                 # Try to copy xattr from $file0 to $file1.
9846                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
9847
9848                 setfattr --name=trusted.$name --value="$value" $file1 ||
9849                         error "setxattr 'trusted.$name' failed"
9850
9851                 # Try to set a garbage xattr.
9852                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
9853
9854                 setfattr --name=trusted.$name --value="$value" $file1 ||
9855                         error "setxattr 'trusted.$name' failed"
9856
9857                 # Try to remove the xattr from $file1. We don't care if this
9858                 # appears to succeed or fail, we just don't want there to be
9859                 # any changes or crashes.
9860                 setfattr --remove=$trusted.$name $file1 2> /dev/null
9861         fi
9862
9863         # Get 'after' xattrs of file1.
9864         getfattr --absolute-names --dump --match=- $file1 > $xattr1
9865
9866         if ! diff $xattr0 $xattr1; then
9867                 error "before and after xattrs of '$file1' differ"
9868         fi
9869
9870         rm -rf $file0 $file1 $xattr0 $xattr1
9871
9872         return 0
9873 }
9874 run_test 102n "silently ignore setxattr on internal trusted xattrs"
9875
9876 test_102p() { # LU-4703 setxattr did not check ownership
9877         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
9878                 skip "MDS needs to be at least 2.5.56"
9879
9880         local testfile=$DIR/$tfile
9881
9882         touch $testfile
9883
9884         echo "setfacl as user..."
9885         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
9886         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
9887
9888         echo "setfattr as user..."
9889         setfacl -m "u:$RUNAS_ID:---" $testfile
9890         $RUNAS setfattr -x system.posix_acl_access $testfile
9891         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
9892 }
9893 run_test 102p "check setxattr(2) correctly fails without permission"
9894
9895 test_102q() {
9896         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
9897                 skip "MDS needs to be at least 2.6.92"
9898
9899         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
9900 }
9901 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
9902
9903 test_102r() {
9904         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
9905                 skip "MDS needs to be at least 2.6.93"
9906
9907         touch $DIR/$tfile || error "touch"
9908         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
9909         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
9910         rm $DIR/$tfile || error "rm"
9911
9912         #normal directory
9913         mkdir -p $DIR/$tdir || error "mkdir"
9914         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
9915         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
9916         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
9917                 error "$testfile error deleting user.author1"
9918         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
9919                 grep "user.$(basename $tdir)" &&
9920                 error "$tdir did not delete user.$(basename $tdir)"
9921         rmdir $DIR/$tdir || error "rmdir"
9922
9923         #striped directory
9924         test_mkdir $DIR/$tdir
9925         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
9926         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
9927         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
9928                 error "$testfile error deleting user.author1"
9929         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
9930                 grep "user.$(basename $tdir)" &&
9931                 error "$tdir did not delete user.$(basename $tdir)"
9932         rmdir $DIR/$tdir || error "rm striped dir"
9933 }
9934 run_test 102r "set EAs with empty values"
9935
9936 test_102s() {
9937         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
9938                 skip "MDS needs to be at least 2.11.52"
9939
9940         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
9941
9942         save_lustre_params client "llite.*.xattr_cache" > $save
9943
9944         for cache in 0 1; do
9945                 lctl set_param llite.*.xattr_cache=$cache
9946
9947                 rm -f $DIR/$tfile
9948                 touch $DIR/$tfile || error "touch"
9949                 for prefix in lustre security system trusted user; do
9950                         # Note getxattr() may fail with 'Operation not
9951                         # supported' or 'No such attribute' depending
9952                         # on prefix and cache.
9953                         getfattr -n $prefix.n102s $DIR/$tfile &&
9954                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
9955                 done
9956         done
9957
9958         restore_lustre_params < $save
9959 }
9960 run_test 102s "getting nonexistent xattrs should fail"
9961
9962 test_102t() {
9963         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
9964                 skip "MDS needs to be at least 2.11.52"
9965
9966         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
9967
9968         save_lustre_params client "llite.*.xattr_cache" > $save
9969
9970         for cache in 0 1; do
9971                 lctl set_param llite.*.xattr_cache=$cache
9972
9973                 for buf_size in 0 256; do
9974                         rm -f $DIR/$tfile
9975                         touch $DIR/$tfile || error "touch"
9976                         setfattr -n user.multiop $DIR/$tfile
9977                         $MULTIOP $DIR/$tfile oa$buf_size ||
9978                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
9979                 done
9980         done
9981
9982         restore_lustre_params < $save
9983 }
9984 run_test 102t "zero length xattr values handled correctly"
9985
9986 run_acl_subtest()
9987 {
9988     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
9989     return $?
9990 }
9991
9992 test_103a() {
9993         [ "$UID" != 0 ] && skip "must run as root"
9994         $GSS && skip_env "could not run under gss"
9995         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
9996                 skip_env "must have acl enabled"
9997         [ -z "$(which setfacl 2>/dev/null)" ] &&
9998                 skip_env "could not find setfacl"
9999         remote_mds_nodsh && skip "remote MDS with nodsh"
10000
10001         gpasswd -a daemon bin                           # LU-5641
10002         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
10003
10004         declare -a identity_old
10005
10006         for num in $(seq $MDSCOUNT); do
10007                 switch_identity $num true || identity_old[$num]=$?
10008         done
10009
10010         SAVE_UMASK=$(umask)
10011         umask 0022
10012         mkdir -p $DIR/$tdir
10013         cd $DIR/$tdir
10014
10015         echo "performing cp ..."
10016         run_acl_subtest cp || error "run_acl_subtest cp failed"
10017         echo "performing getfacl-noacl..."
10018         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
10019         echo "performing misc..."
10020         run_acl_subtest misc || error  "misc test failed"
10021         echo "performing permissions..."
10022         run_acl_subtest permissions || error "permissions failed"
10023         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
10024         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
10025                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
10026                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
10027         then
10028                 echo "performing permissions xattr..."
10029                 run_acl_subtest permissions_xattr ||
10030                         error "permissions_xattr failed"
10031         fi
10032         echo "performing setfacl..."
10033         run_acl_subtest setfacl || error  "setfacl test failed"
10034
10035         # inheritance test got from HP
10036         echo "performing inheritance..."
10037         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
10038         chmod +x make-tree || error "chmod +x failed"
10039         run_acl_subtest inheritance || error "inheritance test failed"
10040         rm -f make-tree
10041
10042         echo "LU-974 ignore umask when acl is enabled..."
10043         run_acl_subtest 974 || error "LU-974 umask test failed"
10044         if [ $MDSCOUNT -ge 2 ]; then
10045                 run_acl_subtest 974_remote ||
10046                         error "LU-974 umask test failed under remote dir"
10047         fi
10048
10049         echo "LU-2561 newly created file is same size as directory..."
10050         if [ "$mds1_FSTYPE" != "zfs" ]; then
10051                 run_acl_subtest 2561 || error "LU-2561 test failed"
10052         else
10053                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
10054         fi
10055
10056         run_acl_subtest 4924 || error "LU-4924 test failed"
10057
10058         cd $SAVE_PWD
10059         umask $SAVE_UMASK
10060
10061         for num in $(seq $MDSCOUNT); do
10062                 if [ "${identity_old[$num]}" = 1 ]; then
10063                         switch_identity $num false || identity_old[$num]=$?
10064                 fi
10065         done
10066 }
10067 run_test 103a "acl test"
10068
10069 test_103b() {
10070         declare -a pids
10071         local U
10072
10073         for U in {0..511}; do
10074                 {
10075                 local O=$(printf "%04o" $U)
10076
10077                 umask $(printf "%04o" $((511 ^ $O)))
10078                 $LFS setstripe -c 1 $DIR/$tfile.s$O
10079                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
10080
10081                 (( $S == ($O & 0666) )) ||
10082                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
10083
10084                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
10085                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
10086                 (( $S == ($O & 0666) )) ||
10087                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
10088
10089                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
10090                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
10091                 (( $S == ($O & 0666) )) ||
10092                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
10093                 rm -f $DIR/$tfile.[smp]$0
10094                 } &
10095                 local pid=$!
10096
10097                 # limit the concurrently running threads to 64. LU-11878
10098                 local idx=$((U % 64))
10099                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
10100                 pids[idx]=$pid
10101         done
10102         wait
10103 }
10104 run_test 103b "umask lfs setstripe"
10105
10106 test_103c() {
10107         mkdir -p $DIR/$tdir
10108         cp -rp $DIR/$tdir $DIR/$tdir.bak
10109
10110         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
10111                 error "$DIR/$tdir shouldn't contain default ACL"
10112         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
10113                 error "$DIR/$tdir.bak shouldn't contain default ACL"
10114         true
10115 }
10116 run_test 103c "'cp -rp' won't set empty acl"
10117
10118 test_104a() {
10119         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10120
10121         touch $DIR/$tfile
10122         lfs df || error "lfs df failed"
10123         lfs df -ih || error "lfs df -ih failed"
10124         lfs df -h $DIR || error "lfs df -h $DIR failed"
10125         lfs df -i $DIR || error "lfs df -i $DIR failed"
10126         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
10127         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
10128
10129         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
10130         lctl --device %$OSC deactivate
10131         lfs df || error "lfs df with deactivated OSC failed"
10132         lctl --device %$OSC activate
10133         # wait the osc back to normal
10134         wait_osc_import_ready client ost
10135
10136         lfs df || error "lfs df with reactivated OSC failed"
10137         rm -f $DIR/$tfile
10138 }
10139 run_test 104a "lfs df [-ih] [path] test ========================="
10140
10141 test_104b() {
10142         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10143         [ $RUNAS_ID -eq $UID ] &&
10144                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10145
10146         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
10147                         grep "Permission denied" | wc -l)))
10148         if [ $denied_cnt -ne 0 ]; then
10149                 error "lfs check servers test failed"
10150         fi
10151 }
10152 run_test 104b "$RUNAS lfs check servers test ===================="
10153
10154 test_105a() {
10155         # doesn't work on 2.4 kernels
10156         touch $DIR/$tfile
10157         if $(flock_is_enabled); then
10158                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
10159         else
10160                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
10161         fi
10162         rm -f $DIR/$tfile
10163 }
10164 run_test 105a "flock when mounted without -o flock test ========"
10165
10166 test_105b() {
10167         touch $DIR/$tfile
10168         if $(flock_is_enabled); then
10169                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
10170         else
10171                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
10172         fi
10173         rm -f $DIR/$tfile
10174 }
10175 run_test 105b "fcntl when mounted without -o flock test ========"
10176
10177 test_105c() {
10178         touch $DIR/$tfile
10179         if $(flock_is_enabled); then
10180                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
10181         else
10182                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
10183         fi
10184         rm -f $DIR/$tfile
10185 }
10186 run_test 105c "lockf when mounted without -o flock test"
10187
10188 test_105d() { # bug 15924
10189         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10190
10191         test_mkdir $DIR/$tdir
10192         flock_is_enabled || skip_env "mount w/o flock enabled"
10193         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
10194         $LCTL set_param fail_loc=0x80000315
10195         flocks_test 2 $DIR/$tdir
10196 }
10197 run_test 105d "flock race (should not freeze) ========"
10198
10199 test_105e() { # bug 22660 && 22040
10200         flock_is_enabled || skip_env "mount w/o flock enabled"
10201
10202         touch $DIR/$tfile
10203         flocks_test 3 $DIR/$tfile
10204 }
10205 run_test 105e "Two conflicting flocks from same process"
10206
10207 test_106() { #bug 10921
10208         test_mkdir $DIR/$tdir
10209         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
10210         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
10211 }
10212 run_test 106 "attempt exec of dir followed by chown of that dir"
10213
10214 test_107() {
10215         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10216
10217         CDIR=`pwd`
10218         local file=core
10219
10220         cd $DIR
10221         rm -f $file
10222
10223         local save_pattern=$(sysctl -n kernel.core_pattern)
10224         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
10225         sysctl -w kernel.core_pattern=$file
10226         sysctl -w kernel.core_uses_pid=0
10227
10228         ulimit -c unlimited
10229         sleep 60 &
10230         SLEEPPID=$!
10231
10232         sleep 1
10233
10234         kill -s 11 $SLEEPPID
10235         wait $SLEEPPID
10236         if [ -e $file ]; then
10237                 size=`stat -c%s $file`
10238                 [ $size -eq 0 ] && error "Fail to create core file $file"
10239         else
10240                 error "Fail to create core file $file"
10241         fi
10242         rm -f $file
10243         sysctl -w kernel.core_pattern=$save_pattern
10244         sysctl -w kernel.core_uses_pid=$save_uses_pid
10245         cd $CDIR
10246 }
10247 run_test 107 "Coredump on SIG"
10248
10249 test_110() {
10250         test_mkdir $DIR/$tdir
10251         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
10252         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
10253                 error "mkdir with 256 char should fail, but did not"
10254         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
10255                 error "create with 255 char failed"
10256         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
10257                 error "create with 256 char should fail, but did not"
10258
10259         ls -l $DIR/$tdir
10260         rm -rf $DIR/$tdir
10261 }
10262 run_test 110 "filename length checking"
10263
10264 #
10265 # Purpose: To verify dynamic thread (OSS) creation.
10266 #
10267 test_115() {
10268         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10269         remote_ost_nodsh && skip "remote OST with nodsh"
10270
10271         # Lustre does not stop service threads once they are started.
10272         # Reset number of running threads to default.
10273         stopall
10274         setupall
10275
10276         local OSTIO_pre
10277         local save_params="$TMP/sanity-$TESTNAME.parameters"
10278
10279         # Get ll_ost_io count before I/O
10280         OSTIO_pre=$(do_facet ost1 \
10281                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
10282         # Exit if lustre is not running (ll_ost_io not running).
10283         [ -z "$OSTIO_pre" ] && error "no OSS threads"
10284
10285         echo "Starting with $OSTIO_pre threads"
10286         local thread_max=$((OSTIO_pre * 2))
10287         local rpc_in_flight=$((thread_max * 2))
10288         # Number of I/O Process proposed to be started.
10289         local nfiles
10290         local facets=$(get_facets OST)
10291
10292         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
10293         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
10294
10295         # Set in_flight to $rpc_in_flight
10296         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
10297                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
10298         nfiles=${rpc_in_flight}
10299         # Set ost thread_max to $thread_max
10300         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
10301
10302         # 5 Minutes should be sufficient for max number of OSS
10303         # threads(thread_max) to be created.
10304         local timeout=300
10305
10306         # Start I/O.
10307         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
10308         test_mkdir $DIR/$tdir
10309         for i in $(seq $nfiles); do
10310                 local file=$DIR/$tdir/${tfile}-$i
10311                 $LFS setstripe -c -1 -i 0 $file
10312                 ($WTL $file $timeout)&
10313         done
10314
10315         # I/O Started - Wait for thread_started to reach thread_max or report
10316         # error if thread_started is more than thread_max.
10317         echo "Waiting for thread_started to reach thread_max"
10318         local thread_started=0
10319         local end_time=$((SECONDS + timeout))
10320
10321         while [ $SECONDS -le $end_time ] ; do
10322                 echo -n "."
10323                 # Get ost i/o thread_started count.
10324                 thread_started=$(do_facet ost1 \
10325                         "$LCTL get_param \
10326                         ost.OSS.ost_io.threads_started | cut -d= -f2")
10327                 # Break out if thread_started is equal/greater than thread_max
10328                 if [[ $thread_started -ge $thread_max ]]; then
10329                         echo ll_ost_io thread_started $thread_started, \
10330                                 equal/greater than thread_max $thread_max
10331                         break
10332                 fi
10333                 sleep 1
10334         done
10335
10336         # Cleanup - We have the numbers, Kill i/o jobs if running.
10337         jobcount=($(jobs -p))
10338         for i in $(seq 0 $((${#jobcount[@]}-1)))
10339         do
10340                 kill -9 ${jobcount[$i]}
10341                 if [ $? -ne 0 ] ; then
10342                         echo Warning: \
10343                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
10344                 fi
10345         done
10346
10347         # Cleanup files left by WTL binary.
10348         for i in $(seq $nfiles); do
10349                 local file=$DIR/$tdir/${tfile}-$i
10350                 rm -rf $file
10351                 if [ $? -ne 0 ] ; then
10352                         echo "Warning: Failed to delete file $file"
10353                 fi
10354         done
10355
10356         restore_lustre_params <$save_params
10357         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
10358
10359         # Error out if no new thread has started or Thread started is greater
10360         # than thread max.
10361         if [[ $thread_started -le $OSTIO_pre ||
10362                         $thread_started -gt $thread_max ]]; then
10363                 error "ll_ost_io: thread_started $thread_started" \
10364                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
10365                       "No new thread started or thread started greater " \
10366                       "than thread_max."
10367         fi
10368 }
10369 run_test 115 "verify dynamic thread creation===================="
10370
10371 free_min_max () {
10372         wait_delete_completed
10373         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
10374         echo "OST kbytes available: ${AVAIL[@]}"
10375         MAXV=${AVAIL[0]}
10376         MAXI=0
10377         MINV=${AVAIL[0]}
10378         MINI=0
10379         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
10380                 #echo OST $i: ${AVAIL[i]}kb
10381                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
10382                         MAXV=${AVAIL[i]}
10383                         MAXI=$i
10384                 fi
10385                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
10386                         MINV=${AVAIL[i]}
10387                         MINI=$i
10388                 fi
10389         done
10390         echo "Min free space: OST $MINI: $MINV"
10391         echo "Max free space: OST $MAXI: $MAXV"
10392 }
10393
10394 test_116a() { # was previously test_116()
10395         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10396         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10397         remote_mds_nodsh && skip "remote MDS with nodsh"
10398
10399         echo -n "Free space priority "
10400         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
10401                 head -n1
10402         declare -a AVAIL
10403         free_min_max
10404
10405         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
10406         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
10407         trap simple_cleanup_common EXIT
10408
10409         # Check if we need to generate uneven OSTs
10410         test_mkdir -p $DIR/$tdir/OST${MINI}
10411         local FILL=$((MINV / 4))
10412         local DIFF=$((MAXV - MINV))
10413         local DIFF2=$((DIFF * 100 / MINV))
10414
10415         local threshold=$(do_facet $SINGLEMDS \
10416                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
10417         threshold=${threshold%%%}
10418         echo -n "Check for uneven OSTs: "
10419         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
10420
10421         if [[ $DIFF2 -gt $threshold ]]; then
10422                 echo "ok"
10423                 echo "Don't need to fill OST$MINI"
10424         else
10425                 # generate uneven OSTs. Write 2% over the QOS threshold value
10426                 echo "no"
10427                 DIFF=$((threshold - DIFF2 + 2))
10428                 DIFF2=$((MINV * DIFF / 100))
10429                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
10430                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
10431                         error "setstripe failed"
10432                 DIFF=$((DIFF2 / 2048))
10433                 i=0
10434                 while [ $i -lt $DIFF ]; do
10435                         i=$((i + 1))
10436                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
10437                                 bs=2M count=1 2>/dev/null
10438                         echo -n .
10439                 done
10440                 echo .
10441                 sync
10442                 sleep_maxage
10443                 free_min_max
10444         fi
10445
10446         DIFF=$((MAXV - MINV))
10447         DIFF2=$((DIFF * 100 / MINV))
10448         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
10449         if [ $DIFF2 -gt $threshold ]; then
10450                 echo "ok"
10451         else
10452                 echo "failed - QOS mode won't be used"
10453                 simple_cleanup_common
10454                 skip "QOS imbalance criteria not met"
10455         fi
10456
10457         MINI1=$MINI
10458         MINV1=$MINV
10459         MAXI1=$MAXI
10460         MAXV1=$MAXV
10461
10462         # now fill using QOS
10463         $LFS setstripe -c 1 $DIR/$tdir
10464         FILL=$((FILL / 200))
10465         if [ $FILL -gt 600 ]; then
10466                 FILL=600
10467         fi
10468         echo "writing $FILL files to QOS-assigned OSTs"
10469         i=0
10470         while [ $i -lt $FILL ]; do
10471                 i=$((i + 1))
10472                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
10473                         count=1 2>/dev/null
10474                 echo -n .
10475         done
10476         echo "wrote $i 200k files"
10477         sync
10478         sleep_maxage
10479
10480         echo "Note: free space may not be updated, so measurements might be off"
10481         free_min_max
10482         DIFF2=$((MAXV - MINV))
10483         echo "free space delta: orig $DIFF final $DIFF2"
10484         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
10485         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
10486         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
10487         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
10488         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
10489         if [[ $DIFF -gt 0 ]]; then
10490                 FILL=$((DIFF2 * 100 / DIFF - 100))
10491                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
10492         fi
10493
10494         # Figure out which files were written where
10495         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10496                awk '/'$MINI1': / {print $2; exit}')
10497         echo $UUID
10498         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10499         echo "$MINC files created on smaller OST $MINI1"
10500         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10501                awk '/'$MAXI1': / {print $2; exit}')
10502         echo $UUID
10503         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10504         echo "$MAXC files created on larger OST $MAXI1"
10505         if [[ $MINC -gt 0 ]]; then
10506                 FILL=$((MAXC * 100 / MINC - 100))
10507                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
10508         fi
10509         [[ $MAXC -gt $MINC ]] ||
10510                 error_ignore LU-9 "stripe QOS didn't balance free space"
10511         simple_cleanup_common
10512 }
10513 run_test 116a "stripe QOS: free space balance ==================="
10514
10515 test_116b() { # LU-2093
10516         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10517         remote_mds_nodsh && skip "remote MDS with nodsh"
10518
10519 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
10520         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
10521                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
10522         [ -z "$old_rr" ] && skip "no QOS"
10523         do_facet $SINGLEMDS lctl set_param \
10524                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
10525         mkdir -p $DIR/$tdir
10526         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
10527         createmany -o $DIR/$tdir/f- 20 || error "can't create"
10528         do_facet $SINGLEMDS lctl set_param fail_loc=0
10529         rm -rf $DIR/$tdir
10530         do_facet $SINGLEMDS lctl set_param \
10531                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
10532 }
10533 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
10534
10535 test_117() # bug 10891
10536 {
10537         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10538
10539         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
10540         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
10541         lctl set_param fail_loc=0x21e
10542         > $DIR/$tfile || error "truncate failed"
10543         lctl set_param fail_loc=0
10544         echo "Truncate succeeded."
10545         rm -f $DIR/$tfile
10546 }
10547 run_test 117 "verify osd extend =========="
10548
10549 NO_SLOW_RESENDCOUNT=4
10550 export OLD_RESENDCOUNT=""
10551 set_resend_count () {
10552         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
10553         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
10554         lctl set_param -n $PROC_RESENDCOUNT $1
10555         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
10556 }
10557
10558 # for reduce test_118* time (b=14842)
10559 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
10560
10561 # Reset async IO behavior after error case
10562 reset_async() {
10563         FILE=$DIR/reset_async
10564
10565         # Ensure all OSCs are cleared
10566         $LFS setstripe -c -1 $FILE
10567         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
10568         sync
10569         rm $FILE
10570 }
10571
10572 test_118a() #bug 11710
10573 {
10574         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10575
10576         reset_async
10577
10578         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10579         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10580         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10581
10582         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10583                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10584                 return 1;
10585         fi
10586         rm -f $DIR/$tfile
10587 }
10588 run_test 118a "verify O_SYNC works =========="
10589
10590 test_118b()
10591 {
10592         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10593         remote_ost_nodsh && skip "remote OST with nodsh"
10594
10595         reset_async
10596
10597         #define OBD_FAIL_SRV_ENOENT 0x217
10598         set_nodes_failloc "$(osts_nodes)" 0x217
10599         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10600         RC=$?
10601         set_nodes_failloc "$(osts_nodes)" 0
10602         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10603         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10604                     grep -c writeback)
10605
10606         if [[ $RC -eq 0 ]]; then
10607                 error "Must return error due to dropped pages, rc=$RC"
10608                 return 1;
10609         fi
10610
10611         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10612                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10613                 return 1;
10614         fi
10615
10616         echo "Dirty pages not leaked on ENOENT"
10617
10618         # Due to the above error the OSC will issue all RPCs syncronously
10619         # until a subsequent RPC completes successfully without error.
10620         $MULTIOP $DIR/$tfile Ow4096yc
10621         rm -f $DIR/$tfile
10622
10623         return 0
10624 }
10625 run_test 118b "Reclaim dirty pages on fatal error =========="
10626
10627 test_118c()
10628 {
10629         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10630
10631         # for 118c, restore the original resend count, LU-1940
10632         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
10633                                 set_resend_count $OLD_RESENDCOUNT
10634         remote_ost_nodsh && skip "remote OST with nodsh"
10635
10636         reset_async
10637
10638         #define OBD_FAIL_OST_EROFS               0x216
10639         set_nodes_failloc "$(osts_nodes)" 0x216
10640
10641         # multiop should block due to fsync until pages are written
10642         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10643         MULTIPID=$!
10644         sleep 1
10645
10646         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
10647                 error "Multiop failed to block on fsync, pid=$MULTIPID"
10648         fi
10649
10650         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10651                     grep -c writeback)
10652         if [[ $WRITEBACK -eq 0 ]]; then
10653                 error "No page in writeback, writeback=$WRITEBACK"
10654         fi
10655
10656         set_nodes_failloc "$(osts_nodes)" 0
10657         wait $MULTIPID
10658         RC=$?
10659         if [[ $RC -ne 0 ]]; then
10660                 error "Multiop fsync failed, rc=$RC"
10661         fi
10662
10663         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10664         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10665                     grep -c writeback)
10666         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10667                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10668         fi
10669
10670         rm -f $DIR/$tfile
10671         echo "Dirty pages flushed via fsync on EROFS"
10672         return 0
10673 }
10674 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
10675
10676 # continue to use small resend count to reduce test_118* time (b=14842)
10677 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
10678
10679 test_118d()
10680 {
10681         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10682         remote_ost_nodsh && skip "remote OST with nodsh"
10683
10684         reset_async
10685
10686         #define OBD_FAIL_OST_BRW_PAUSE_BULK
10687         set_nodes_failloc "$(osts_nodes)" 0x214
10688         # multiop should block due to fsync until pages are written
10689         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10690         MULTIPID=$!
10691         sleep 1
10692
10693         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
10694                 error "Multiop failed to block on fsync, pid=$MULTIPID"
10695         fi
10696
10697         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10698                     grep -c writeback)
10699         if [[ $WRITEBACK -eq 0 ]]; then
10700                 error "No page in writeback, writeback=$WRITEBACK"
10701         fi
10702
10703         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
10704         set_nodes_failloc "$(osts_nodes)" 0
10705
10706         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10707         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10708                     grep -c writeback)
10709         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10710                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10711         fi
10712
10713         rm -f $DIR/$tfile
10714         echo "Dirty pages gaurenteed flushed via fsync"
10715         return 0
10716 }
10717 run_test 118d "Fsync validation inject a delay of the bulk =========="
10718
10719 test_118f() {
10720         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10721
10722         reset_async
10723
10724         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
10725         lctl set_param fail_loc=0x8000040a
10726
10727         # Should simulate EINVAL error which is fatal
10728         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10729         RC=$?
10730         if [[ $RC -eq 0 ]]; then
10731                 error "Must return error due to dropped pages, rc=$RC"
10732         fi
10733
10734         lctl set_param fail_loc=0x0
10735
10736         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10737         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10738         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10739                     grep -c writeback)
10740         if [[ $LOCKED -ne 0 ]]; then
10741                 error "Locked pages remain in cache, locked=$LOCKED"
10742         fi
10743
10744         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10745                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10746         fi
10747
10748         rm -f $DIR/$tfile
10749         echo "No pages locked after fsync"
10750
10751         reset_async
10752         return 0
10753 }
10754 run_test 118f "Simulate unrecoverable OSC side error =========="
10755
10756 test_118g() {
10757         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10758
10759         reset_async
10760
10761         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
10762         lctl set_param fail_loc=0x406
10763
10764         # simulate local -ENOMEM
10765         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10766         RC=$?
10767
10768         lctl set_param fail_loc=0
10769         if [[ $RC -eq 0 ]]; then
10770                 error "Must return error due to dropped pages, rc=$RC"
10771         fi
10772
10773         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10774         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10775         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10776                         grep -c writeback)
10777         if [[ $LOCKED -ne 0 ]]; then
10778                 error "Locked pages remain in cache, locked=$LOCKED"
10779         fi
10780
10781         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10782                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10783         fi
10784
10785         rm -f $DIR/$tfile
10786         echo "No pages locked after fsync"
10787
10788         reset_async
10789         return 0
10790 }
10791 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
10792
10793 test_118h() {
10794         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10795         remote_ost_nodsh && skip "remote OST with nodsh"
10796
10797         reset_async
10798
10799         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
10800         set_nodes_failloc "$(osts_nodes)" 0x20e
10801         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
10802         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10803         RC=$?
10804
10805         set_nodes_failloc "$(osts_nodes)" 0
10806         if [[ $RC -eq 0 ]]; then
10807                 error "Must return error due to dropped pages, rc=$RC"
10808         fi
10809
10810         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10811         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10812         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10813                     grep -c writeback)
10814         if [[ $LOCKED -ne 0 ]]; then
10815                 error "Locked pages remain in cache, locked=$LOCKED"
10816         fi
10817
10818         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10819                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10820         fi
10821
10822         rm -f $DIR/$tfile
10823         echo "No pages locked after fsync"
10824
10825         return 0
10826 }
10827 run_test 118h "Verify timeout in handling recoverables errors  =========="
10828
10829 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
10830
10831 test_118i() {
10832         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10833         remote_ost_nodsh && skip "remote OST with nodsh"
10834
10835         reset_async
10836
10837         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
10838         set_nodes_failloc "$(osts_nodes)" 0x20e
10839
10840         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
10841         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10842         PID=$!
10843         sleep 5
10844         set_nodes_failloc "$(osts_nodes)" 0
10845
10846         wait $PID
10847         RC=$?
10848         if [[ $RC -ne 0 ]]; then
10849                 error "got error, but should be not, rc=$RC"
10850         fi
10851
10852         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10853         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10854         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10855         if [[ $LOCKED -ne 0 ]]; then
10856                 error "Locked pages remain in cache, locked=$LOCKED"
10857         fi
10858
10859         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10860                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10861         fi
10862
10863         rm -f $DIR/$tfile
10864         echo "No pages locked after fsync"
10865
10866         return 0
10867 }
10868 run_test 118i "Fix error before timeout in recoverable error  =========="
10869
10870 [ "$SLOW" = "no" ] && set_resend_count 4
10871
10872 test_118j() {
10873         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10874         remote_ost_nodsh && skip "remote OST with nodsh"
10875
10876         reset_async
10877
10878         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
10879         set_nodes_failloc "$(osts_nodes)" 0x220
10880
10881         # return -EIO from OST
10882         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10883         RC=$?
10884         set_nodes_failloc "$(osts_nodes)" 0x0
10885         if [[ $RC -eq 0 ]]; then
10886                 error "Must return error due to dropped pages, rc=$RC"
10887         fi
10888
10889         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10890         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10891         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10892         if [[ $LOCKED -ne 0 ]]; then
10893                 error "Locked pages remain in cache, locked=$LOCKED"
10894         fi
10895
10896         # in recoverable error on OST we want resend and stay until it finished
10897         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10898                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10899         fi
10900
10901         rm -f $DIR/$tfile
10902         echo "No pages locked after fsync"
10903
10904         return 0
10905 }
10906 run_test 118j "Simulate unrecoverable OST side error =========="
10907
10908 test_118k()
10909 {
10910         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10911         remote_ost_nodsh && skip "remote OSTs with nodsh"
10912
10913         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
10914         set_nodes_failloc "$(osts_nodes)" 0x20e
10915         test_mkdir $DIR/$tdir
10916
10917         for ((i=0;i<10;i++)); do
10918                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
10919                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
10920                 SLEEPPID=$!
10921                 sleep 0.500s
10922                 kill $SLEEPPID
10923                 wait $SLEEPPID
10924         done
10925
10926         set_nodes_failloc "$(osts_nodes)" 0
10927         rm -rf $DIR/$tdir
10928 }
10929 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
10930
10931 test_118l() # LU-646
10932 {
10933         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10934
10935         test_mkdir $DIR/$tdir
10936         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
10937         rm -rf $DIR/$tdir
10938 }
10939 run_test 118l "fsync dir"
10940
10941 test_118m() # LU-3066
10942 {
10943         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10944
10945         test_mkdir $DIR/$tdir
10946         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
10947         rm -rf $DIR/$tdir
10948 }
10949 run_test 118m "fdatasync dir ========="
10950
10951 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
10952
10953 test_118n()
10954 {
10955         local begin
10956         local end
10957
10958         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10959         remote_ost_nodsh && skip "remote OSTs with nodsh"
10960
10961         # Sleep to avoid a cached response.
10962         #define OBD_STATFS_CACHE_SECONDS 1
10963         sleep 2
10964
10965         # Inject a 10 second delay in the OST_STATFS handler.
10966         #define OBD_FAIL_OST_STATFS_DELAY 0x242
10967         set_nodes_failloc "$(osts_nodes)" 0x242
10968
10969         begin=$SECONDS
10970         stat --file-system $MOUNT > /dev/null
10971         end=$SECONDS
10972
10973         set_nodes_failloc "$(osts_nodes)" 0
10974
10975         if ((end - begin > 20)); then
10976             error "statfs took $((end - begin)) seconds, expected 10"
10977         fi
10978 }
10979 run_test 118n "statfs() sends OST_STATFS requests in parallel"
10980
10981 test_119a() # bug 11737
10982 {
10983         BSIZE=$((512 * 1024))
10984         directio write $DIR/$tfile 0 1 $BSIZE
10985         # We ask to read two blocks, which is more than a file size.
10986         # directio will indicate an error when requested and actual
10987         # sizes aren't equeal (a normal situation in this case) and
10988         # print actual read amount.
10989         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
10990         if [ "$NOB" != "$BSIZE" ]; then
10991                 error "read $NOB bytes instead of $BSIZE"
10992         fi
10993         rm -f $DIR/$tfile
10994 }
10995 run_test 119a "Short directIO read must return actual read amount"
10996
10997 test_119b() # bug 11737
10998 {
10999         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11000
11001         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
11002         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
11003         sync
11004         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
11005                 error "direct read failed"
11006         rm -f $DIR/$tfile
11007 }
11008 run_test 119b "Sparse directIO read must return actual read amount"
11009
11010 test_119c() # bug 13099
11011 {
11012         BSIZE=1048576
11013         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
11014         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
11015         rm -f $DIR/$tfile
11016 }
11017 run_test 119c "Testing for direct read hitting hole"
11018
11019 test_119d() # bug 15950
11020 {
11021         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11022
11023         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
11024         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
11025         BSIZE=1048576
11026         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
11027         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
11028         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
11029         lctl set_param fail_loc=0x40d
11030         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
11031         pid_dio=$!
11032         sleep 1
11033         cat $DIR/$tfile > /dev/null &
11034         lctl set_param fail_loc=0
11035         pid_reads=$!
11036         wait $pid_dio
11037         log "the DIO writes have completed, now wait for the reads (should not block very long)"
11038         sleep 2
11039         [ -n "`ps h -p $pid_reads -o comm`" ] && \
11040         error "the read rpcs have not completed in 2s"
11041         rm -f $DIR/$tfile
11042         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
11043 }
11044 run_test 119d "The DIO path should try to send a new rpc once one is completed"
11045
11046 test_120a() {
11047         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11048         remote_mds_nodsh && skip "remote MDS with nodsh"
11049         test_mkdir -i0 -c1 $DIR/$tdir
11050         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11051                 skip_env "no early lock cancel on server"
11052
11053         lru_resize_disable mdc
11054         lru_resize_disable osc
11055         cancel_lru_locks mdc
11056         # asynchronous object destroy at MDT could cause bl ast to client
11057         cancel_lru_locks osc
11058
11059         stat $DIR/$tdir > /dev/null
11060         can1=$(do_facet mds1 \
11061                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11062                awk '/ldlm_cancel/ {print $2}')
11063         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11064                awk '/ldlm_bl_callback/ {print $2}')
11065         test_mkdir -i0 -c1 $DIR/$tdir/d1
11066         can2=$(do_facet mds1 \
11067                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11068                awk '/ldlm_cancel/ {print $2}')
11069         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11070                awk '/ldlm_bl_callback/ {print $2}')
11071         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11072         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11073         lru_resize_enable mdc
11074         lru_resize_enable osc
11075 }
11076 run_test 120a "Early Lock Cancel: mkdir test"
11077
11078 test_120b() {
11079         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11080         remote_mds_nodsh && skip "remote MDS with nodsh"
11081         test_mkdir $DIR/$tdir
11082         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11083                 skip_env "no early lock cancel on server"
11084
11085         lru_resize_disable mdc
11086         lru_resize_disable osc
11087         cancel_lru_locks mdc
11088         stat $DIR/$tdir > /dev/null
11089         can1=$(do_facet $SINGLEMDS \
11090                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11091                awk '/ldlm_cancel/ {print $2}')
11092         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11093                awk '/ldlm_bl_callback/ {print $2}')
11094         touch $DIR/$tdir/f1
11095         can2=$(do_facet $SINGLEMDS \
11096                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11097                awk '/ldlm_cancel/ {print $2}')
11098         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11099                awk '/ldlm_bl_callback/ {print $2}')
11100         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11101         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11102         lru_resize_enable mdc
11103         lru_resize_enable osc
11104 }
11105 run_test 120b "Early Lock Cancel: create test"
11106
11107 test_120c() {
11108         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11109         remote_mds_nodsh && skip "remote MDS with nodsh"
11110         test_mkdir -i0 -c1 $DIR/$tdir
11111         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11112                 skip "no early lock cancel on server"
11113
11114         lru_resize_disable mdc
11115         lru_resize_disable osc
11116         test_mkdir -i0 -c1 $DIR/$tdir/d1
11117         test_mkdir -i0 -c1 $DIR/$tdir/d2
11118         touch $DIR/$tdir/d1/f1
11119         cancel_lru_locks mdc
11120         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
11121         can1=$(do_facet mds1 \
11122                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11123                awk '/ldlm_cancel/ {print $2}')
11124         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11125                awk '/ldlm_bl_callback/ {print $2}')
11126         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
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 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11133         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11134         lru_resize_enable mdc
11135         lru_resize_enable osc
11136 }
11137 run_test 120c "Early Lock Cancel: link test"
11138
11139 test_120d() {
11140         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11141         remote_mds_nodsh && skip "remote MDS with nodsh"
11142         test_mkdir -i0 -c1 $DIR/$tdir
11143         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11144                 skip_env "no early lock cancel on server"
11145
11146         lru_resize_disable mdc
11147         lru_resize_disable osc
11148         touch $DIR/$tdir
11149         cancel_lru_locks mdc
11150         stat $DIR/$tdir > /dev/null
11151         can1=$(do_facet mds1 \
11152                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11153                awk '/ldlm_cancel/ {print $2}')
11154         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11155                awk '/ldlm_bl_callback/ {print $2}')
11156         chmod a+x $DIR/$tdir
11157         can2=$(do_facet mds1 \
11158                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11159                awk '/ldlm_cancel/ {print $2}')
11160         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11161                awk '/ldlm_bl_callback/ {print $2}')
11162         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11163         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11164         lru_resize_enable mdc
11165         lru_resize_enable osc
11166 }
11167 run_test 120d "Early Lock Cancel: setattr test"
11168
11169 test_120e() {
11170         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11171         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11172                 skip_env "no early lock cancel on server"
11173         remote_mds_nodsh && skip "remote MDS with nodsh"
11174
11175         local dlmtrace_set=false
11176
11177         test_mkdir -i0 -c1 $DIR/$tdir
11178         lru_resize_disable mdc
11179         lru_resize_disable osc
11180         ! $LCTL get_param debug | grep -q dlmtrace &&
11181                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
11182         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
11183         cancel_lru_locks mdc
11184         cancel_lru_locks osc
11185         dd if=$DIR/$tdir/f1 of=/dev/null
11186         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
11187         # XXX client can not do early lock cancel of OST lock
11188         # during unlink (LU-4206), so cancel osc lock now.
11189         sleep 2
11190         cancel_lru_locks osc
11191         can1=$(do_facet mds1 \
11192                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11193                awk '/ldlm_cancel/ {print $2}')
11194         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11195                awk '/ldlm_bl_callback/ {print $2}')
11196         unlink $DIR/$tdir/f1
11197         sleep 5
11198         can2=$(do_facet mds1 \
11199                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11200                awk '/ldlm_cancel/ {print $2}')
11201         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11202                awk '/ldlm_bl_callback/ {print $2}')
11203         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
11204                 $LCTL dk $TMP/cancel.debug.txt
11205         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
11206                 $LCTL dk $TMP/blocking.debug.txt
11207         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
11208         lru_resize_enable mdc
11209         lru_resize_enable osc
11210 }
11211 run_test 120e "Early Lock Cancel: unlink test"
11212
11213 test_120f() {
11214         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11215         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11216                 skip_env "no early lock cancel on server"
11217         remote_mds_nodsh && skip "remote MDS with nodsh"
11218
11219         test_mkdir -i0 -c1 $DIR/$tdir
11220         lru_resize_disable mdc
11221         lru_resize_disable osc
11222         test_mkdir -i0 -c1 $DIR/$tdir/d1
11223         test_mkdir -i0 -c1 $DIR/$tdir/d2
11224         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
11225         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
11226         cancel_lru_locks mdc
11227         cancel_lru_locks osc
11228         dd if=$DIR/$tdir/d1/f1 of=/dev/null
11229         dd if=$DIR/$tdir/d2/f2 of=/dev/null
11230         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
11231         # XXX client can not do early lock cancel of OST lock
11232         # during rename (LU-4206), so cancel osc lock now.
11233         sleep 2
11234         cancel_lru_locks osc
11235         can1=$(do_facet mds1 \
11236                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11237                awk '/ldlm_cancel/ {print $2}')
11238         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11239                awk '/ldlm_bl_callback/ {print $2}')
11240         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11241         sleep 5
11242         can2=$(do_facet mds1 \
11243                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11244                awk '/ldlm_cancel/ {print $2}')
11245         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11246                awk '/ldlm_bl_callback/ {print $2}')
11247         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11248         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11249         lru_resize_enable mdc
11250         lru_resize_enable osc
11251 }
11252 run_test 120f "Early Lock Cancel: rename test"
11253
11254 test_120g() {
11255         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11256         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11257                 skip_env "no early lock cancel on server"
11258         remote_mds_nodsh && skip "remote MDS with nodsh"
11259
11260         lru_resize_disable mdc
11261         lru_resize_disable osc
11262         count=10000
11263         echo create $count files
11264         test_mkdir $DIR/$tdir
11265         cancel_lru_locks mdc
11266         cancel_lru_locks osc
11267         t0=$(date +%s)
11268
11269         can0=$(do_facet $SINGLEMDS \
11270                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11271                awk '/ldlm_cancel/ {print $2}')
11272         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11273                awk '/ldlm_bl_callback/ {print $2}')
11274         createmany -o $DIR/$tdir/f $count
11275         sync
11276         can1=$(do_facet $SINGLEMDS \
11277                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11278                awk '/ldlm_cancel/ {print $2}')
11279         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11280                awk '/ldlm_bl_callback/ {print $2}')
11281         t1=$(date +%s)
11282         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
11283         echo rm $count files
11284         rm -r $DIR/$tdir
11285         sync
11286         can2=$(do_facet $SINGLEMDS \
11287                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11288                awk '/ldlm_cancel/ {print $2}')
11289         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11290                awk '/ldlm_bl_callback/ {print $2}')
11291         t2=$(date +%s)
11292         echo total: $count removes in $((t2-t1))
11293         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
11294         sleep 2
11295         # wait for commitment of removal
11296         lru_resize_enable mdc
11297         lru_resize_enable osc
11298 }
11299 run_test 120g "Early Lock Cancel: performance test"
11300
11301 test_121() { #bug #10589
11302         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11303
11304         rm -rf $DIR/$tfile
11305         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
11306 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
11307         lctl set_param fail_loc=0x310
11308         cancel_lru_locks osc > /dev/null
11309         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
11310         lctl set_param fail_loc=0
11311         [[ $reads -eq $writes ]] ||
11312                 error "read $reads blocks, must be $writes blocks"
11313 }
11314 run_test 121 "read cancel race ========="
11315
11316 test_123a() { # was test 123, statahead(bug 11401)
11317         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11318
11319         SLOWOK=0
11320         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
11321                 log "testing UP system. Performance may be lower than expected."
11322                 SLOWOK=1
11323         fi
11324
11325         rm -rf $DIR/$tdir
11326         test_mkdir $DIR/$tdir
11327         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
11328         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
11329         MULT=10
11330         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
11331                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
11332
11333                 max=`lctl get_param -n llite.*.statahead_max | head -n 1`
11334                 lctl set_param -n llite.*.statahead_max 0
11335                 lctl get_param llite.*.statahead_max
11336                 cancel_lru_locks mdc
11337                 cancel_lru_locks osc
11338                 stime=`date +%s`
11339                 time ls -l $DIR/$tdir | wc -l
11340                 etime=`date +%s`
11341                 delta=$((etime - stime))
11342                 log "ls $i files without statahead: $delta sec"
11343                 lctl set_param llite.*.statahead_max=$max
11344
11345                 swrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
11346                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
11347                 cancel_lru_locks mdc
11348                 cancel_lru_locks osc
11349                 stime=`date +%s`
11350                 time ls -l $DIR/$tdir | wc -l
11351                 etime=`date +%s`
11352                 delta_sa=$((etime - stime))
11353                 log "ls $i files with statahead: $delta_sa sec"
11354                 lctl get_param -n llite.*.statahead_stats
11355                 ewrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
11356
11357                 [[ $swrong -lt $ewrong ]] &&
11358                         log "statahead was stopped, maybe too many locks held!"
11359                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
11360
11361                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
11362                     max=`lctl get_param -n llite.*.statahead_max | head -n 1`
11363                     lctl set_param -n llite.*.statahead_max 0
11364                     lctl get_param llite.*.statahead_max
11365                     cancel_lru_locks mdc
11366                     cancel_lru_locks osc
11367                     stime=`date +%s`
11368                     time ls -l $DIR/$tdir | wc -l
11369                     etime=`date +%s`
11370                     delta=$((etime - stime))
11371                     log "ls $i files again without statahead: $delta sec"
11372                     lctl set_param llite.*.statahead_max=$max
11373                     if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
11374                         if [  $SLOWOK -eq 0 ]; then
11375                                 error "ls $i files is slower with statahead!"
11376                         else
11377                                 log "ls $i files is slower with statahead!"
11378                         fi
11379                         break
11380                     fi
11381                 fi
11382
11383                 [ $delta -gt 20 ] && break
11384                 [ $delta -gt 8 ] && MULT=$((50 / delta))
11385                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
11386         done
11387         log "ls done"
11388
11389         stime=`date +%s`
11390         rm -r $DIR/$tdir
11391         sync
11392         etime=`date +%s`
11393         delta=$((etime - stime))
11394         log "rm -r $DIR/$tdir/: $delta seconds"
11395         log "rm done"
11396         lctl get_param -n llite.*.statahead_stats
11397 }
11398 run_test 123a "verify statahead work"
11399
11400 test_123b () { # statahead(bug 15027)
11401         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11402
11403         test_mkdir $DIR/$tdir
11404         createmany -o $DIR/$tdir/$tfile-%d 1000
11405
11406         cancel_lru_locks mdc
11407         cancel_lru_locks osc
11408
11409 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
11410         lctl set_param fail_loc=0x80000803
11411         ls -lR $DIR/$tdir > /dev/null
11412         log "ls done"
11413         lctl set_param fail_loc=0x0
11414         lctl get_param -n llite.*.statahead_stats
11415         rm -r $DIR/$tdir
11416         sync
11417
11418 }
11419 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
11420
11421 test_123c() {
11422         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
11423
11424         test_mkdir -i 0 -c 1 $DIR/$tdir.0
11425         test_mkdir -i 1 -c 1 $DIR/$tdir.1
11426         touch $DIR/$tdir.1/{1..3}
11427         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
11428
11429         remount_client $MOUNT
11430
11431         $MULTIOP $DIR/$tdir.0 Q
11432
11433         # let statahead to complete
11434         ls -l $DIR/$tdir.0 > /dev/null
11435
11436         testid=$(echo $TESTNAME | tr '_' ' ')
11437         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
11438                 error "statahead warning" || true
11439 }
11440 run_test 123c "Can not initialize inode warning on DNE statahead"
11441
11442 test_124a() {
11443         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11444         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11445                 skip_env "no lru resize on server"
11446
11447         local NR=2000
11448
11449         test_mkdir $DIR/$tdir
11450
11451         log "create $NR files at $DIR/$tdir"
11452         createmany -o $DIR/$tdir/f $NR ||
11453                 error "failed to create $NR files in $DIR/$tdir"
11454
11455         cancel_lru_locks mdc
11456         ls -l $DIR/$tdir > /dev/null
11457
11458         local NSDIR=""
11459         local LRU_SIZE=0
11460         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
11461                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
11462                 LRU_SIZE=$($LCTL get_param -n $PARAM)
11463                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
11464                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
11465                         log "NSDIR=$NSDIR"
11466                         log "NS=$(basename $NSDIR)"
11467                         break
11468                 fi
11469         done
11470
11471         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
11472                 skip "Not enough cached locks created!"
11473         fi
11474         log "LRU=$LRU_SIZE"
11475
11476         local SLEEP=30
11477
11478         # We know that lru resize allows one client to hold $LIMIT locks
11479         # for 10h. After that locks begin to be killed by client.
11480         local MAX_HRS=10
11481         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
11482         log "LIMIT=$LIMIT"
11483         if [ $LIMIT -lt $LRU_SIZE ]; then
11484                 skip "Limit is too small $LIMIT"
11485         fi
11486
11487         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
11488         # killing locks. Some time was spent for creating locks. This means
11489         # that up to the moment of sleep finish we must have killed some of
11490         # them (10-100 locks). This depends on how fast ther were created.
11491         # Many of them were touched in almost the same moment and thus will
11492         # be killed in groups.
11493         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE))
11494
11495         # Use $LRU_SIZE_B here to take into account real number of locks
11496         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
11497         local LRU_SIZE_B=$LRU_SIZE
11498         log "LVF=$LVF"
11499         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
11500         log "OLD_LVF=$OLD_LVF"
11501         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
11502
11503         # Let's make sure that we really have some margin. Client checks
11504         # cached locks every 10 sec.
11505         SLEEP=$((SLEEP+20))
11506         log "Sleep ${SLEEP} sec"
11507         local SEC=0
11508         while ((SEC<$SLEEP)); do
11509                 echo -n "..."
11510                 sleep 5
11511                 SEC=$((SEC+5))
11512                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
11513                 echo -n "$LRU_SIZE"
11514         done
11515         echo ""
11516         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
11517         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
11518
11519         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
11520                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
11521                 unlinkmany $DIR/$tdir/f $NR
11522                 return
11523         }
11524
11525         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
11526         log "unlink $NR files at $DIR/$tdir"
11527         unlinkmany $DIR/$tdir/f $NR
11528 }
11529 run_test 124a "lru resize ======================================="
11530
11531 get_max_pool_limit()
11532 {
11533         local limit=$($LCTL get_param \
11534                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
11535         local max=0
11536         for l in $limit; do
11537                 if [[ $l -gt $max ]]; then
11538                         max=$l
11539                 fi
11540         done
11541         echo $max
11542 }
11543
11544 test_124b() {
11545         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11546         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11547                 skip_env "no lru resize on server"
11548
11549         LIMIT=$(get_max_pool_limit)
11550
11551         NR=$(($(default_lru_size)*20))
11552         if [[ $NR -gt $LIMIT ]]; then
11553                 log "Limit lock number by $LIMIT locks"
11554                 NR=$LIMIT
11555         fi
11556
11557         IFree=$(mdsrate_inodes_available)
11558         if [ $IFree -lt $NR ]; then
11559                 log "Limit lock number by $IFree inodes"
11560                 NR=$IFree
11561         fi
11562
11563         lru_resize_disable mdc
11564         test_mkdir -p $DIR/$tdir/disable_lru_resize
11565
11566         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
11567         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
11568         cancel_lru_locks mdc
11569         stime=`date +%s`
11570         PID=""
11571         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11572         PID="$PID $!"
11573         sleep 2
11574         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11575         PID="$PID $!"
11576         sleep 2
11577         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11578         PID="$PID $!"
11579         wait $PID
11580         etime=`date +%s`
11581         nolruresize_delta=$((etime-stime))
11582         log "ls -la time: $nolruresize_delta seconds"
11583         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
11584         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
11585
11586         lru_resize_enable mdc
11587         test_mkdir -p $DIR/$tdir/enable_lru_resize
11588
11589         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
11590         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
11591         cancel_lru_locks mdc
11592         stime=`date +%s`
11593         PID=""
11594         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11595         PID="$PID $!"
11596         sleep 2
11597         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11598         PID="$PID $!"
11599         sleep 2
11600         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11601         PID="$PID $!"
11602         wait $PID
11603         etime=`date +%s`
11604         lruresize_delta=$((etime-stime))
11605         log "ls -la time: $lruresize_delta seconds"
11606         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
11607
11608         if [ $lruresize_delta -gt $nolruresize_delta ]; then
11609                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
11610         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
11611                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
11612         else
11613                 log "lru resize performs the same with no lru resize"
11614         fi
11615         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
11616 }
11617 run_test 124b "lru resize (performance test) ======================="
11618
11619 test_124c() {
11620         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11621         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11622                 skip_env "no lru resize on server"
11623
11624         # cache ununsed locks on client
11625         local nr=100
11626         cancel_lru_locks mdc
11627         test_mkdir $DIR/$tdir
11628         createmany -o $DIR/$tdir/f $nr ||
11629                 error "failed to create $nr files in $DIR/$tdir"
11630         ls -l $DIR/$tdir > /dev/null
11631
11632         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
11633         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11634         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
11635         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
11636         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
11637
11638         # set lru_max_age to 1 sec
11639         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
11640         echo "sleep $((recalc_p * 2)) seconds..."
11641         sleep $((recalc_p * 2))
11642
11643         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
11644         # restore lru_max_age
11645         $LCTL set_param -n $nsdir.lru_max_age $max_age
11646         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
11647         unlinkmany $DIR/$tdir/f $nr
11648 }
11649 run_test 124c "LRUR cancel very aged locks"
11650
11651 test_124d() {
11652         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11653         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11654                 skip_env "no lru resize on server"
11655
11656         # cache ununsed locks on client
11657         local nr=100
11658
11659         lru_resize_disable mdc
11660         stack_trap "lru_resize_enable mdc" EXIT
11661
11662         cancel_lru_locks mdc
11663
11664         # asynchronous object destroy at MDT could cause bl ast to client
11665         test_mkdir $DIR/$tdir
11666         createmany -o $DIR/$tdir/f $nr ||
11667                 error "failed to create $nr files in $DIR/$tdir"
11668         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
11669
11670         ls -l $DIR/$tdir > /dev/null
11671
11672         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
11673         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11674         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
11675         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
11676
11677         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
11678
11679         # set lru_max_age to 1 sec
11680         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
11681         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
11682
11683         echo "sleep $((recalc_p * 2)) seconds..."
11684         sleep $((recalc_p * 2))
11685
11686         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
11687
11688         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
11689 }
11690 run_test 124d "cancel very aged locks if lru-resize diasbaled"
11691
11692 test_125() { # 13358
11693         $LCTL get_param -n llite.*.client_type | grep -q local ||
11694                 skip "must run as local client"
11695         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
11696                 skip_env "must have acl enabled"
11697         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
11698
11699         test_mkdir $DIR/$tdir
11700         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
11701         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
11702         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
11703 }
11704 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
11705
11706 test_126() { # bug 12829/13455
11707         $GSS && skip_env "must run as gss disabled"
11708         $LCTL get_param -n llite.*.client_type | grep -q local ||
11709                 skip "must run as local client"
11710         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
11711
11712         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
11713         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
11714         rm -f $DIR/$tfile
11715         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
11716 }
11717 run_test 126 "check that the fsgid provided by the client is taken into account"
11718
11719 test_127a() { # bug 15521
11720         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11721         local name count samp unit min max sum sumsq
11722
11723         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
11724         echo "stats before reset"
11725         $LCTL get_param osc.*.stats
11726         $LCTL set_param osc.*.stats=0
11727         local fsize=$((2048 * 1024))
11728
11729         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
11730         cancel_lru_locks osc
11731         dd if=$DIR/$tfile of=/dev/null bs=$fsize
11732
11733         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
11734         stack_trap "rm -f $TMP/$tfile.tmp"
11735         while read name count samp unit min max sum sumsq; do
11736                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
11737                 [ ! $min ] && error "Missing min value for $name proc entry"
11738                 eval $name=$count || error "Wrong proc format"
11739
11740                 case $name in
11741                 read_bytes|write_bytes)
11742                         [[ "$unit" =~ "bytes" ]] ||
11743                                 error "unit is not 'bytes': $unit"
11744                         (( $min >= 4096 )) || error "min is too small: $min"
11745                         (( $min <= $fsize )) || error "min is too big: $min"
11746                         (( $max >= 4096 )) || error "max is too small: $max"
11747                         (( $max <= $fsize )) || error "max is too big: $max"
11748                         (( $sum == $fsize )) || error "sum is wrong: $sum"
11749                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
11750                                 error "sumsquare is too small: $sumsq"
11751                         (( $sumsq <= $fsize * $fsize )) ||
11752                                 error "sumsquare is too big: $sumsq"
11753                         ;;
11754                 ost_read|ost_write)
11755                         [[ "$unit" =~ "usec" ]] ||
11756                                 error "unit is not 'usec': $unit"
11757                         ;;
11758                 *)      ;;
11759                 esac
11760         done < $DIR/$tfile.tmp
11761
11762         #check that we actually got some stats
11763         [ "$read_bytes" ] || error "Missing read_bytes stats"
11764         [ "$write_bytes" ] || error "Missing write_bytes stats"
11765         [ "$read_bytes" != 0 ] || error "no read done"
11766         [ "$write_bytes" != 0 ] || error "no write done"
11767 }
11768 run_test 127a "verify the client stats are sane"
11769
11770 test_127b() { # bug LU-333
11771         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11772         local name count samp unit min max sum sumsq
11773
11774         echo "stats before reset"
11775         $LCTL get_param llite.*.stats
11776         $LCTL set_param llite.*.stats=0
11777
11778         # perform 2 reads and writes so MAX is different from SUM.
11779         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
11780         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
11781         cancel_lru_locks osc
11782         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
11783         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
11784
11785         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
11786         stack_trap "rm -f $TMP/$tfile.tmp"
11787         while read name count samp unit min max sum sumsq; do
11788                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
11789                 eval $name=$count || error "Wrong proc format"
11790
11791                 case $name in
11792                 read_bytes|write_bytes)
11793                         [[ "$unit" =~ "bytes" ]] ||
11794                                 error "unit is not 'bytes': $unit"
11795                         (( $count == 2 )) || error "count is not 2: $count"
11796                         (( $min == $PAGE_SIZE )) ||
11797                                 error "min is not $PAGE_SIZE: $min"
11798                         (( $max == $PAGE_SIZE )) ||
11799                                 error "max is not $PAGE_SIZE: $max"
11800                         (( $sum == $PAGE_SIZE * 2 )) ||
11801                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
11802                         ;;
11803                 read|write)
11804                         [[ "$unit" =~ "usec" ]] ||
11805                                 error "unit is not 'usec': $unit"
11806                         ;;
11807                 *)      ;;
11808                 esac
11809         done < $TMP/$tfile.tmp
11810
11811         #check that we actually got some stats
11812         [ "$read_bytes" ] || error "Missing read_bytes stats"
11813         [ "$write_bytes" ] || error "Missing write_bytes stats"
11814         [ "$read_bytes" != 0 ] || error "no read done"
11815         [ "$write_bytes" != 0 ] || error "no write done"
11816 }
11817 run_test 127b "verify the llite client stats are sane"
11818
11819 test_127c() { # LU-12394
11820         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
11821         local size
11822         local bsize
11823         local reads
11824         local writes
11825         local count
11826
11827         $LCTL set_param llite.*.extents_stats=1
11828         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
11829
11830         # Use two stripes so there is enough space in default config
11831         $LFS setstripe -c 2 $DIR/$tfile
11832
11833         # Extent stats start at 0-4K and go in power of two buckets
11834         # LL_HIST_START = 12 --> 2^12 = 4K
11835         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
11836         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
11837         # small configs
11838         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
11839                 do
11840                 # Write and read, 2x each, second time at a non-zero offset
11841                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
11842                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
11843                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
11844                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
11845                 rm -f $DIR/$tfile
11846         done
11847
11848         $LCTL get_param llite.*.extents_stats
11849
11850         count=2
11851         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
11852                 do
11853                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
11854                                 grep -m 1 $bsize)
11855                 reads=$(echo $bucket | awk '{print $5}')
11856                 writes=$(echo $bucket | awk '{print $9}')
11857                 [ "$reads" -eq $count ] ||
11858                         error "$reads reads in < $bsize bucket, expect $count"
11859                 [ "$writes" -eq $count ] ||
11860                         error "$writes writes in < $bsize bucket, expect $count"
11861         done
11862
11863         # Test mmap write and read
11864         $LCTL set_param llite.*.extents_stats=c
11865         size=512
11866         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
11867         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
11868         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
11869
11870         $LCTL get_param llite.*.extents_stats
11871
11872         count=$(((size*1024) / PAGE_SIZE))
11873
11874         bsize=$((2 * PAGE_SIZE / 1024))K
11875
11876         bucket=$($LCTL get_param -n llite.*.extents_stats |
11877                         grep -m 1 $bsize)
11878         reads=$(echo $bucket | awk '{print $5}')
11879         writes=$(echo $bucket | awk '{print $9}')
11880         # mmap writes fault in the page first, creating an additonal read
11881         [ "$reads" -eq $((2 * count)) ] ||
11882                 error "$reads reads in < $bsize bucket, expect $count"
11883         [ "$writes" -eq $count ] ||
11884                 error "$writes writes in < $bsize bucket, expect $count"
11885 }
11886 run_test 127c "test llite extent stats with regular & mmap i/o"
11887
11888 test_128() { # bug 15212
11889         touch $DIR/$tfile
11890         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
11891                 find $DIR/$tfile
11892                 find $DIR/$tfile
11893         EOF
11894
11895         result=$(grep error $TMP/$tfile.log)
11896         rm -f $DIR/$tfile $TMP/$tfile.log
11897         [ -z "$result" ] ||
11898                 error "consecutive find's under interactive lfs failed"
11899 }
11900 run_test 128 "interactive lfs for 2 consecutive find's"
11901
11902 set_dir_limits () {
11903         local mntdev
11904         local canondev
11905         local node
11906
11907         local ldproc=/proc/fs/ldiskfs
11908         local facets=$(get_facets MDS)
11909
11910         for facet in ${facets//,/ }; do
11911                 canondev=$(ldiskfs_canon \
11912                            *.$(convert_facet2label $facet).mntdev $facet)
11913                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
11914                         ldproc=/sys/fs/ldiskfs
11915                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
11916                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
11917         done
11918 }
11919
11920 check_mds_dmesg() {
11921         local facets=$(get_facets MDS)
11922         for facet in ${facets//,/ }; do
11923                 do_facet $facet "dmesg | tail -3 | grep -q $1" && return 0
11924         done
11925         return 1
11926 }
11927
11928 test_129() {
11929         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11930         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
11931                 skip "Need MDS version with at least 2.5.56"
11932         if [ "$mds1_FSTYPE" != ldiskfs ]; then
11933                 skip_env "ldiskfs only test"
11934         fi
11935         remote_mds_nodsh && skip "remote MDS with nodsh"
11936
11937         local ENOSPC=28
11938         local EFBIG=27
11939         local has_warning=false
11940
11941         rm -rf $DIR/$tdir
11942         mkdir -p $DIR/$tdir
11943
11944         # block size of mds1
11945         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 5))
11946         set_dir_limits $maxsize $maxsize
11947         local dirsize=$(stat -c%s "$DIR/$tdir")
11948         local nfiles=0
11949         while [[ $dirsize -le $maxsize ]]; do
11950                 $MULTIOP $DIR/$tdir/file_base_$nfiles Oc
11951                 rc=$?
11952                 if ! $has_warning; then
11953                         check_mds_dmesg '"is approaching"' && has_warning=true
11954                 fi
11955                 # check two errors:
11956                 # ENOSPC for new ext4 max_dir_size (kernel commit df981d03ee)
11957                 # EFBIG for previous versions included in ldiskfs series
11958                 if [ $rc -eq $EFBIG ] || [ $rc -eq $ENOSPC ]; then
11959                         set_dir_limits 0 0
11960                         echo "return code $rc received as expected"
11961
11962                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
11963                                 error_exit "create failed w/o dir size limit"
11964
11965                         check_mds_dmesg '"has reached"' ||
11966                                 error_exit "reached message should be output"
11967
11968                         [ $has_warning = "false" ] &&
11969                                 error_exit "warning message should be output"
11970
11971                         dirsize=$(stat -c%s "$DIR/$tdir")
11972
11973                         [[ $dirsize -ge $maxsize ]] && return 0
11974                         error_exit "current dir size $dirsize, " \
11975                                    "previous limit $maxsize"
11976                 elif [ $rc -ne 0 ]; then
11977                         set_dir_limits 0 0
11978                         error_exit "return $rc received instead of expected " \
11979                                    "$EFBIG or $ENOSPC, files in dir $dirsize"
11980                 fi
11981                 nfiles=$((nfiles + 1))
11982                 dirsize=$(stat -c%s "$DIR/$tdir")
11983         done
11984
11985         set_dir_limits 0 0
11986         error "exceeded dir size limit $maxsize($MDSCOUNT) : $dirsize bytes"
11987 }
11988 run_test 129 "test directory size limit ========================"
11989
11990 OLDIFS="$IFS"
11991 cleanup_130() {
11992         trap 0
11993         IFS="$OLDIFS"
11994 }
11995
11996 test_130a() {
11997         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11998         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
11999
12000         trap cleanup_130 EXIT RETURN
12001
12002         local fm_file=$DIR/$tfile
12003         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
12004         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
12005                 error "dd failed for $fm_file"
12006
12007         # LU-1795: test filefrag/FIEMAP once, even if unsupported
12008         filefrag -ves $fm_file
12009         RC=$?
12010         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12011                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12012         [ $RC != 0 ] && error "filefrag $fm_file failed"
12013
12014         filefrag_op=$(filefrag -ve -k $fm_file |
12015                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12016         lun=$($LFS getstripe -i $fm_file)
12017
12018         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
12019         IFS=$'\n'
12020         tot_len=0
12021         for line in $filefrag_op
12022         do
12023                 frag_lun=`echo $line | cut -d: -f5`
12024                 ext_len=`echo $line | cut -d: -f4`
12025                 if (( $frag_lun != $lun )); then
12026                         cleanup_130
12027                         error "FIEMAP on 1-stripe file($fm_file) failed"
12028                         return
12029                 fi
12030                 (( tot_len += ext_len ))
12031         done
12032
12033         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
12034                 cleanup_130
12035                 error "FIEMAP on 1-stripe file($fm_file) failed;"
12036                 return
12037         fi
12038
12039         cleanup_130
12040
12041         echo "FIEMAP on single striped file succeeded"
12042 }
12043 run_test 130a "FIEMAP (1-stripe file)"
12044
12045 test_130b() {
12046         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12047
12048         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12049         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12050
12051         trap cleanup_130 EXIT RETURN
12052
12053         local fm_file=$DIR/$tfile
12054         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12055                         error "setstripe on $fm_file"
12056         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12057                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12058
12059         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
12060                 error "dd failed on $fm_file"
12061
12062         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12063         filefrag_op=$(filefrag -ve -k $fm_file |
12064                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12065
12066         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12067                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12068
12069         IFS=$'\n'
12070         tot_len=0
12071         num_luns=1
12072         for line in $filefrag_op
12073         do
12074                 frag_lun=$(echo $line | cut -d: -f5 |
12075                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12076                 ext_len=$(echo $line | cut -d: -f4)
12077                 if (( $frag_lun != $last_lun )); then
12078                         if (( tot_len != 1024 )); then
12079                                 cleanup_130
12080                                 error "FIEMAP on $fm_file failed; returned " \
12081                                 "len $tot_len for OST $last_lun instead of 1024"
12082                                 return
12083                         else
12084                                 (( num_luns += 1 ))
12085                                 tot_len=0
12086                         fi
12087                 fi
12088                 (( tot_len += ext_len ))
12089                 last_lun=$frag_lun
12090         done
12091         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
12092                 cleanup_130
12093                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12094                         "luns or wrong len for OST $last_lun"
12095                 return
12096         fi
12097
12098         cleanup_130
12099
12100         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
12101 }
12102 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
12103
12104 test_130c() {
12105         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12106
12107         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12108         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12109
12110         trap cleanup_130 EXIT RETURN
12111
12112         local fm_file=$DIR/$tfile
12113         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
12114         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12115                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12116
12117         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
12118                         error "dd failed on $fm_file"
12119
12120         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12121         filefrag_op=$(filefrag -ve -k $fm_file |
12122                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12123
12124         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12125                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12126
12127         IFS=$'\n'
12128         tot_len=0
12129         num_luns=1
12130         for line in $filefrag_op
12131         do
12132                 frag_lun=$(echo $line | cut -d: -f5 |
12133                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12134                 ext_len=$(echo $line | cut -d: -f4)
12135                 if (( $frag_lun != $last_lun )); then
12136                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
12137                         if (( logical != 512 )); then
12138                                 cleanup_130
12139                                 error "FIEMAP on $fm_file failed; returned " \
12140                                 "logical start for lun $logical instead of 512"
12141                                 return
12142                         fi
12143                         if (( tot_len != 512 )); then
12144                                 cleanup_130
12145                                 error "FIEMAP on $fm_file failed; returned " \
12146                                 "len $tot_len for OST $last_lun instead of 1024"
12147                                 return
12148                         else
12149                                 (( num_luns += 1 ))
12150                                 tot_len=0
12151                         fi
12152                 fi
12153                 (( tot_len += ext_len ))
12154                 last_lun=$frag_lun
12155         done
12156         if (( num_luns != 2 || tot_len != 512 )); then
12157                 cleanup_130
12158                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12159                         "luns or wrong len for OST $last_lun"
12160                 return
12161         fi
12162
12163         cleanup_130
12164
12165         echo "FIEMAP on 2-stripe file with hole succeeded"
12166 }
12167 run_test 130c "FIEMAP (2-stripe file with hole)"
12168
12169 test_130d() {
12170         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
12171
12172         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12173         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12174
12175         trap cleanup_130 EXIT RETURN
12176
12177         local fm_file=$DIR/$tfile
12178         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12179                         error "setstripe on $fm_file"
12180         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12181                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12182
12183         local actual_stripe_count=$($LFS getstripe -c $fm_file)
12184         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
12185                 error "dd failed on $fm_file"
12186
12187         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12188         filefrag_op=$(filefrag -ve -k $fm_file |
12189                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12190
12191         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12192                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12193
12194         IFS=$'\n'
12195         tot_len=0
12196         num_luns=1
12197         for line in $filefrag_op
12198         do
12199                 frag_lun=$(echo $line | cut -d: -f5 |
12200                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12201                 ext_len=$(echo $line | cut -d: -f4)
12202                 if (( $frag_lun != $last_lun )); then
12203                         if (( tot_len != 1024 )); then
12204                                 cleanup_130
12205                                 error "FIEMAP on $fm_file failed; returned " \
12206                                 "len $tot_len for OST $last_lun instead of 1024"
12207                                 return
12208                         else
12209                                 (( num_luns += 1 ))
12210                                 tot_len=0
12211                         fi
12212                 fi
12213                 (( tot_len += ext_len ))
12214                 last_lun=$frag_lun
12215         done
12216         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
12217                 cleanup_130
12218                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12219                         "luns or wrong len for OST $last_lun"
12220                 return
12221         fi
12222
12223         cleanup_130
12224
12225         echo "FIEMAP on N-stripe file succeeded"
12226 }
12227 run_test 130d "FIEMAP (N-stripe file)"
12228
12229 test_130e() {
12230         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12231
12232         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12233         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12234
12235         trap cleanup_130 EXIT RETURN
12236
12237         local fm_file=$DIR/$tfile
12238         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
12239         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12240                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12241
12242         NUM_BLKS=512
12243         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
12244         for ((i = 0; i < $NUM_BLKS; i++))
12245         do
12246                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) conv=notrunc > /dev/null 2>&1
12247         done
12248
12249         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12250         filefrag_op=$(filefrag -ve -k $fm_file |
12251                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12252
12253         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12254                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12255
12256         IFS=$'\n'
12257         tot_len=0
12258         num_luns=1
12259         for line in $filefrag_op
12260         do
12261                 frag_lun=$(echo $line | cut -d: -f5 |
12262                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12263                 ext_len=$(echo $line | cut -d: -f4)
12264                 if (( $frag_lun != $last_lun )); then
12265                         if (( tot_len != $EXPECTED_LEN )); then
12266                                 cleanup_130
12267                                 error "FIEMAP on $fm_file failed; returned " \
12268                                 "len $tot_len for OST $last_lun instead " \
12269                                 "of $EXPECTED_LEN"
12270                                 return
12271                         else
12272                                 (( num_luns += 1 ))
12273                                 tot_len=0
12274                         fi
12275                 fi
12276                 (( tot_len += ext_len ))
12277                 last_lun=$frag_lun
12278         done
12279         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
12280                 cleanup_130
12281                 error "FIEMAP on $fm_file failed; returned wrong number " \
12282                         "of luns or wrong len for OST $last_lun"
12283                 return
12284         fi
12285
12286         cleanup_130
12287
12288         echo "FIEMAP with continuation calls succeeded"
12289 }
12290 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
12291
12292 test_130f() {
12293         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12294         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12295
12296         local fm_file=$DIR/$tfile
12297         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
12298                 error "multiop create with lov_delay_create on $fm_file"
12299
12300         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12301         filefrag_extents=$(filefrag -vek $fm_file |
12302                            awk '/extents? found/ { print $2 }')
12303         if [[ "$filefrag_extents" != "0" ]]; then
12304                 error "FIEMAP on $fm_file failed; " \
12305                       "returned $filefrag_extents expected 0"
12306         fi
12307
12308         rm -f $fm_file
12309 }
12310 run_test 130f "FIEMAP (unstriped file)"
12311
12312 # Test for writev/readv
12313 test_131a() {
12314         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
12315                 error "writev test failed"
12316         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
12317                 error "readv failed"
12318         rm -f $DIR/$tfile
12319 }
12320 run_test 131a "test iov's crossing stripe boundary for writev/readv"
12321
12322 test_131b() {
12323         local fsize=$((524288 + 1048576 + 1572864))
12324         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
12325                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12326                         error "append writev test failed"
12327
12328         ((fsize += 1572864 + 1048576))
12329         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
12330                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12331                         error "append writev test failed"
12332         rm -f $DIR/$tfile
12333 }
12334 run_test 131b "test append writev"
12335
12336 test_131c() {
12337         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
12338         error "NOT PASS"
12339 }
12340 run_test 131c "test read/write on file w/o objects"
12341
12342 test_131d() {
12343         rwv -f $DIR/$tfile -w -n 1 1572864
12344         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
12345         if [ "$NOB" != 1572864 ]; then
12346                 error "Short read filed: read $NOB bytes instead of 1572864"
12347         fi
12348         rm -f $DIR/$tfile
12349 }
12350 run_test 131d "test short read"
12351
12352 test_131e() {
12353         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
12354         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
12355         error "read hitting hole failed"
12356         rm -f $DIR/$tfile
12357 }
12358 run_test 131e "test read hitting hole"
12359
12360 check_stats() {
12361         local facet=$1
12362         local op=$2
12363         local want=${3:-0}
12364         local res
12365
12366         case $facet in
12367         mds*) res=$(do_facet $facet \
12368                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
12369                  ;;
12370         ost*) res=$(do_facet $facet \
12371                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
12372                  ;;
12373         *) error "Wrong facet '$facet'" ;;
12374         esac
12375         [ "$res" ] || error "The counter for $op on $facet was not incremented"
12376         # if the argument $3 is zero, it means any stat increment is ok.
12377         if [[ $want -gt 0 ]]; then
12378                 local count=$(echo $res | awk '{ print $2 }')
12379                 [[ $count -ne $want ]] &&
12380                         error "The $op counter on $facet is $count, not $want"
12381         fi
12382 }
12383
12384 test_133a() {
12385         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12386         remote_ost_nodsh && skip "remote OST with nodsh"
12387         remote_mds_nodsh && skip "remote MDS with nodsh"
12388         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
12389                 skip_env "MDS doesn't support rename stats"
12390
12391         local testdir=$DIR/${tdir}/stats_testdir
12392
12393         mkdir -p $DIR/${tdir}
12394
12395         # clear stats.
12396         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12397         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12398
12399         # verify mdt stats first.
12400         mkdir ${testdir} || error "mkdir failed"
12401         check_stats $SINGLEMDS "mkdir" 1
12402         touch ${testdir}/${tfile} || error "touch failed"
12403         check_stats $SINGLEMDS "open" 1
12404         check_stats $SINGLEMDS "close" 1
12405         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
12406                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
12407                 check_stats $SINGLEMDS "mknod" 2
12408         }
12409         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
12410         check_stats $SINGLEMDS "unlink" 1
12411         rm -f ${testdir}/${tfile} || error "file remove failed"
12412         check_stats $SINGLEMDS "unlink" 2
12413
12414         # remove working dir and check mdt stats again.
12415         rmdir ${testdir} || error "rmdir failed"
12416         check_stats $SINGLEMDS "rmdir" 1
12417
12418         local testdir1=$DIR/${tdir}/stats_testdir1
12419         mkdir -p ${testdir}
12420         mkdir -p ${testdir1}
12421         touch ${testdir1}/test1
12422         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
12423         check_stats $SINGLEMDS "crossdir_rename" 1
12424
12425         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
12426         check_stats $SINGLEMDS "samedir_rename" 1
12427
12428         rm -rf $DIR/${tdir}
12429 }
12430 run_test 133a "Verifying MDT stats ========================================"
12431
12432 test_133b() {
12433         local res
12434
12435         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12436         remote_ost_nodsh && skip "remote OST with nodsh"
12437         remote_mds_nodsh && skip "remote MDS with nodsh"
12438
12439         local testdir=$DIR/${tdir}/stats_testdir
12440
12441         mkdir -p ${testdir} || error "mkdir failed"
12442         touch ${testdir}/${tfile} || error "touch failed"
12443         cancel_lru_locks mdc
12444
12445         # clear stats.
12446         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12447         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12448
12449         # extra mdt stats verification.
12450         chmod 444 ${testdir}/${tfile} || error "chmod failed"
12451         check_stats $SINGLEMDS "setattr" 1
12452         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12453         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
12454         then            # LU-1740
12455                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
12456                 check_stats $SINGLEMDS "getattr" 1
12457         fi
12458         rm -rf $DIR/${tdir}
12459
12460         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
12461         # so the check below is not reliable
12462         [ $MDSCOUNT -eq 1 ] || return 0
12463
12464         # Sleep to avoid a cached response.
12465         #define OBD_STATFS_CACHE_SECONDS 1
12466         sleep 2
12467         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12468         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12469         $LFS df || error "lfs failed"
12470         check_stats $SINGLEMDS "statfs" 1
12471
12472         # check aggregated statfs (LU-10018)
12473         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
12474                 return 0
12475         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
12476                 return 0
12477         sleep 2
12478         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12479         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12480         df $DIR
12481         check_stats $SINGLEMDS "statfs" 1
12482
12483         # We want to check that the client didn't send OST_STATFS to
12484         # ost1 but the MDT also uses OST_STATFS for precreate. So some
12485         # extra care is needed here.
12486         if remote_mds; then
12487                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
12488                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
12489
12490                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
12491                 [ "$res" ] && error "OST got STATFS"
12492         fi
12493
12494         return 0
12495 }
12496 run_test 133b "Verifying extra MDT stats =================================="
12497
12498 test_133c() {
12499         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12500         remote_ost_nodsh && skip "remote OST with nodsh"
12501         remote_mds_nodsh && skip "remote MDS with nodsh"
12502
12503         local testdir=$DIR/$tdir/stats_testdir
12504
12505         test_mkdir -p $testdir
12506
12507         # verify obdfilter stats.
12508         $LFS setstripe -c 1 -i 0 $testdir/$tfile
12509         sync
12510         cancel_lru_locks osc
12511         wait_delete_completed
12512
12513         # clear stats.
12514         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12515         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12516
12517         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
12518                 error "dd failed"
12519         sync
12520         cancel_lru_locks osc
12521         check_stats ost1 "write" 1
12522
12523         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
12524         check_stats ost1 "read" 1
12525
12526         > $testdir/$tfile || error "truncate failed"
12527         check_stats ost1 "punch" 1
12528
12529         rm -f $testdir/$tfile || error "file remove failed"
12530         wait_delete_completed
12531         check_stats ost1 "destroy" 1
12532
12533         rm -rf $DIR/$tdir
12534 }
12535 run_test 133c "Verifying OST stats ========================================"
12536
12537 order_2() {
12538         local value=$1
12539         local orig=$value
12540         local order=1
12541
12542         while [ $value -ge 2 ]; do
12543                 order=$((order*2))
12544                 value=$((value/2))
12545         done
12546
12547         if [ $orig -gt $order ]; then
12548                 order=$((order*2))
12549         fi
12550         echo $order
12551 }
12552
12553 size_in_KMGT() {
12554     local value=$1
12555     local size=('K' 'M' 'G' 'T');
12556     local i=0
12557     local size_string=$value
12558
12559     while [ $value -ge 1024 ]; do
12560         if [ $i -gt 3 ]; then
12561             #T is the biggest unit we get here, if that is bigger,
12562             #just return XXXT
12563             size_string=${value}T
12564             break
12565         fi
12566         value=$((value >> 10))
12567         if [ $value -lt 1024 ]; then
12568             size_string=${value}${size[$i]}
12569             break
12570         fi
12571         i=$((i + 1))
12572     done
12573
12574     echo $size_string
12575 }
12576
12577 get_rename_size() {
12578         local size=$1
12579         local context=${2:-.}
12580         local sample=$(do_facet $SINGLEMDS $LCTL \
12581                 get_param mdt.$FSNAME-MDT0000.rename_stats |
12582                 grep -A1 $context |
12583                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
12584         echo $sample
12585 }
12586
12587 test_133d() {
12588         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12589         remote_ost_nodsh && skip "remote OST with nodsh"
12590         remote_mds_nodsh && skip "remote MDS with nodsh"
12591         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
12592                 skip_env "MDS doesn't support rename stats"
12593
12594         local testdir1=$DIR/${tdir}/stats_testdir1
12595         local testdir2=$DIR/${tdir}/stats_testdir2
12596         mkdir -p $DIR/${tdir}
12597
12598         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
12599
12600         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
12601         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
12602
12603         createmany -o $testdir1/test 512 || error "createmany failed"
12604
12605         # check samedir rename size
12606         mv ${testdir1}/test0 ${testdir1}/test_0
12607
12608         local testdir1_size=$(ls -l $DIR/${tdir} |
12609                 awk '/stats_testdir1/ {print $5}')
12610         local testdir2_size=$(ls -l $DIR/${tdir} |
12611                 awk '/stats_testdir2/ {print $5}')
12612
12613         testdir1_size=$(order_2 $testdir1_size)
12614         testdir2_size=$(order_2 $testdir2_size)
12615
12616         testdir1_size=$(size_in_KMGT $testdir1_size)
12617         testdir2_size=$(size_in_KMGT $testdir2_size)
12618
12619         echo "source rename dir size: ${testdir1_size}"
12620         echo "target rename dir size: ${testdir2_size}"
12621
12622         local cmd="do_facet $SINGLEMDS $LCTL "
12623         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
12624
12625         eval $cmd || error "$cmd failed"
12626         local samedir=$($cmd | grep 'same_dir')
12627         local same_sample=$(get_rename_size $testdir1_size)
12628         [ -z "$samedir" ] && error "samedir_rename_size count error"
12629         [[ $same_sample -eq 1 ]] ||
12630                 error "samedir_rename_size error $same_sample"
12631         echo "Check same dir rename stats success"
12632
12633         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
12634
12635         # check crossdir rename size
12636         mv ${testdir1}/test_0 ${testdir2}/test_0
12637
12638         testdir1_size=$(ls -l $DIR/${tdir} |
12639                 awk '/stats_testdir1/ {print $5}')
12640         testdir2_size=$(ls -l $DIR/${tdir} |
12641                 awk '/stats_testdir2/ {print $5}')
12642
12643         testdir1_size=$(order_2 $testdir1_size)
12644         testdir2_size=$(order_2 $testdir2_size)
12645
12646         testdir1_size=$(size_in_KMGT $testdir1_size)
12647         testdir2_size=$(size_in_KMGT $testdir2_size)
12648
12649         echo "source rename dir size: ${testdir1_size}"
12650         echo "target rename dir size: ${testdir2_size}"
12651
12652         eval $cmd || error "$cmd failed"
12653         local crossdir=$($cmd | grep 'crossdir')
12654         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
12655         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
12656         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
12657         [[ $src_sample -eq 1 ]] ||
12658                 error "crossdir_rename_size error $src_sample"
12659         [[ $tgt_sample -eq 1 ]] ||
12660                 error "crossdir_rename_size error $tgt_sample"
12661         echo "Check cross dir rename stats success"
12662         rm -rf $DIR/${tdir}
12663 }
12664 run_test 133d "Verifying rename_stats ========================================"
12665
12666 test_133e() {
12667         remote_mds_nodsh && skip "remote MDS with nodsh"
12668         remote_ost_nodsh && skip "remote OST with nodsh"
12669         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12670
12671         local testdir=$DIR/${tdir}/stats_testdir
12672         local ctr f0 f1 bs=32768 count=42 sum
12673
12674         mkdir -p ${testdir} || error "mkdir failed"
12675
12676         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
12677
12678         for ctr in {write,read}_bytes; do
12679                 sync
12680                 cancel_lru_locks osc
12681
12682                 do_facet ost1 $LCTL set_param -n \
12683                         "obdfilter.*.exports.clear=clear"
12684
12685                 if [ $ctr = write_bytes ]; then
12686                         f0=/dev/zero
12687                         f1=${testdir}/${tfile}
12688                 else
12689                         f0=${testdir}/${tfile}
12690                         f1=/dev/null
12691                 fi
12692
12693                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
12694                         error "dd failed"
12695                 sync
12696                 cancel_lru_locks osc
12697
12698                 sum=$(do_facet ost1 $LCTL get_param \
12699                         "obdfilter.*.exports.*.stats" |
12700                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
12701                                 $1 == ctr { sum += $7 }
12702                                 END { printf("%0.0f", sum) }')
12703
12704                 if ((sum != bs * count)); then
12705                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
12706                 fi
12707         done
12708
12709         rm -rf $DIR/${tdir}
12710 }
12711 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
12712
12713 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
12714
12715 # Some versions of find (4.5.11, 4.5.14) included in CentOS 7.3-7.5 do
12716 # not honor the -ignore_readdir_race option correctly. So we call
12717 # error_ignore() rather than error() in these cases. See LU-11152.
12718 error_133() {
12719         if (find --version; do_facet mds1 find --version) |
12720                 grep -q '\b4\.5\.1[1-4]\b'; then
12721                 error_ignore LU-11152 "$@"
12722         else
12723                 error "$@"
12724         fi
12725 }
12726
12727 test_133f() {
12728         # First without trusting modes.
12729         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
12730         echo "proc_dirs='$proc_dirs'"
12731         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
12732         find $proc_dirs -exec cat '{}' \; &> /dev/null
12733
12734         # Second verifying readability.
12735         $LCTL get_param -R '*' &> /dev/null
12736
12737         # Verifing writability with badarea_io.
12738         find $proc_dirs \
12739                 -ignore_readdir_race \
12740                 -type f \
12741                 -not -name force_lbug \
12742                 -not -name changelog_mask \
12743                 -exec badarea_io '{}' \; ||
12744                         error_133 "find $proc_dirs failed"
12745 }
12746 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
12747
12748 test_133g() {
12749         remote_mds_nodsh && skip "remote MDS with nodsh"
12750         remote_ost_nodsh && skip "remote OST with nodsh"
12751
12752         local facet
12753         for facet in mds1 ost1; do
12754                 local facet_ver=$(lustre_version_code $facet)
12755                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
12756                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
12757                 else
12758                         log "$facet: too old lustre for get_param -R"
12759                 fi
12760                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
12761                         do_facet $facet "$LCTL list_param -R '*' | grep '=' |
12762                                 tr -d = | egrep -v 'force_lbug|changelog_mask' |
12763                                 xargs badarea_io" ||
12764                                         error_133 "$facet badarea_io failed"
12765                 else
12766                         skip_noexit "$facet: too old lustre for get_param -R"
12767                 fi
12768         done
12769
12770         # remount the FS in case writes/reads /proc break the FS
12771         cleanup || error "failed to unmount"
12772         setup || error "failed to setup"
12773         true
12774 }
12775 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
12776
12777 test_133h() {
12778         remote_mds_nodsh && skip "remote MDS with nodsh"
12779         remote_ost_nodsh && skip "remote OST with nodsh"
12780         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
12781                 skip "Need MDS version at least 2.9.54"
12782
12783         local facet
12784
12785         for facet in client mds1 ost1; do
12786                 local facet_proc_dirs=$(do_facet $facet \
12787                                         \\\ls -d $proc_regexp 2> /dev/null)
12788                 [ -z "$facet_proc_dirs" ] && error "no proc_dirs on $facet"
12789                 echo "${facet}_proc_dirs='$facet_proc_dirs'"
12790                 # Get the list of files that are missing the terminating newline
12791                 local missing=($(do_facet $facet \
12792                         find ${facet_proc_dirs} -type f \|              \
12793                                 while read F\; do                       \
12794                                         awk -v FS='\v' -v RS='\v\v'     \
12795                                         "'END { if(NR>0 &&              \
12796                                         \\\$NF !~ /.*\\\n\$/)           \
12797                                                 print FILENAME}'"       \
12798                                         '\$F'\;                         \
12799                                 done 2>/dev/null))
12800                 [ ${#missing[*]} -eq 0 ] ||
12801                         error "files do not end with newline: ${missing[*]}"
12802         done
12803 }
12804 run_test 133h "Proc files should end with newlines"
12805
12806 test_134a() {
12807         remote_mds_nodsh && skip "remote MDS with nodsh"
12808         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
12809                 skip "Need MDS version at least 2.7.54"
12810
12811         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
12812         cancel_lru_locks mdc
12813
12814         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12815         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12816         [ $unused -eq 0 ] || error "$unused locks are not cleared"
12817
12818         local nr=1000
12819         createmany -o $DIR/$tdir/f $nr ||
12820                 error "failed to create $nr files in $DIR/$tdir"
12821         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12822
12823         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
12824         do_facet mds1 $LCTL set_param fail_loc=0x327
12825         do_facet mds1 $LCTL set_param fail_val=500
12826         touch $DIR/$tdir/m
12827
12828         echo "sleep 10 seconds ..."
12829         sleep 10
12830         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
12831
12832         do_facet mds1 $LCTL set_param fail_loc=0
12833         do_facet mds1 $LCTL set_param fail_val=0
12834         [ $lck_cnt -lt $unused ] ||
12835                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
12836
12837         rm $DIR/$tdir/m
12838         unlinkmany $DIR/$tdir/f $nr
12839 }
12840 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
12841
12842 test_134b() {
12843         remote_mds_nodsh && skip "remote MDS with nodsh"
12844         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
12845                 skip "Need MDS version at least 2.7.54"
12846
12847         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
12848         cancel_lru_locks mdc
12849
12850         local low_wm=$(do_facet mds1 $LCTL get_param -n \
12851                         ldlm.lock_reclaim_threshold_mb)
12852         # disable reclaim temporarily
12853         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
12854
12855         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
12856         do_facet mds1 $LCTL set_param fail_loc=0x328
12857         do_facet mds1 $LCTL set_param fail_val=500
12858
12859         $LCTL set_param debug=+trace
12860
12861         local nr=600
12862         createmany -o $DIR/$tdir/f $nr &
12863         local create_pid=$!
12864
12865         echo "Sleep $TIMEOUT seconds ..."
12866         sleep $TIMEOUT
12867         if ! ps -p $create_pid  > /dev/null 2>&1; then
12868                 do_facet mds1 $LCTL set_param fail_loc=0
12869                 do_facet mds1 $LCTL set_param fail_val=0
12870                 do_facet mds1 $LCTL set_param \
12871                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
12872                 error "createmany finished incorrectly!"
12873         fi
12874         do_facet mds1 $LCTL set_param fail_loc=0
12875         do_facet mds1 $LCTL set_param fail_val=0
12876         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
12877         wait $create_pid || return 1
12878
12879         unlinkmany $DIR/$tdir/f $nr
12880 }
12881 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
12882
12883 test_135() {
12884         remote_mds_nodsh && skip "remote MDS with nodsh"
12885         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
12886                 skip "Need MDS version at least 2.13.50"
12887         local fname
12888
12889         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
12890
12891 #define OBD_FAIL_PLAIN_RECORDS 0x1319
12892         #set only one record at plain llog
12893         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
12894
12895         #fill already existed plain llog each 64767
12896         #wrapping whole catalog
12897         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
12898
12899         createmany -o $DIR/$tdir/$tfile_ 64700
12900         for (( i = 0; i < 64700; i = i + 2 ))
12901         do
12902                 rm $DIR/$tdir/$tfile_$i &
12903                 rm $DIR/$tdir/$tfile_$((i + 1)) &
12904                 local pid=$!
12905                 wait $pid
12906         done
12907
12908         #waiting osp synchronization
12909         wait_delete_completed
12910 }
12911 run_test 135 "Race catalog processing"
12912
12913 test_136() {
12914         remote_mds_nodsh && skip "remote MDS with nodsh"
12915         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
12916                 skip "Need MDS version at least 2.13.50"
12917         local fname
12918
12919         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
12920         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
12921         #set only one record at plain llog
12922 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
12923         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
12924
12925         #fill already existed 2 plain llogs each 64767
12926         #wrapping whole catalog
12927         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
12928         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
12929         wait_delete_completed
12930
12931         createmany -o $DIR/$tdir/$tfile_ 10
12932         sleep 25
12933
12934         do_facet $SINGLEMDS $LCTL set_param fail_val=3
12935         for (( i = 0; i < 10; i = i + 3 ))
12936         do
12937                 rm $DIR/$tdir/$tfile_$i &
12938                 rm $DIR/$tdir/$tfile_$((i + 1)) &
12939                 local pid=$!
12940                 wait $pid
12941                 sleep 7
12942                 rm $DIR/$tdir/$tfile_$((i + 2)) &
12943         done
12944
12945         #waiting osp synchronization
12946         wait_delete_completed
12947 }
12948 run_test 136 "Race catalog processing 2"
12949
12950 test_140() { #bug-17379
12951         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12952
12953         test_mkdir $DIR/$tdir
12954         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
12955         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
12956
12957         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
12958         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
12959         local i=0
12960         while i=$((i + 1)); do
12961                 test_mkdir $i
12962                 cd $i || error "Changing to $i"
12963                 ln -s ../stat stat || error "Creating stat symlink"
12964                 # Read the symlink until ELOOP present,
12965                 # not LBUGing the system is considered success,
12966                 # we didn't overrun the stack.
12967                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
12968                 if [ $ret -ne 0 ]; then
12969                         if [ $ret -eq 40 ]; then
12970                                 break  # -ELOOP
12971                         else
12972                                 error "Open stat symlink"
12973                                         return
12974                         fi
12975                 fi
12976         done
12977         i=$((i - 1))
12978         echo "The symlink depth = $i"
12979         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
12980                 error "Invalid symlink depth"
12981
12982         # Test recursive symlink
12983         ln -s symlink_self symlink_self
12984         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
12985         echo "open symlink_self returns $ret"
12986         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
12987 }
12988 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
12989
12990 test_150() {
12991         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12992
12993         local TF="$TMP/$tfile"
12994
12995         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
12996         cp $TF $DIR/$tfile
12997         cancel_lru_locks $OSC
12998         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
12999         remount_client $MOUNT
13000         df -P $MOUNT
13001         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
13002
13003         $TRUNCATE $TF 6000
13004         $TRUNCATE $DIR/$tfile 6000
13005         cancel_lru_locks $OSC
13006         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
13007
13008         echo "12345" >>$TF
13009         echo "12345" >>$DIR/$tfile
13010         cancel_lru_locks $OSC
13011         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
13012
13013         echo "12345" >>$TF
13014         echo "12345" >>$DIR/$tfile
13015         cancel_lru_locks $OSC
13016         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
13017
13018         rm -f $TF
13019         true
13020 }
13021 run_test 150 "truncate/append tests"
13022
13023 #LU-2902 roc_hit was not able to read all values from lproc
13024 function roc_hit_init() {
13025         local list=$(comma_list $(osts_nodes))
13026         local dir=$DIR/$tdir-check
13027         local file=$dir/$tfile
13028         local BEFORE
13029         local AFTER
13030         local idx
13031
13032         test_mkdir $dir
13033         #use setstripe to do a write to every ost
13034         for i in $(seq 0 $((OSTCOUNT-1))); do
13035                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
13036                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
13037                 idx=$(printf %04x $i)
13038                 BEFORE=$(get_osd_param $list *OST*$idx stats |
13039                         awk '$1 == "cache_access" {sum += $7}
13040                                 END { printf("%0.0f", sum) }')
13041
13042                 cancel_lru_locks osc
13043                 cat $file >/dev/null
13044
13045                 AFTER=$(get_osd_param $list *OST*$idx stats |
13046                         awk '$1 == "cache_access" {sum += $7}
13047                                 END { printf("%0.0f", sum) }')
13048
13049                 echo BEFORE:$BEFORE AFTER:$AFTER
13050                 if ! let "AFTER - BEFORE == 4"; then
13051                         rm -rf $dir
13052                         error "roc_hit is not safe to use"
13053                 fi
13054                 rm $file
13055         done
13056
13057         rm -rf $dir
13058 }
13059
13060 function roc_hit() {
13061         local list=$(comma_list $(osts_nodes))
13062         echo $(get_osd_param $list '' stats |
13063                 awk '$1 == "cache_hit" {sum += $7}
13064                         END { printf("%0.0f", sum) }')
13065 }
13066
13067 function set_cache() {
13068         local on=1
13069
13070         if [ "$2" == "off" ]; then
13071                 on=0;
13072         fi
13073         local list=$(comma_list $(osts_nodes))
13074         set_osd_param $list '' $1_cache_enable $on
13075
13076         cancel_lru_locks osc
13077 }
13078
13079 test_151() {
13080         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13081         remote_ost_nodsh && skip "remote OST with nodsh"
13082
13083         local CPAGES=3
13084         local list=$(comma_list $(osts_nodes))
13085
13086         # check whether obdfilter is cache capable at all
13087         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
13088                 skip "not cache-capable obdfilter"
13089         fi
13090
13091         # check cache is enabled on all obdfilters
13092         if get_osd_param $list '' read_cache_enable | grep 0; then
13093                 skip "oss cache is disabled"
13094         fi
13095
13096         set_osd_param $list '' writethrough_cache_enable 1
13097
13098         # check write cache is enabled on all obdfilters
13099         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
13100                 skip "oss write cache is NOT enabled"
13101         fi
13102
13103         roc_hit_init
13104
13105         #define OBD_FAIL_OBD_NO_LRU  0x609
13106         do_nodes $list $LCTL set_param fail_loc=0x609
13107
13108         # pages should be in the case right after write
13109         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
13110                 error "dd failed"
13111
13112         local BEFORE=$(roc_hit)
13113         cancel_lru_locks osc
13114         cat $DIR/$tfile >/dev/null
13115         local AFTER=$(roc_hit)
13116
13117         do_nodes $list $LCTL set_param fail_loc=0
13118
13119         if ! let "AFTER - BEFORE == CPAGES"; then
13120                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
13121         fi
13122
13123         cancel_lru_locks osc
13124         # invalidates OST cache
13125         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
13126         set_osd_param $list '' read_cache_enable 0
13127         cat $DIR/$tfile >/dev/null
13128
13129         # now data shouldn't be found in the cache
13130         BEFORE=$(roc_hit)
13131         cancel_lru_locks osc
13132         cat $DIR/$tfile >/dev/null
13133         AFTER=$(roc_hit)
13134         if let "AFTER - BEFORE != 0"; then
13135                 error "IN CACHE: before: $BEFORE, after: $AFTER"
13136         fi
13137
13138         set_osd_param $list '' read_cache_enable 1
13139         rm -f $DIR/$tfile
13140 }
13141 run_test 151 "test cache on oss and controls ==============================="
13142
13143 test_152() {
13144         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13145
13146         local TF="$TMP/$tfile"
13147
13148         # simulate ENOMEM during write
13149 #define OBD_FAIL_OST_NOMEM      0x226
13150         lctl set_param fail_loc=0x80000226
13151         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13152         cp $TF $DIR/$tfile
13153         sync || error "sync failed"
13154         lctl set_param fail_loc=0
13155
13156         # discard client's cache
13157         cancel_lru_locks osc
13158
13159         # simulate ENOMEM during read
13160         lctl set_param fail_loc=0x80000226
13161         cmp $TF $DIR/$tfile || error "cmp failed"
13162         lctl set_param fail_loc=0
13163
13164         rm -f $TF
13165 }
13166 run_test 152 "test read/write with enomem ============================"
13167
13168 test_153() {
13169         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
13170 }
13171 run_test 153 "test if fdatasync does not crash ======================="
13172
13173 dot_lustre_fid_permission_check() {
13174         local fid=$1
13175         local ffid=$MOUNT/.lustre/fid/$fid
13176         local test_dir=$2
13177
13178         echo "stat fid $fid"
13179         stat $ffid > /dev/null || error "stat $ffid failed."
13180         echo "touch fid $fid"
13181         touch $ffid || error "touch $ffid failed."
13182         echo "write to fid $fid"
13183         cat /etc/hosts > $ffid || error "write $ffid failed."
13184         echo "read fid $fid"
13185         diff /etc/hosts $ffid || error "read $ffid failed."
13186         echo "append write to fid $fid"
13187         cat /etc/hosts >> $ffid || error "append write $ffid failed."
13188         echo "rename fid $fid"
13189         mv $ffid $test_dir/$tfile.1 &&
13190                 error "rename $ffid to $tfile.1 should fail."
13191         touch $test_dir/$tfile.1
13192         mv $test_dir/$tfile.1 $ffid &&
13193                 error "rename $tfile.1 to $ffid should fail."
13194         rm -f $test_dir/$tfile.1
13195         echo "truncate fid $fid"
13196         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
13197         echo "link fid $fid"
13198         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
13199         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
13200                 echo "setfacl fid $fid"
13201                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
13202                 echo "getfacl fid $fid"
13203                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
13204         fi
13205         echo "unlink fid $fid"
13206         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
13207         echo "mknod fid $fid"
13208         mknod $ffid c 1 3 && error "mknod $ffid should fail."
13209
13210         fid=[0xf00000400:0x1:0x0]
13211         ffid=$MOUNT/.lustre/fid/$fid
13212
13213         echo "stat non-exist fid $fid"
13214         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
13215         echo "write to non-exist fid $fid"
13216         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
13217         echo "link new fid $fid"
13218         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
13219
13220         mkdir -p $test_dir/$tdir
13221         touch $test_dir/$tdir/$tfile
13222         fid=$($LFS path2fid $test_dir/$tdir)
13223         rc=$?
13224         [ $rc -ne 0 ] &&
13225                 error "error: could not get fid for $test_dir/$dir/$tfile."
13226
13227         ffid=$MOUNT/.lustre/fid/$fid
13228
13229         echo "ls $fid"
13230         ls $ffid > /dev/null || error "ls $ffid failed."
13231         echo "touch $fid/$tfile.1"
13232         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
13233
13234         echo "touch $MOUNT/.lustre/fid/$tfile"
13235         touch $MOUNT/.lustre/fid/$tfile && \
13236                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
13237
13238         echo "setxattr to $MOUNT/.lustre/fid"
13239         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
13240
13241         echo "listxattr for $MOUNT/.lustre/fid"
13242         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
13243
13244         echo "delxattr from $MOUNT/.lustre/fid"
13245         setfattr -x trusted.name1 $MOUNT/.lustre/fid
13246
13247         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
13248         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
13249                 error "touch invalid fid should fail."
13250
13251         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
13252         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
13253                 error "touch non-normal fid should fail."
13254
13255         echo "rename $tdir to $MOUNT/.lustre/fid"
13256         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
13257                 error "rename to $MOUNT/.lustre/fid should fail."
13258
13259         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
13260         then            # LU-3547
13261                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
13262                 local new_obf_mode=777
13263
13264                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
13265                 chmod $new_obf_mode $DIR/.lustre/fid ||
13266                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
13267
13268                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
13269                 [ $obf_mode -eq $new_obf_mode ] ||
13270                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
13271
13272                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
13273                 chmod $old_obf_mode $DIR/.lustre/fid ||
13274                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
13275         fi
13276
13277         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
13278         fid=$($LFS path2fid $test_dir/$tfile-2)
13279
13280         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
13281         then # LU-5424
13282                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
13283                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
13284                         error "create lov data thru .lustre failed"
13285         fi
13286         echo "cp /etc/passwd $test_dir/$tfile-2"
13287         cp /etc/passwd $test_dir/$tfile-2 ||
13288                 error "copy to $test_dir/$tfile-2 failed."
13289         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
13290         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
13291                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
13292
13293         rm -rf $test_dir/tfile.lnk
13294         rm -rf $test_dir/$tfile-2
13295 }
13296
13297 test_154A() {
13298         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13299                 skip "Need MDS version at least 2.4.1"
13300
13301         local tf=$DIR/$tfile
13302         touch $tf
13303
13304         local fid=$($LFS path2fid $tf)
13305         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
13306
13307         # check that we get the same pathname back
13308         local found=$($LFS fid2path $MOUNT "$fid")
13309         [ -z "$found" ] && error "fid2path unable to get '$fid' path"
13310         [ "$found" == "$tf" ] ||
13311                 error "fid2path($fid=path2fid($tf)) = $found != $tf"
13312 }
13313 run_test 154A "lfs path2fid and fid2path basic checks"
13314
13315 test_154B() {
13316         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13317                 skip "Need MDS version at least 2.4.1"
13318
13319         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
13320         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
13321         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
13322         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
13323
13324         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
13325         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
13326
13327         # check that we get the same pathname
13328         echo "PFID: $PFID, name: $name"
13329         local FOUND=$($LFS fid2path $MOUNT "$PFID")
13330         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
13331         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
13332                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
13333
13334         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
13335 }
13336 run_test 154B "verify the ll_decode_linkea tool"
13337
13338 test_154a() {
13339         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13340         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13341         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
13342                 skip "Need MDS version at least 2.2.51"
13343         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13344
13345         cp /etc/hosts $DIR/$tfile
13346
13347         fid=$($LFS path2fid $DIR/$tfile)
13348         rc=$?
13349         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
13350
13351         dot_lustre_fid_permission_check "$fid" $DIR ||
13352                 error "dot lustre permission check $fid failed"
13353
13354         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
13355
13356         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
13357
13358         touch $MOUNT/.lustre/file &&
13359                 error "creation is not allowed under .lustre"
13360
13361         mkdir $MOUNT/.lustre/dir &&
13362                 error "mkdir is not allowed under .lustre"
13363
13364         rm -rf $DIR/$tfile
13365 }
13366 run_test 154a "Open-by-FID"
13367
13368 test_154b() {
13369         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13370         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13371         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13372         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
13373                 skip "Need MDS version at least 2.2.51"
13374
13375         local remote_dir=$DIR/$tdir/remote_dir
13376         local MDTIDX=1
13377         local rc=0
13378
13379         mkdir -p $DIR/$tdir
13380         $LFS mkdir -i $MDTIDX $remote_dir ||
13381                 error "create remote directory failed"
13382
13383         cp /etc/hosts $remote_dir/$tfile
13384
13385         fid=$($LFS path2fid $remote_dir/$tfile)
13386         rc=$?
13387         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
13388
13389         dot_lustre_fid_permission_check "$fid" $remote_dir ||
13390                 error "dot lustre permission check $fid failed"
13391         rm -rf $DIR/$tdir
13392 }
13393 run_test 154b "Open-by-FID for remote directory"
13394
13395 test_154c() {
13396         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13397                 skip "Need MDS version at least 2.4.1"
13398
13399         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
13400         local FID1=$($LFS path2fid $DIR/$tfile.1)
13401         local FID2=$($LFS path2fid $DIR/$tfile.2)
13402         local FID3=$($LFS path2fid $DIR/$tfile.3)
13403
13404         local N=1
13405         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
13406                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
13407                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
13408                 local want=FID$N
13409                 [ "$FID" = "${!want}" ] ||
13410                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
13411                 N=$((N + 1))
13412         done
13413
13414         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
13415         do
13416                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
13417                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
13418                 N=$((N + 1))
13419         done
13420 }
13421 run_test 154c "lfs path2fid and fid2path multiple arguments"
13422
13423 test_154d() {
13424         remote_mds_nodsh && skip "remote MDS with nodsh"
13425         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
13426                 skip "Need MDS version at least 2.5.53"
13427
13428         if remote_mds; then
13429                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
13430         else
13431                 nid="0@lo"
13432         fi
13433         local proc_ofile="mdt.*.exports.'$nid'.open_files"
13434         local fd
13435         local cmd
13436
13437         rm -f $DIR/$tfile
13438         touch $DIR/$tfile
13439
13440         local fid=$($LFS path2fid $DIR/$tfile)
13441         # Open the file
13442         fd=$(free_fd)
13443         cmd="exec $fd<$DIR/$tfile"
13444         eval $cmd
13445         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
13446         echo "$fid_list" | grep "$fid"
13447         rc=$?
13448
13449         cmd="exec $fd>/dev/null"
13450         eval $cmd
13451         if [ $rc -ne 0 ]; then
13452                 error "FID $fid not found in open files list $fid_list"
13453         fi
13454 }
13455 run_test 154d "Verify open file fid"
13456
13457 test_154e()
13458 {
13459         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
13460                 skip "Need MDS version at least 2.6.50"
13461
13462         if ls -a $MOUNT | grep -q '^\.lustre$'; then
13463                 error ".lustre returned by readdir"
13464         fi
13465 }
13466 run_test 154e ".lustre is not returned by readdir"
13467
13468 test_154f() {
13469         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13470
13471         # create parent directory on a single MDT to avoid cross-MDT hardlinks
13472         test_mkdir -p -c1 $DIR/$tdir/d
13473         # test dirs inherit from its stripe
13474         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
13475         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
13476         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
13477         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
13478         touch $DIR/f
13479
13480         # get fid of parents
13481         local FID0=$($LFS path2fid $DIR/$tdir/d)
13482         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
13483         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
13484         local FID3=$($LFS path2fid $DIR)
13485
13486         # check that path2fid --parents returns expected <parent_fid>/name
13487         # 1) test for a directory (single parent)
13488         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
13489         [ "$parent" == "$FID0/foo1" ] ||
13490                 error "expected parent: $FID0/foo1, got: $parent"
13491
13492         # 2) test for a file with nlink > 1 (multiple parents)
13493         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
13494         echo "$parent" | grep -F "$FID1/$tfile" ||
13495                 error "$FID1/$tfile not returned in parent list"
13496         echo "$parent" | grep -F "$FID2/link" ||
13497                 error "$FID2/link not returned in parent list"
13498
13499         # 3) get parent by fid
13500         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
13501         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13502         echo "$parent" | grep -F "$FID1/$tfile" ||
13503                 error "$FID1/$tfile not returned in parent list (by fid)"
13504         echo "$parent" | grep -F "$FID2/link" ||
13505                 error "$FID2/link not returned in parent list (by fid)"
13506
13507         # 4) test for entry in root directory
13508         parent=$($LFS path2fid --parents $DIR/f)
13509         echo "$parent" | grep -F "$FID3/f" ||
13510                 error "$FID3/f not returned in parent list"
13511
13512         # 5) test it on root directory
13513         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
13514                 error "$MOUNT should not have parents"
13515
13516         # enable xattr caching and check that linkea is correctly updated
13517         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
13518         save_lustre_params client "llite.*.xattr_cache" > $save
13519         lctl set_param llite.*.xattr_cache 1
13520
13521         # 6.1) linkea update on rename
13522         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
13523
13524         # get parents by fid
13525         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13526         # foo1 should no longer be returned in parent list
13527         echo "$parent" | grep -F "$FID1" &&
13528                 error "$FID1 should no longer be in parent list"
13529         # the new path should appear
13530         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
13531                 error "$FID2/$tfile.moved is not in parent list"
13532
13533         # 6.2) linkea update on unlink
13534         rm -f $DIR/$tdir/d/foo2/link
13535         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13536         # foo2/link should no longer be returned in parent list
13537         echo "$parent" | grep -F "$FID2/link" &&
13538                 error "$FID2/link should no longer be in parent list"
13539         true
13540
13541         rm -f $DIR/f
13542         restore_lustre_params < $save
13543         rm -f $save
13544 }
13545 run_test 154f "get parent fids by reading link ea"
13546
13547 test_154g()
13548 {
13549         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13550         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
13551            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
13552                 skip "Need MDS version at least 2.6.92"
13553
13554         mkdir -p $DIR/$tdir
13555         llapi_fid_test -d $DIR/$tdir
13556 }
13557 run_test 154g "various llapi FID tests"
13558
13559 test_155_small_load() {
13560     local temp=$TMP/$tfile
13561     local file=$DIR/$tfile
13562
13563     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
13564         error "dd of=$temp bs=6096 count=1 failed"
13565     cp $temp $file
13566     cancel_lru_locks $OSC
13567     cmp $temp $file || error "$temp $file differ"
13568
13569     $TRUNCATE $temp 6000
13570     $TRUNCATE $file 6000
13571     cmp $temp $file || error "$temp $file differ (truncate1)"
13572
13573     echo "12345" >>$temp
13574     echo "12345" >>$file
13575     cmp $temp $file || error "$temp $file differ (append1)"
13576
13577     echo "12345" >>$temp
13578     echo "12345" >>$file
13579     cmp $temp $file || error "$temp $file differ (append2)"
13580
13581     rm -f $temp $file
13582     true
13583 }
13584
13585 test_155_big_load() {
13586         remote_ost_nodsh && skip "remote OST with nodsh"
13587
13588         local temp=$TMP/$tfile
13589         local file=$DIR/$tfile
13590
13591         free_min_max
13592         local cache_size=$(do_facet ost$((MAXI+1)) \
13593                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
13594         local large_file_size=$((cache_size * 2))
13595
13596         echo "OSS cache size: $cache_size KB"
13597         echo "Large file size: $large_file_size KB"
13598
13599         [ $MAXV -le $large_file_size ] &&
13600                 skip_env "max available OST size needs > $large_file_size KB"
13601
13602         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
13603
13604         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
13605                 error "dd of=$temp bs=$large_file_size count=1k failed"
13606         cp $temp $file
13607         ls -lh $temp $file
13608         cancel_lru_locks osc
13609         cmp $temp $file || error "$temp $file differ"
13610
13611         rm -f $temp $file
13612         true
13613 }
13614
13615 save_writethrough() {
13616         local facets=$(get_facets OST)
13617
13618         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
13619 }
13620
13621 test_155a() {
13622         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13623
13624         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13625
13626         save_writethrough $p
13627
13628         set_cache read on
13629         set_cache writethrough on
13630         test_155_small_load
13631         restore_lustre_params < $p
13632         rm -f $p
13633 }
13634 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
13635
13636 test_155b() {
13637         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13638
13639         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13640
13641         save_writethrough $p
13642
13643         set_cache read on
13644         set_cache writethrough off
13645         test_155_small_load
13646         restore_lustre_params < $p
13647         rm -f $p
13648 }
13649 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
13650
13651 test_155c() {
13652         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13653
13654         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13655
13656         save_writethrough $p
13657
13658         set_cache read off
13659         set_cache writethrough on
13660         test_155_small_load
13661         restore_lustre_params < $p
13662         rm -f $p
13663 }
13664 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
13665
13666 test_155d() {
13667         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13668
13669         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13670
13671         save_writethrough $p
13672
13673         set_cache read off
13674         set_cache writethrough off
13675         test_155_small_load
13676         restore_lustre_params < $p
13677         rm -f $p
13678 }
13679 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
13680
13681 test_155e() {
13682         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13683
13684         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13685
13686         save_writethrough $p
13687
13688         set_cache read on
13689         set_cache writethrough on
13690         test_155_big_load
13691         restore_lustre_params < $p
13692         rm -f $p
13693 }
13694 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
13695
13696 test_155f() {
13697         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13698
13699         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13700
13701         save_writethrough $p
13702
13703         set_cache read on
13704         set_cache writethrough off
13705         test_155_big_load
13706         restore_lustre_params < $p
13707         rm -f $p
13708 }
13709 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
13710
13711 test_155g() {
13712         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13713
13714         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13715
13716         save_writethrough $p
13717
13718         set_cache read off
13719         set_cache writethrough on
13720         test_155_big_load
13721         restore_lustre_params < $p
13722         rm -f $p
13723 }
13724 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
13725
13726 test_155h() {
13727         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13728
13729         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13730
13731         save_writethrough $p
13732
13733         set_cache read off
13734         set_cache writethrough off
13735         test_155_big_load
13736         restore_lustre_params < $p
13737         rm -f $p
13738 }
13739 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
13740
13741 test_156() {
13742         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13743         remote_ost_nodsh && skip "remote OST with nodsh"
13744         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
13745                 skip "stats not implemented on old servers"
13746         [ "$ost1_FSTYPE" = "zfs" ] &&
13747                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
13748
13749         local CPAGES=3
13750         local BEFORE
13751         local AFTER
13752         local file="$DIR/$tfile"
13753         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13754
13755         save_writethrough $p
13756         roc_hit_init
13757
13758         log "Turn on read and write cache"
13759         set_cache read on
13760         set_cache writethrough on
13761
13762         log "Write data and read it back."
13763         log "Read should be satisfied from the cache."
13764         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
13765         BEFORE=$(roc_hit)
13766         cancel_lru_locks osc
13767         cat $file >/dev/null
13768         AFTER=$(roc_hit)
13769         if ! let "AFTER - BEFORE == CPAGES"; then
13770                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
13771         else
13772                 log "cache hits: before: $BEFORE, after: $AFTER"
13773         fi
13774
13775         log "Read again; it should be satisfied from the cache."
13776         BEFORE=$AFTER
13777         cancel_lru_locks osc
13778         cat $file >/dev/null
13779         AFTER=$(roc_hit)
13780         if ! let "AFTER - BEFORE == CPAGES"; then
13781                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
13782         else
13783                 log "cache hits:: before: $BEFORE, after: $AFTER"
13784         fi
13785
13786         log "Turn off the read cache and turn on the write cache"
13787         set_cache read off
13788         set_cache writethrough on
13789
13790         log "Read again; it should be satisfied from the cache."
13791         BEFORE=$(roc_hit)
13792         cancel_lru_locks osc
13793         cat $file >/dev/null
13794         AFTER=$(roc_hit)
13795         if ! let "AFTER - BEFORE == CPAGES"; then
13796                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
13797         else
13798                 log "cache hits:: before: $BEFORE, after: $AFTER"
13799         fi
13800
13801         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
13802                 # > 2.12.56 uses pagecache if cached
13803                 log "Read again; it should not be satisfied from the cache."
13804                 BEFORE=$AFTER
13805                 cancel_lru_locks osc
13806                 cat $file >/dev/null
13807                 AFTER=$(roc_hit)
13808                 if ! let "AFTER - BEFORE == 0"; then
13809                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
13810                 else
13811                         log "cache hits:: before: $BEFORE, after: $AFTER"
13812                 fi
13813         fi
13814
13815         log "Write data and read it back."
13816         log "Read should be satisfied from the cache."
13817         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
13818         BEFORE=$(roc_hit)
13819         cancel_lru_locks osc
13820         cat $file >/dev/null
13821         AFTER=$(roc_hit)
13822         if ! let "AFTER - BEFORE == CPAGES"; then
13823                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
13824         else
13825                 log "cache hits:: before: $BEFORE, after: $AFTER"
13826         fi
13827
13828         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
13829                 # > 2.12.56 uses pagecache if cached
13830                 log "Read again; it should not be satisfied from the cache."
13831                 BEFORE=$AFTER
13832                 cancel_lru_locks osc
13833                 cat $file >/dev/null
13834                 AFTER=$(roc_hit)
13835                 if ! let "AFTER - BEFORE == 0"; then
13836                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
13837                 else
13838                         log "cache hits:: before: $BEFORE, after: $AFTER"
13839                 fi
13840         fi
13841
13842         log "Turn off read and write cache"
13843         set_cache read off
13844         set_cache writethrough off
13845
13846         log "Write data and read it back"
13847         log "It should not be satisfied from the cache."
13848         rm -f $file
13849         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
13850         cancel_lru_locks osc
13851         BEFORE=$(roc_hit)
13852         cat $file >/dev/null
13853         AFTER=$(roc_hit)
13854         if ! let "AFTER - BEFORE == 0"; then
13855                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
13856         else
13857                 log "cache hits:: before: $BEFORE, after: $AFTER"
13858         fi
13859
13860         log "Turn on the read cache and turn off the write cache"
13861         set_cache read on
13862         set_cache writethrough off
13863
13864         log "Write data and read it back"
13865         log "It should not be satisfied from the cache."
13866         rm -f $file
13867         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
13868         BEFORE=$(roc_hit)
13869         cancel_lru_locks osc
13870         cat $file >/dev/null
13871         AFTER=$(roc_hit)
13872         if ! let "AFTER - BEFORE == 0"; then
13873                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
13874         else
13875                 log "cache hits:: before: $BEFORE, after: $AFTER"
13876         fi
13877
13878         log "Read again; it should be satisfied from the cache."
13879         BEFORE=$(roc_hit)
13880         cancel_lru_locks osc
13881         cat $file >/dev/null
13882         AFTER=$(roc_hit)
13883         if ! let "AFTER - BEFORE == CPAGES"; then
13884                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
13885         else
13886                 log "cache hits:: before: $BEFORE, after: $AFTER"
13887         fi
13888
13889         restore_lustre_params < $p
13890         rm -f $p $file
13891 }
13892 run_test 156 "Verification of tunables"
13893
13894 test_160a() {
13895         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13896         remote_mds_nodsh && skip "remote MDS with nodsh"
13897         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
13898                 skip "Need MDS version at least 2.2.0"
13899
13900         changelog_register || error "changelog_register failed"
13901         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
13902         changelog_users $SINGLEMDS | grep -q $cl_user ||
13903                 error "User $cl_user not found in changelog_users"
13904
13905         # change something
13906         test_mkdir -p $DIR/$tdir/pics/2008/zachy
13907         changelog_clear 0 || error "changelog_clear failed"
13908         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
13909         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
13910         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
13911         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
13912         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
13913         rm $DIR/$tdir/pics/desktop.jpg
13914
13915         changelog_dump | tail -10
13916
13917         echo "verifying changelog mask"
13918         changelog_chmask "-MKDIR"
13919         changelog_chmask "-CLOSE"
13920
13921         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
13922         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
13923
13924         changelog_chmask "+MKDIR"
13925         changelog_chmask "+CLOSE"
13926
13927         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
13928         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
13929
13930         changelog_dump | tail -10
13931         MKDIRS=$(changelog_dump | grep -c "MKDIR")
13932         CLOSES=$(changelog_dump | grep -c "CLOSE")
13933         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
13934         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
13935
13936         # verify contents
13937         echo "verifying target fid"
13938         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
13939         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
13940         [ "$fidc" == "$fidf" ] ||
13941                 error "changelog '$tfile' fid $fidc != file fid $fidf"
13942         echo "verifying parent fid"
13943         # The FID returned from the Changelog may be the directory shard on
13944         # a different MDT, and not the FID returned by path2fid on the parent.
13945         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
13946         # since this is what will matter when recreating this file in the tree.
13947         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
13948         local pathp=$($LFS fid2path $MOUNT "$fidp")
13949         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
13950                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
13951
13952         echo "getting records for $cl_user"
13953         changelog_users $SINGLEMDS
13954         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
13955         local nclr=3
13956         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
13957                 error "changelog_clear failed"
13958         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
13959         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
13960         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
13961                 error "user index expect $user_rec1 + $nclr != $user_rec2"
13962
13963         local min0_rec=$(changelog_users $SINGLEMDS |
13964                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
13965         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
13966                           awk '{ print $1; exit; }')
13967
13968         changelog_dump | tail -n 5
13969         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
13970         [ $first_rec == $((min0_rec + 1)) ] ||
13971                 error "first index should be $min0_rec + 1 not $first_rec"
13972
13973         # LU-3446 changelog index reset on MDT restart
13974         local cur_rec1=$(changelog_users $SINGLEMDS |
13975                          awk '/^current.index:/ { print $NF }')
13976         changelog_clear 0 ||
13977                 error "clear all changelog records for $cl_user failed"
13978         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
13979         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
13980                 error "Fail to start $SINGLEMDS"
13981         local cur_rec2=$(changelog_users $SINGLEMDS |
13982                          awk '/^current.index:/ { print $NF }')
13983         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
13984         [ $cur_rec1 == $cur_rec2 ] ||
13985                 error "current index should be $cur_rec1 not $cur_rec2"
13986
13987         echo "verifying users from this test are deregistered"
13988         changelog_deregister || error "changelog_deregister failed"
13989         changelog_users $SINGLEMDS | grep -q $cl_user &&
13990                 error "User '$cl_user' still in changelog_users"
13991
13992         # lctl get_param -n mdd.*.changelog_users
13993         # current index: 144
13994         # ID    index (idle seconds)
13995         # cl3   144 (2)
13996         if ! changelog_users $SINGLEMDS | grep "^cl"; then
13997                 # this is the normal case where all users were deregistered
13998                 # make sure no new records are added when no users are present
13999                 local last_rec1=$(changelog_users $SINGLEMDS |
14000                                   awk '/^current.index:/ { print $NF }')
14001                 touch $DIR/$tdir/chloe
14002                 local last_rec2=$(changelog_users $SINGLEMDS |
14003                                   awk '/^current.index:/ { print $NF }')
14004                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
14005                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
14006         else
14007                 # any changelog users must be leftovers from a previous test
14008                 changelog_users $SINGLEMDS
14009                 echo "other changelog users; can't verify off"
14010         fi
14011 }
14012 run_test 160a "changelog sanity"
14013
14014 test_160b() { # LU-3587
14015         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14016         remote_mds_nodsh && skip "remote MDS with nodsh"
14017         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14018                 skip "Need MDS version at least 2.2.0"
14019
14020         changelog_register || error "changelog_register failed"
14021         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14022         changelog_users $SINGLEMDS | grep -q $cl_user ||
14023                 error "User '$cl_user' not found in changelog_users"
14024
14025         local longname1=$(str_repeat a 255)
14026         local longname2=$(str_repeat b 255)
14027
14028         cd $DIR
14029         echo "creating very long named file"
14030         touch $longname1 || error "create of '$longname1' failed"
14031         echo "renaming very long named file"
14032         mv $longname1 $longname2
14033
14034         changelog_dump | grep RENME | tail -n 5
14035         rm -f $longname2
14036 }
14037 run_test 160b "Verify that very long rename doesn't crash in changelog"
14038
14039 test_160c() {
14040         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14041         remote_mds_nodsh && skip "remote MDS with nodsh"
14042
14043         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
14044                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
14045                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
14046                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
14047
14048         local rc=0
14049
14050         # Registration step
14051         changelog_register || error "changelog_register failed"
14052
14053         rm -rf $DIR/$tdir
14054         mkdir -p $DIR/$tdir
14055         $MCREATE $DIR/$tdir/foo_160c
14056         changelog_chmask "-TRUNC"
14057         $TRUNCATE $DIR/$tdir/foo_160c 200
14058         changelog_chmask "+TRUNC"
14059         $TRUNCATE $DIR/$tdir/foo_160c 199
14060         changelog_dump | tail -n 5
14061         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
14062         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
14063 }
14064 run_test 160c "verify that changelog log catch the truncate event"
14065
14066 test_160d() {
14067         remote_mds_nodsh && skip "remote MDS with nodsh"
14068         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14069         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14070         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
14071                 skip "Need MDS version at least 2.7.60"
14072
14073         # Registration step
14074         changelog_register || error "changelog_register failed"
14075
14076         mkdir -p $DIR/$tdir/migrate_dir
14077         changelog_clear 0 || error "changelog_clear failed"
14078
14079         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
14080         changelog_dump | tail -n 5
14081         local migrates=$(changelog_dump | grep -c "MIGRT")
14082         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
14083 }
14084 run_test 160d "verify that changelog log catch the migrate event"
14085
14086 test_160e() {
14087         remote_mds_nodsh && skip "remote MDS with nodsh"
14088
14089         # Create a user
14090         changelog_register || error "changelog_register failed"
14091
14092         # Delete a future user (expect fail)
14093         local MDT0=$(facet_svc $SINGLEMDS)
14094         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
14095         local rc=$?
14096
14097         if [ $rc -eq 0 ]; then
14098                 error "Deleted non-existant user cl77"
14099         elif [ $rc -ne 2 ]; then
14100                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
14101         fi
14102
14103         # Clear to a bad index (1 billion should be safe)
14104         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
14105         rc=$?
14106
14107         if [ $rc -eq 0 ]; then
14108                 error "Successfully cleared to invalid CL index"
14109         elif [ $rc -ne 22 ]; then
14110                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
14111         fi
14112 }
14113 run_test 160e "changelog negative testing (should return errors)"
14114
14115 test_160f() {
14116         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14117         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14118                 skip "Need MDS version at least 2.10.56"
14119
14120         local mdts=$(comma_list $(mdts_nodes))
14121
14122         # Create a user
14123         changelog_register || error "first changelog_register failed"
14124         changelog_register || error "second changelog_register failed"
14125         local cl_users
14126         declare -A cl_user1
14127         declare -A cl_user2
14128         local user_rec1
14129         local user_rec2
14130         local i
14131
14132         # generate some changelog records to accumulate on each MDT
14133         # use fnv1a because created files should be evenly distributed
14134         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14135                 error "test_mkdir $tdir failed"
14136         log "$(date +%s): creating first files"
14137         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14138                 error "create $DIR/$tdir/$tfile failed"
14139
14140         # check changelogs have been generated
14141         local start=$SECONDS
14142         local idle_time=$((MDSCOUNT * 5 + 5))
14143         local nbcl=$(changelog_dump | wc -l)
14144         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14145
14146         for param in "changelog_max_idle_time=$idle_time" \
14147                      "changelog_gc=1" \
14148                      "changelog_min_gc_interval=2" \
14149                      "changelog_min_free_cat_entries=3"; do
14150                 local MDT0=$(facet_svc $SINGLEMDS)
14151                 local var="${param%=*}"
14152                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14153
14154                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14155                 do_nodes $mdts $LCTL set_param mdd.*.$param
14156         done
14157
14158         # force cl_user2 to be idle (1st part), but also cancel the
14159         # cl_user1 records so that it is not evicted later in the test.
14160         local sleep1=$((idle_time / 2))
14161         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
14162         sleep $sleep1
14163
14164         # simulate changelog catalog almost full
14165         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
14166         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
14167
14168         for i in $(seq $MDSCOUNT); do
14169                 cl_users=(${CL_USERS[mds$i]})
14170                 cl_user1[mds$i]="${cl_users[0]}"
14171                 cl_user2[mds$i]="${cl_users[1]}"
14172
14173                 [ -n "${cl_user1[mds$i]}" ] ||
14174                         error "mds$i: no user registered"
14175                 [ -n "${cl_user2[mds$i]}" ] ||
14176                         error "mds$i: only ${cl_user2[mds$i]} is registered"
14177
14178                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14179                 [ -n "$user_rec1" ] ||
14180                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14181                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14182                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14183                 [ -n "$user_rec2" ] ||
14184                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14185                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14186                      "$user_rec1 + 2 == $user_rec2"
14187                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14188                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14189                               "$user_rec1 + 2, but is $user_rec2"
14190                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14191                 [ -n "$user_rec2" ] ||
14192                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14193                 [ $user_rec1 == $user_rec2 ] ||
14194                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14195                               "$user_rec1, but is $user_rec2"
14196         done
14197
14198         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
14199         local sleep2=$((idle_time - (SECONDS - start) + 1))
14200         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
14201         sleep $sleep2
14202
14203         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
14204         # cl_user1 should be OK because it recently processed records.
14205         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
14206         createmany -m $DIR/$tdir/${tfile}b $((MDSCOUNT * 2)) ||
14207                 error "create $DIR/$tdir/${tfile}b failed"
14208
14209         # ensure gc thread is done
14210         for i in $(mdts_nodes); do
14211                 wait_update $i \
14212                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
14213                         error "$i: GC-thread not done"
14214         done
14215
14216         local first_rec
14217         for i in $(seq $MDSCOUNT); do
14218                 # check cl_user1 still registered
14219                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14220                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14221                 # check cl_user2 unregistered
14222                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14223                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14224
14225                 # check changelogs are present and starting at $user_rec1 + 1
14226                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14227                 [ -n "$user_rec1" ] ||
14228                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14229                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14230                             awk '{ print $1; exit; }')
14231
14232                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14233                 [ $((user_rec1 + 1)) == $first_rec ] ||
14234                         error "mds$i: first index should be $user_rec1 + 1, " \
14235                               "but is $first_rec"
14236         done
14237 }
14238 run_test 160f "changelog garbage collect (timestamped users)"
14239
14240 test_160g() {
14241         remote_mds_nodsh && skip "remote MDS with nodsh"
14242         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14243                 skip "Need MDS version at least 2.10.56"
14244
14245         local mdts=$(comma_list $(mdts_nodes))
14246
14247         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
14248         do_nodes $mdts $LCTL set_param fail_loc=0x1314
14249
14250         # Create a user
14251         changelog_register || error "first changelog_register failed"
14252         changelog_register || error "second changelog_register failed"
14253         local cl_users
14254         declare -A cl_user1
14255         declare -A cl_user2
14256         local user_rec1
14257         local user_rec2
14258         local i
14259
14260         # generate some changelog records to accumulate on each MDT
14261         # use fnv1a because created files should be evenly distributed
14262         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14263                 error "mkdir $tdir failed"
14264         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14265                 error "create $DIR/$tdir/$tfile failed"
14266
14267         # check changelogs have been generated
14268         local nbcl=$(changelog_dump | wc -l)
14269         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14270
14271         # reduce the max_idle_indexes value to make sure we exceed it
14272         max_ndx=$((nbcl / 2 - 1))
14273
14274         for param in "changelog_max_idle_indexes=$max_ndx" \
14275                      "changelog_gc=1" \
14276                      "changelog_min_gc_interval=2" \
14277                      "changelog_min_free_cat_entries=3"; do
14278                 local MDT0=$(facet_svc $SINGLEMDS)
14279                 local var="${param%=*}"
14280                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14281
14282                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14283                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
14284                         error "unable to set mdd.*.$param"
14285         done
14286
14287         # simulate changelog catalog almost full
14288         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
14289         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
14290
14291         for i in $(seq $MDSCOUNT); do
14292                 cl_users=(${CL_USERS[mds$i]})
14293                 cl_user1[mds$i]="${cl_users[0]}"
14294                 cl_user2[mds$i]="${cl_users[1]}"
14295
14296                 [ -n "${cl_user1[mds$i]}" ] ||
14297                         error "mds$i: no user registered"
14298                 [ -n "${cl_user2[mds$i]}" ] ||
14299                         error "mds$i: only ${cl_user1[mds$i]} is registered"
14300
14301                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14302                 [ -n "$user_rec1" ] ||
14303                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14304                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14305                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14306                 [ -n "$user_rec2" ] ||
14307                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14308                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14309                      "$user_rec1 + 2 == $user_rec2"
14310                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14311                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14312                               "$user_rec1 + 2, but is $user_rec2"
14313                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14314                 [ -n "$user_rec2" ] ||
14315                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14316                 [ $user_rec1 == $user_rec2 ] ||
14317                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14318                               "$user_rec1, but is $user_rec2"
14319         done
14320
14321         # ensure we are past the previous changelog_min_gc_interval set above
14322         sleep 2
14323
14324         # generate one more changelog to trigger fail_loc
14325         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14326                 error "create $DIR/$tdir/${tfile}bis failed"
14327
14328         # ensure gc thread is done
14329         for i in $(mdts_nodes); do
14330                 wait_update $i \
14331                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
14332                         error "$i: GC-thread not done"
14333         done
14334
14335         local first_rec
14336         for i in $(seq $MDSCOUNT); do
14337                 # check cl_user1 still registered
14338                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14339                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14340                 # check cl_user2 unregistered
14341                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14342                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14343
14344                 # check changelogs are present and starting at $user_rec1 + 1
14345                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14346                 [ -n "$user_rec1" ] ||
14347                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14348                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14349                             awk '{ print $1; exit; }')
14350
14351                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14352                 [ $((user_rec1 + 1)) == $first_rec ] ||
14353                         error "mds$i: first index should be $user_rec1 + 1, " \
14354                               "but is $first_rec"
14355         done
14356 }
14357 run_test 160g "changelog garbage collect (old users)"
14358
14359 test_160h() {
14360         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14361         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14362                 skip "Need MDS version at least 2.10.56"
14363
14364         local mdts=$(comma_list $(mdts_nodes))
14365
14366         # Create a user
14367         changelog_register || error "first changelog_register failed"
14368         changelog_register || error "second changelog_register failed"
14369         local cl_users
14370         declare -A cl_user1
14371         declare -A cl_user2
14372         local user_rec1
14373         local user_rec2
14374         local i
14375
14376         # generate some changelog records to accumulate on each MDT
14377         # use fnv1a because created files should be evenly distributed
14378         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14379                 error "test_mkdir $tdir failed"
14380         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14381                 error "create $DIR/$tdir/$tfile failed"
14382
14383         # check changelogs have been generated
14384         local nbcl=$(changelog_dump | wc -l)
14385         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14386
14387         for param in "changelog_max_idle_time=10" \
14388                      "changelog_gc=1" \
14389                      "changelog_min_gc_interval=2"; do
14390                 local MDT0=$(facet_svc $SINGLEMDS)
14391                 local var="${param%=*}"
14392                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14393
14394                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14395                 do_nodes $mdts $LCTL set_param mdd.*.$param
14396         done
14397
14398         # force cl_user2 to be idle (1st part)
14399         sleep 9
14400
14401         for i in $(seq $MDSCOUNT); do
14402                 cl_users=(${CL_USERS[mds$i]})
14403                 cl_user1[mds$i]="${cl_users[0]}"
14404                 cl_user2[mds$i]="${cl_users[1]}"
14405
14406                 [ -n "${cl_user1[mds$i]}" ] ||
14407                         error "mds$i: no user registered"
14408                 [ -n "${cl_user2[mds$i]}" ] ||
14409                         error "mds$i: only ${cl_user2[mds$i]} is registered"
14410
14411                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14412                 [ -n "$user_rec1" ] ||
14413                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14414                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14415                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14416                 [ -n "$user_rec2" ] ||
14417                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14418                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14419                      "$user_rec1 + 2 == $user_rec2"
14420                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14421                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14422                               "$user_rec1 + 2, but is $user_rec2"
14423                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14424                 [ -n "$user_rec2" ] ||
14425                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14426                 [ $user_rec1 == $user_rec2 ] ||
14427                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14428                               "$user_rec1, but is $user_rec2"
14429         done
14430
14431         # force cl_user2 to be idle (2nd part) and to reach
14432         # changelog_max_idle_time
14433         sleep 2
14434
14435         # force each GC-thread start and block then
14436         # one per MDT/MDD, set fail_val accordingly
14437         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
14438         do_nodes $mdts $LCTL set_param fail_loc=0x1316
14439
14440         # generate more changelogs to trigger fail_loc
14441         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14442                 error "create $DIR/$tdir/${tfile}bis failed"
14443
14444         # stop MDT to stop GC-thread, should be done in back-ground as it will
14445         # block waiting for the thread to be released and exit
14446         declare -A stop_pids
14447         for i in $(seq $MDSCOUNT); do
14448                 stop mds$i &
14449                 stop_pids[mds$i]=$!
14450         done
14451
14452         for i in $(mdts_nodes); do
14453                 local facet
14454                 local nb=0
14455                 local facets=$(facets_up_on_host $i)
14456
14457                 for facet in ${facets//,/ }; do
14458                         if [[ $facet == mds* ]]; then
14459                                 nb=$((nb + 1))
14460                         fi
14461                 done
14462                 # ensure each MDS's gc threads are still present and all in "R"
14463                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
14464                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
14465                         error "$i: expected $nb GC-thread"
14466                 wait_update $i \
14467                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
14468                         "R" 20 ||
14469                         error "$i: GC-thread not found in R-state"
14470                 # check umounts of each MDT on MDS have reached kthread_stop()
14471                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
14472                         error "$i: expected $nb umount"
14473                 wait_update $i \
14474                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
14475                         error "$i: umount not found in D-state"
14476         done
14477
14478         # release all GC-threads
14479         do_nodes $mdts $LCTL set_param fail_loc=0
14480
14481         # wait for MDT stop to complete
14482         for i in $(seq $MDSCOUNT); do
14483                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
14484         done
14485
14486         # XXX
14487         # may try to check if any orphan changelog records are present
14488         # via ldiskfs/zfs and llog_reader...
14489
14490         # re-start/mount MDTs
14491         for i in $(seq $MDSCOUNT); do
14492                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
14493                         error "Fail to start mds$i"
14494         done
14495
14496         local first_rec
14497         for i in $(seq $MDSCOUNT); do
14498                 # check cl_user1 still registered
14499                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14500                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14501                 # check cl_user2 unregistered
14502                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14503                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14504
14505                 # check changelogs are present and starting at $user_rec1 + 1
14506                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14507                 [ -n "$user_rec1" ] ||
14508                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14509                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14510                             awk '{ print $1; exit; }')
14511
14512                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14513                 [ $((user_rec1 + 1)) == $first_rec ] ||
14514                         error "mds$i: first index should be $user_rec1 + 1, " \
14515                               "but is $first_rec"
14516         done
14517 }
14518 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
14519               "during mount"
14520
14521 test_160i() {
14522
14523         local mdts=$(comma_list $(mdts_nodes))
14524
14525         changelog_register || error "first changelog_register failed"
14526
14527         # generate some changelog records to accumulate on each MDT
14528         # use fnv1a because created files should be evenly distributed
14529         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14530                 error "mkdir $tdir failed"
14531         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14532                 error "create $DIR/$tdir/$tfile failed"
14533
14534         # check changelogs have been generated
14535         local nbcl=$(changelog_dump | wc -l)
14536         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14537
14538         # simulate race between register and unregister
14539         # XXX as fail_loc is set per-MDS, with DNE configs the race
14540         # simulation will only occur for one MDT per MDS and for the
14541         # others the normal race scenario will take place
14542         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
14543         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
14544         do_nodes $mdts $LCTL set_param fail_val=1
14545
14546         # unregister 1st user
14547         changelog_deregister &
14548         local pid1=$!
14549         # wait some time for deregister work to reach race rdv
14550         sleep 2
14551         # register 2nd user
14552         changelog_register || error "2nd user register failed"
14553
14554         wait $pid1 || error "1st user deregister failed"
14555
14556         local i
14557         local last_rec
14558         declare -A LAST_REC
14559         for i in $(seq $MDSCOUNT); do
14560                 if changelog_users mds$i | grep "^cl"; then
14561                         # make sure new records are added with one user present
14562                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
14563                                           awk '/^current.index:/ { print $NF }')
14564                 else
14565                         error "mds$i has no user registered"
14566                 fi
14567         done
14568
14569         # generate more changelog records to accumulate on each MDT
14570         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14571                 error "create $DIR/$tdir/${tfile}bis failed"
14572
14573         for i in $(seq $MDSCOUNT); do
14574                 last_rec=$(changelog_users $SINGLEMDS |
14575                            awk '/^current.index:/ { print $NF }')
14576                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
14577                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
14578                         error "changelogs are off on mds$i"
14579         done
14580 }
14581 run_test 160i "changelog user register/unregister race"
14582
14583 test_160j() {
14584         remote_mds_nodsh && skip "remote MDS with nodsh"
14585         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
14586                 skip "Need MDS version at least 2.12.56"
14587
14588         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
14589         stack_trap "umount $MOUNT2" EXIT
14590
14591         changelog_register || error "first changelog_register failed"
14592         stack_trap "changelog_deregister" EXIT
14593
14594         # generate some changelog
14595         # use fnv1a because created files should be evenly distributed
14596         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14597                 error "mkdir $tdir failed"
14598         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14599                 error "create $DIR/$tdir/${tfile}bis failed"
14600
14601         # open the changelog device
14602         exec 3>/dev/changelog-$FSNAME-MDT0000
14603         stack_trap "exec 3>&-" EXIT
14604         exec 4</dev/changelog-$FSNAME-MDT0000
14605         stack_trap "exec 4<&-" EXIT
14606
14607         # umount the first lustre mount
14608         umount $MOUNT
14609         stack_trap "mount_client $MOUNT" EXIT
14610
14611         # read changelog
14612         cat <&4 >/dev/null || error "read changelog failed"
14613
14614         # clear changelog
14615         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14616         changelog_users $SINGLEMDS | grep -q $cl_user ||
14617                 error "User $cl_user not found in changelog_users"
14618
14619         printf 'clear:'$cl_user':0' >&3
14620 }
14621 run_test 160j "client can be umounted  while its chanangelog is being used"
14622
14623 test_160k() {
14624         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14625         remote_mds_nodsh && skip "remote MDS with nodsh"
14626
14627         mkdir -p $DIR/$tdir/1/1
14628
14629         changelog_register || error "changelog_register failed"
14630         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14631
14632         changelog_users $SINGLEMDS | grep -q $cl_user ||
14633                 error "User '$cl_user' not found in changelog_users"
14634 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
14635         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
14636         rmdir $DIR/$tdir/1/1 & sleep 1
14637         mkdir $DIR/$tdir/2
14638         touch $DIR/$tdir/2/2
14639         rm -rf $DIR/$tdir/2
14640
14641         wait
14642         sleep 4
14643
14644         changelog_dump | grep rmdir || error "rmdir not recorded"
14645
14646         rm -rf $DIR/$tdir
14647         changelog_deregister
14648 }
14649 run_test 160k "Verify that changelog records are not lost"
14650
14651 test_161a() {
14652         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14653
14654         test_mkdir -c1 $DIR/$tdir
14655         cp /etc/hosts $DIR/$tdir/$tfile
14656         test_mkdir -c1 $DIR/$tdir/foo1
14657         test_mkdir -c1 $DIR/$tdir/foo2
14658         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
14659         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
14660         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
14661         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
14662         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
14663         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
14664                 $LFS fid2path $DIR $FID
14665                 error "bad link ea"
14666         fi
14667         # middle
14668         rm $DIR/$tdir/foo2/zachary
14669         # last
14670         rm $DIR/$tdir/foo2/thor
14671         # first
14672         rm $DIR/$tdir/$tfile
14673         # rename
14674         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
14675         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
14676                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
14677         rm $DIR/$tdir/foo2/maggie
14678
14679         # overflow the EA
14680         local longname=$tfile.avg_len_is_thirty_two_
14681         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
14682                 error_noexit 'failed to unlink many hardlinks'" EXIT
14683         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
14684                 error "failed to hardlink many files"
14685         links=$($LFS fid2path $DIR $FID | wc -l)
14686         echo -n "${links}/1000 links in link EA"
14687         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
14688 }
14689 run_test 161a "link ea sanity"
14690
14691 test_161b() {
14692         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14693         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
14694
14695         local MDTIDX=1
14696         local remote_dir=$DIR/$tdir/remote_dir
14697
14698         mkdir -p $DIR/$tdir
14699         $LFS mkdir -i $MDTIDX $remote_dir ||
14700                 error "create remote directory failed"
14701
14702         cp /etc/hosts $remote_dir/$tfile
14703         mkdir -p $remote_dir/foo1
14704         mkdir -p $remote_dir/foo2
14705         ln $remote_dir/$tfile $remote_dir/foo1/sofia
14706         ln $remote_dir/$tfile $remote_dir/foo2/zachary
14707         ln $remote_dir/$tfile $remote_dir/foo1/luna
14708         ln $remote_dir/$tfile $remote_dir/foo2/thor
14709
14710         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
14711                      tr -d ']')
14712         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
14713                 $LFS fid2path $DIR $FID
14714                 error "bad link ea"
14715         fi
14716         # middle
14717         rm $remote_dir/foo2/zachary
14718         # last
14719         rm $remote_dir/foo2/thor
14720         # first
14721         rm $remote_dir/$tfile
14722         # rename
14723         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
14724         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
14725         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
14726                 $LFS fid2path $DIR $FID
14727                 error "bad link rename"
14728         fi
14729         rm $remote_dir/foo2/maggie
14730
14731         # overflow the EA
14732         local longname=filename_avg_len_is_thirty_two_
14733         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
14734                 error "failed to hardlink many files"
14735         links=$($LFS fid2path $DIR $FID | wc -l)
14736         echo -n "${links}/1000 links in link EA"
14737         [[ ${links} -gt 60 ]] ||
14738                 error "expected at least 60 links in link EA"
14739         unlinkmany $remote_dir/foo2/$longname 1000 ||
14740         error "failed to unlink many hardlinks"
14741 }
14742 run_test 161b "link ea sanity under remote directory"
14743
14744 test_161c() {
14745         remote_mds_nodsh && skip "remote MDS with nodsh"
14746         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14747         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
14748                 skip "Need MDS version at least 2.1.5"
14749
14750         # define CLF_RENAME_LAST 0x0001
14751         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
14752         changelog_register || error "changelog_register failed"
14753
14754         rm -rf $DIR/$tdir
14755         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
14756         touch $DIR/$tdir/foo_161c
14757         touch $DIR/$tdir/bar_161c
14758         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
14759         changelog_dump | grep RENME | tail -n 5
14760         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
14761         changelog_clear 0 || error "changelog_clear failed"
14762         if [ x$flags != "x0x1" ]; then
14763                 error "flag $flags is not 0x1"
14764         fi
14765
14766         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
14767         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
14768         touch $DIR/$tdir/foo_161c
14769         touch $DIR/$tdir/bar_161c
14770         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
14771         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
14772         changelog_dump | grep RENME | tail -n 5
14773         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
14774         changelog_clear 0 || error "changelog_clear failed"
14775         if [ x$flags != "x0x0" ]; then
14776                 error "flag $flags is not 0x0"
14777         fi
14778         echo "rename overwrite a target having nlink > 1," \
14779                 "changelog record has flags of $flags"
14780
14781         # rename doesn't overwrite a target (changelog flag 0x0)
14782         touch $DIR/$tdir/foo_161c
14783         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
14784         changelog_dump | grep RENME | tail -n 5
14785         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
14786         changelog_clear 0 || error "changelog_clear failed"
14787         if [ x$flags != "x0x0" ]; then
14788                 error "flag $flags is not 0x0"
14789         fi
14790         echo "rename doesn't overwrite a target," \
14791                 "changelog record has flags of $flags"
14792
14793         # define CLF_UNLINK_LAST 0x0001
14794         # unlink a file having nlink = 1 (changelog flag 0x1)
14795         rm -f $DIR/$tdir/foo2_161c
14796         changelog_dump | grep UNLNK | tail -n 5
14797         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
14798         changelog_clear 0 || error "changelog_clear failed"
14799         if [ x$flags != "x0x1" ]; then
14800                 error "flag $flags is not 0x1"
14801         fi
14802         echo "unlink a file having nlink = 1," \
14803                 "changelog record has flags of $flags"
14804
14805         # unlink a file having nlink > 1 (changelog flag 0x0)
14806         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
14807         rm -f $DIR/$tdir/foobar_161c
14808         changelog_dump | grep UNLNK | tail -n 5
14809         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
14810         changelog_clear 0 || error "changelog_clear failed"
14811         if [ x$flags != "x0x0" ]; then
14812                 error "flag $flags is not 0x0"
14813         fi
14814         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
14815 }
14816 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
14817
14818 test_161d() {
14819         remote_mds_nodsh && skip "remote MDS with nodsh"
14820         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
14821
14822         local pid
14823         local fid
14824
14825         changelog_register || error "changelog_register failed"
14826
14827         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
14828         # interfer with $MOUNT/.lustre/fid/ access
14829         mkdir $DIR/$tdir
14830         [[ $? -eq 0 ]] || error "mkdir failed"
14831
14832         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
14833         $LCTL set_param fail_loc=0x8000140c
14834         # 5s pause
14835         $LCTL set_param fail_val=5
14836
14837         # create file
14838         echo foofoo > $DIR/$tdir/$tfile &
14839         pid=$!
14840
14841         # wait for create to be delayed
14842         sleep 2
14843
14844         ps -p $pid
14845         [[ $? -eq 0 ]] || error "create should be blocked"
14846
14847         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
14848         stack_trap "rm -f $tempfile"
14849         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
14850         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
14851         # some delay may occur during ChangeLog publishing and file read just
14852         # above, that could allow file write to happen finally
14853         [[ -s $tempfile ]] && echo "file should be empty"
14854
14855         $LCTL set_param fail_loc=0
14856
14857         wait $pid
14858         [[ $? -eq 0 ]] || error "create failed"
14859 }
14860 run_test 161d "create with concurrent .lustre/fid access"
14861
14862 check_path() {
14863         local expected="$1"
14864         shift
14865         local fid="$2"
14866
14867         local path
14868         path=$($LFS fid2path "$@")
14869         local rc=$?
14870
14871         if [ $rc -ne 0 ]; then
14872                 error "path looked up of '$expected' failed: rc=$rc"
14873         elif [ "$path" != "$expected" ]; then
14874                 error "path looked up '$path' instead of '$expected'"
14875         else
14876                 echo "FID '$fid' resolves to path '$path' as expected"
14877         fi
14878 }
14879
14880 test_162a() { # was test_162
14881         test_mkdir -p -c1 $DIR/$tdir/d2
14882         touch $DIR/$tdir/d2/$tfile
14883         touch $DIR/$tdir/d2/x1
14884         touch $DIR/$tdir/d2/x2
14885         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
14886         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
14887         # regular file
14888         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
14889         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
14890
14891         # softlink
14892         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
14893         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
14894         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
14895
14896         # softlink to wrong file
14897         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
14898         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
14899         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
14900
14901         # hardlink
14902         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
14903         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
14904         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
14905         # fid2path dir/fsname should both work
14906         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
14907         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
14908
14909         # hardlink count: check that there are 2 links
14910         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
14911         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
14912
14913         # hardlink indexing: remove the first link
14914         rm $DIR/$tdir/d2/p/q/r/hlink
14915         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
14916 }
14917 run_test 162a "path lookup sanity"
14918
14919 test_162b() {
14920         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14921         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14922
14923         mkdir $DIR/$tdir
14924         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
14925                                 error "create striped dir failed"
14926
14927         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
14928                                         tail -n 1 | awk '{print $2}')
14929         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
14930
14931         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
14932         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
14933
14934         # regular file
14935         for ((i=0;i<5;i++)); do
14936                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
14937                         error "get fid for f$i failed"
14938                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
14939
14940                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
14941                         error "get fid for d$i failed"
14942                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
14943         done
14944
14945         return 0
14946 }
14947 run_test 162b "striped directory path lookup sanity"
14948
14949 # LU-4239: Verify fid2path works with paths 100 or more directories deep
14950 test_162c() {
14951         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
14952                 skip "Need MDS version at least 2.7.51"
14953
14954         local lpath=$tdir.local
14955         local rpath=$tdir.remote
14956
14957         test_mkdir $DIR/$lpath
14958         test_mkdir $DIR/$rpath
14959
14960         for ((i = 0; i <= 101; i++)); do
14961                 lpath="$lpath/$i"
14962                 mkdir $DIR/$lpath
14963                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
14964                         error "get fid for local directory $DIR/$lpath failed"
14965                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
14966
14967                 rpath="$rpath/$i"
14968                 test_mkdir $DIR/$rpath
14969                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
14970                         error "get fid for remote directory $DIR/$rpath failed"
14971                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
14972         done
14973
14974         return 0
14975 }
14976 run_test 162c "fid2path works with paths 100 or more directories deep"
14977
14978 test_169() {
14979         # do directio so as not to populate the page cache
14980         log "creating a 10 Mb file"
14981         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
14982         log "starting reads"
14983         dd if=$DIR/$tfile of=/dev/null bs=4096 &
14984         log "truncating the file"
14985         $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
14986         log "killing dd"
14987         kill %+ || true # reads might have finished
14988         echo "wait until dd is finished"
14989         wait
14990         log "removing the temporary file"
14991         rm -rf $DIR/$tfile || error "tmp file removal failed"
14992 }
14993 run_test 169 "parallel read and truncate should not deadlock"
14994
14995 test_170() {
14996         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14997
14998         $LCTL clear     # bug 18514
14999         $LCTL debug_daemon start $TMP/${tfile}_log_good
15000         touch $DIR/$tfile
15001         $LCTL debug_daemon stop
15002         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
15003                 error "sed failed to read log_good"
15004
15005         $LCTL debug_daemon start $TMP/${tfile}_log_good
15006         rm -rf $DIR/$tfile
15007         $LCTL debug_daemon stop
15008
15009         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
15010                error "lctl df log_bad failed"
15011
15012         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
15013         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
15014
15015         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
15016         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
15017
15018         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
15019                 error "bad_line good_line1 good_line2 are empty"
15020
15021         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
15022         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
15023         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
15024
15025         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
15026         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
15027         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
15028
15029         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
15030                 error "bad_line_new good_line_new are empty"
15031
15032         local expected_good=$((good_line1 + good_line2*2))
15033
15034         rm -f $TMP/${tfile}*
15035         # LU-231, short malformed line may not be counted into bad lines
15036         if [ $bad_line -ne $bad_line_new ] &&
15037                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
15038                 error "expected $bad_line bad lines, but got $bad_line_new"
15039                 return 1
15040         fi
15041
15042         if [ $expected_good -ne $good_line_new ]; then
15043                 error "expected $expected_good good lines, but got $good_line_new"
15044                 return 2
15045         fi
15046         true
15047 }
15048 run_test 170 "test lctl df to handle corrupted log ====================="
15049
15050 test_171() { # bug20592
15051         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15052
15053         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
15054         $LCTL set_param fail_loc=0x50e
15055         $LCTL set_param fail_val=3000
15056         multiop_bg_pause $DIR/$tfile O_s || true
15057         local MULTIPID=$!
15058         kill -USR1 $MULTIPID
15059         # cause log dump
15060         sleep 3
15061         wait $MULTIPID
15062         if dmesg | grep "recursive fault"; then
15063                 error "caught a recursive fault"
15064         fi
15065         $LCTL set_param fail_loc=0
15066         true
15067 }
15068 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
15069
15070 # it would be good to share it with obdfilter-survey/iokit-libecho code
15071 setup_obdecho_osc () {
15072         local rc=0
15073         local ost_nid=$1
15074         local obdfilter_name=$2
15075         echo "Creating new osc for $obdfilter_name on $ost_nid"
15076         # make sure we can find loopback nid
15077         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
15078
15079         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
15080                            ${obdfilter_name}_osc_UUID || rc=2; }
15081         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
15082                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
15083         return $rc
15084 }
15085
15086 cleanup_obdecho_osc () {
15087         local obdfilter_name=$1
15088         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
15089         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
15090         return 0
15091 }
15092
15093 obdecho_test() {
15094         local OBD=$1
15095         local node=$2
15096         local pages=${3:-64}
15097         local rc=0
15098         local id
15099
15100         local count=10
15101         local obd_size=$(get_obd_size $node $OBD)
15102         local page_size=$(get_page_size $node)
15103         if [[ -n "$obd_size" ]]; then
15104                 local new_count=$((obd_size / (pages * page_size / 1024)))
15105                 [[ $new_count -ge $count ]] || count=$new_count
15106         fi
15107
15108         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
15109         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
15110                            rc=2; }
15111         if [ $rc -eq 0 ]; then
15112             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
15113             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
15114         fi
15115         echo "New object id is $id"
15116         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
15117                            rc=4; }
15118         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
15119                            "test_brw $count w v $pages $id" || rc=4; }
15120         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
15121                            rc=4; }
15122         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
15123                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
15124         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
15125                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
15126         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
15127         return $rc
15128 }
15129
15130 test_180a() {
15131         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15132
15133         if ! module_loaded obdecho; then
15134                 load_module obdecho/obdecho &&
15135                         stack_trap "rmmod obdecho" EXIT ||
15136                         error "unable to load obdecho on client"
15137         fi
15138
15139         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
15140         local host=$($LCTL get_param -n osc.$osc.import |
15141                      awk '/current_connection:/ { print $2 }' )
15142         local target=$($LCTL get_param -n osc.$osc.import |
15143                        awk '/target:/ { print $2 }' )
15144         target=${target%_UUID}
15145
15146         if [ -n "$target" ]; then
15147                 setup_obdecho_osc $host $target &&
15148                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
15149                         { error "obdecho setup failed with $?"; return; }
15150
15151                 obdecho_test ${target}_osc client ||
15152                         error "obdecho_test failed on ${target}_osc"
15153         else
15154                 $LCTL get_param osc.$osc.import
15155                 error "there is no osc.$osc.import target"
15156         fi
15157 }
15158 run_test 180a "test obdecho on osc"
15159
15160 test_180b() {
15161         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15162         remote_ost_nodsh && skip "remote OST with nodsh"
15163
15164         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
15165                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
15166                 error "failed to load module obdecho"
15167
15168         local target=$(do_facet ost1 $LCTL dl |
15169                        awk '/obdfilter/ { print $4; exit; }')
15170
15171         if [ -n "$target" ]; then
15172                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
15173         else
15174                 do_facet ost1 $LCTL dl
15175                 error "there is no obdfilter target on ost1"
15176         fi
15177 }
15178 run_test 180b "test obdecho directly on obdfilter"
15179
15180 test_180c() { # LU-2598
15181         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15182         remote_ost_nodsh && skip "remote OST with nodsh"
15183         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
15184                 skip "Need MDS version at least 2.4.0"
15185
15186         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
15187                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
15188                 error "failed to load module obdecho"
15189
15190         local target=$(do_facet ost1 $LCTL dl |
15191                        awk '/obdfilter/ { print $4; exit; }')
15192
15193         if [ -n "$target" ]; then
15194                 local pages=16384 # 64MB bulk I/O RPC size
15195
15196                 obdecho_test "$target" ost1 "$pages" ||
15197                         error "obdecho_test with pages=$pages failed with $?"
15198         else
15199                 do_facet ost1 $LCTL dl
15200                 error "there is no obdfilter target on ost1"
15201         fi
15202 }
15203 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
15204
15205 test_181() { # bug 22177
15206         test_mkdir $DIR/$tdir
15207         # create enough files to index the directory
15208         createmany -o $DIR/$tdir/foobar 4000
15209         # print attributes for debug purpose
15210         lsattr -d .
15211         # open dir
15212         multiop_bg_pause $DIR/$tdir D_Sc || return 1
15213         MULTIPID=$!
15214         # remove the files & current working dir
15215         unlinkmany $DIR/$tdir/foobar 4000
15216         rmdir $DIR/$tdir
15217         kill -USR1 $MULTIPID
15218         wait $MULTIPID
15219         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
15220         return 0
15221 }
15222 run_test 181 "Test open-unlinked dir ========================"
15223
15224 test_182() {
15225         local fcount=1000
15226         local tcount=10
15227
15228         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
15229
15230         $LCTL set_param mdc.*.rpc_stats=clear
15231
15232         for (( i = 0; i < $tcount; i++ )) ; do
15233                 mkdir $DIR/$tdir/$i
15234         done
15235
15236         for (( i = 0; i < $tcount; i++ )) ; do
15237                 createmany -o $DIR/$tdir/$i/f- $fcount &
15238         done
15239         wait
15240
15241         for (( i = 0; i < $tcount; i++ )) ; do
15242                 unlinkmany $DIR/$tdir/$i/f- $fcount &
15243         done
15244         wait
15245
15246         $LCTL get_param mdc.*.rpc_stats
15247
15248         rm -rf $DIR/$tdir
15249 }
15250 run_test 182 "Test parallel modify metadata operations ================"
15251
15252 test_183() { # LU-2275
15253         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15254         remote_mds_nodsh && skip "remote MDS with nodsh"
15255         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
15256                 skip "Need MDS version at least 2.3.56"
15257
15258         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
15259         echo aaa > $DIR/$tdir/$tfile
15260
15261 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
15262         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
15263
15264         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
15265         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
15266
15267         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
15268
15269         # Flush negative dentry cache
15270         touch $DIR/$tdir/$tfile
15271
15272         # We are not checking for any leaked references here, they'll
15273         # become evident next time we do cleanup with module unload.
15274         rm -rf $DIR/$tdir
15275 }
15276 run_test 183 "No crash or request leak in case of strange dispositions ========"
15277
15278 # test suite 184 is for LU-2016, LU-2017
15279 test_184a() {
15280         check_swap_layouts_support
15281
15282         dir0=$DIR/$tdir/$testnum
15283         test_mkdir -p -c1 $dir0
15284         ref1=/etc/passwd
15285         ref2=/etc/group
15286         file1=$dir0/f1
15287         file2=$dir0/f2
15288         $LFS setstripe -c1 $file1
15289         cp $ref1 $file1
15290         $LFS setstripe -c2 $file2
15291         cp $ref2 $file2
15292         gen1=$($LFS getstripe -g $file1)
15293         gen2=$($LFS getstripe -g $file2)
15294
15295         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
15296         gen=$($LFS getstripe -g $file1)
15297         [[ $gen1 != $gen ]] ||
15298                 "Layout generation on $file1 does not change"
15299         gen=$($LFS getstripe -g $file2)
15300         [[ $gen2 != $gen ]] ||
15301                 "Layout generation on $file2 does not change"
15302
15303         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
15304         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
15305
15306         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
15307 }
15308 run_test 184a "Basic layout swap"
15309
15310 test_184b() {
15311         check_swap_layouts_support
15312
15313         dir0=$DIR/$tdir/$testnum
15314         mkdir -p $dir0 || error "creating dir $dir0"
15315         file1=$dir0/f1
15316         file2=$dir0/f2
15317         file3=$dir0/f3
15318         dir1=$dir0/d1
15319         dir2=$dir0/d2
15320         mkdir $dir1 $dir2
15321         $LFS setstripe -c1 $file1
15322         $LFS setstripe -c2 $file2
15323         $LFS setstripe -c1 $file3
15324         chown $RUNAS_ID $file3
15325         gen1=$($LFS getstripe -g $file1)
15326         gen2=$($LFS getstripe -g $file2)
15327
15328         $LFS swap_layouts $dir1 $dir2 &&
15329                 error "swap of directories layouts should fail"
15330         $LFS swap_layouts $dir1 $file1 &&
15331                 error "swap of directory and file layouts should fail"
15332         $RUNAS $LFS swap_layouts $file1 $file2 &&
15333                 error "swap of file we cannot write should fail"
15334         $LFS swap_layouts $file1 $file3 &&
15335                 error "swap of file with different owner should fail"
15336         /bin/true # to clear error code
15337 }
15338 run_test 184b "Forbidden layout swap (will generate errors)"
15339
15340 test_184c() {
15341         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
15342         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
15343         check_swap_layouts_support
15344
15345         local dir0=$DIR/$tdir/$testnum
15346         mkdir -p $dir0 || error "creating dir $dir0"
15347
15348         local ref1=$dir0/ref1
15349         local ref2=$dir0/ref2
15350         local file1=$dir0/file1
15351         local file2=$dir0/file2
15352         # create a file large enough for the concurrent test
15353         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
15354         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
15355         echo "ref file size: ref1($(stat -c %s $ref1))," \
15356              "ref2($(stat -c %s $ref2))"
15357
15358         cp $ref2 $file2
15359         dd if=$ref1 of=$file1 bs=16k &
15360         local DD_PID=$!
15361
15362         # Make sure dd starts to copy file
15363         while [ ! -f $file1 ]; do sleep 0.1; done
15364
15365         $LFS swap_layouts $file1 $file2
15366         local rc=$?
15367         wait $DD_PID
15368         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
15369         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
15370
15371         # how many bytes copied before swapping layout
15372         local copied=$(stat -c %s $file2)
15373         local remaining=$(stat -c %s $ref1)
15374         remaining=$((remaining - copied))
15375         echo "Copied $copied bytes before swapping layout..."
15376
15377         cmp -n $copied $file1 $ref2 | grep differ &&
15378                 error "Content mismatch [0, $copied) of ref2 and file1"
15379         cmp -n $copied $file2 $ref1 ||
15380                 error "Content mismatch [0, $copied) of ref1 and file2"
15381         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
15382                 error "Content mismatch [$copied, EOF) of ref1 and file1"
15383
15384         # clean up
15385         rm -f $ref1 $ref2 $file1 $file2
15386 }
15387 run_test 184c "Concurrent write and layout swap"
15388
15389 test_184d() {
15390         check_swap_layouts_support
15391         [ -z "$(which getfattr 2>/dev/null)" ] &&
15392                 skip_env "no getfattr command"
15393
15394         local file1=$DIR/$tdir/$tfile-1
15395         local file2=$DIR/$tdir/$tfile-2
15396         local file3=$DIR/$tdir/$tfile-3
15397         local lovea1
15398         local lovea2
15399
15400         mkdir -p $DIR/$tdir
15401         touch $file1 || error "create $file1 failed"
15402         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
15403                 error "create $file2 failed"
15404         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
15405                 error "create $file3 failed"
15406         lovea1=$(get_layout_param $file1)
15407
15408         $LFS swap_layouts $file2 $file3 ||
15409                 error "swap $file2 $file3 layouts failed"
15410         $LFS swap_layouts $file1 $file2 ||
15411                 error "swap $file1 $file2 layouts failed"
15412
15413         lovea2=$(get_layout_param $file2)
15414         echo "$lovea1"
15415         echo "$lovea2"
15416         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
15417
15418         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
15419         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
15420 }
15421 run_test 184d "allow stripeless layouts swap"
15422
15423 test_184e() {
15424         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
15425                 skip "Need MDS version at least 2.6.94"
15426         check_swap_layouts_support
15427         [ -z "$(which getfattr 2>/dev/null)" ] &&
15428                 skip_env "no getfattr command"
15429
15430         local file1=$DIR/$tdir/$tfile-1
15431         local file2=$DIR/$tdir/$tfile-2
15432         local file3=$DIR/$tdir/$tfile-3
15433         local lovea
15434
15435         mkdir -p $DIR/$tdir
15436         touch $file1 || error "create $file1 failed"
15437         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
15438                 error "create $file2 failed"
15439         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
15440                 error "create $file3 failed"
15441
15442         $LFS swap_layouts $file1 $file2 ||
15443                 error "swap $file1 $file2 layouts failed"
15444
15445         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
15446         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
15447
15448         echo 123 > $file1 || error "Should be able to write into $file1"
15449
15450         $LFS swap_layouts $file1 $file3 ||
15451                 error "swap $file1 $file3 layouts failed"
15452
15453         echo 123 > $file1 || error "Should be able to write into $file1"
15454
15455         rm -rf $file1 $file2 $file3
15456 }
15457 run_test 184e "Recreate layout after stripeless layout swaps"
15458
15459 test_184f() {
15460         # Create a file with name longer than sizeof(struct stat) ==
15461         # 144 to see if we can get chars from the file name to appear
15462         # in the returned striping. Note that 'f' == 0x66.
15463         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
15464
15465         mkdir -p $DIR/$tdir
15466         mcreate $DIR/$tdir/$file
15467         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
15468                 error "IOC_MDC_GETFILEINFO returned garbage striping"
15469         fi
15470 }
15471 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
15472
15473 test_185() { # LU-2441
15474         # LU-3553 - no volatile file support in old servers
15475         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
15476                 skip "Need MDS version at least 2.3.60"
15477
15478         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
15479         touch $DIR/$tdir/spoo
15480         local mtime1=$(stat -c "%Y" $DIR/$tdir)
15481         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
15482                 error "cannot create/write a volatile file"
15483         [ "$FILESET" == "" ] &&
15484         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
15485                 error "FID is still valid after close"
15486
15487         multiop_bg_pause $DIR/$tdir vVw4096_c
15488         local multi_pid=$!
15489
15490         local OLD_IFS=$IFS
15491         IFS=":"
15492         local fidv=($fid)
15493         IFS=$OLD_IFS
15494         # assume that the next FID for this client is sequential, since stdout
15495         # is unfortunately eaten by multiop_bg_pause
15496         local n=$((${fidv[1]} + 1))
15497         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
15498         if [ "$FILESET" == "" ]; then
15499                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
15500                         error "FID is missing before close"
15501         fi
15502         kill -USR1 $multi_pid
15503         # 1 second delay, so if mtime change we will see it
15504         sleep 1
15505         local mtime2=$(stat -c "%Y" $DIR/$tdir)
15506         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
15507 }
15508 run_test 185 "Volatile file support"
15509
15510 function create_check_volatile() {
15511         local idx=$1
15512         local tgt
15513
15514         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
15515         local PID=$!
15516         sleep 1
15517         local FID=$(cat /tmp/${tfile}.fid)
15518         [ "$FID" == "" ] && error "can't get FID for volatile"
15519         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
15520         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
15521         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
15522         kill -USR1 $PID
15523         wait
15524         sleep 1
15525         cancel_lru_locks mdc # flush opencache
15526         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
15527         return 0
15528 }
15529
15530 test_185a(){
15531         # LU-12516 - volatile creation via .lustre
15532         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
15533                 skip "Need MDS version at least 2.3.55"
15534
15535         create_check_volatile 0
15536         [ $MDSCOUNT -lt 2 ] && return 0
15537
15538         # DNE case
15539         create_check_volatile 1
15540
15541         return 0
15542 }
15543 run_test 185a "Volatile file creation in .lustre/fid/"
15544
15545 test_187a() {
15546         remote_mds_nodsh && skip "remote MDS with nodsh"
15547         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
15548                 skip "Need MDS version at least 2.3.0"
15549
15550         local dir0=$DIR/$tdir/$testnum
15551         mkdir -p $dir0 || error "creating dir $dir0"
15552
15553         local file=$dir0/file1
15554         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
15555         local dv1=$($LFS data_version $file)
15556         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
15557         local dv2=$($LFS data_version $file)
15558         [[ $dv1 != $dv2 ]] ||
15559                 error "data version did not change on write $dv1 == $dv2"
15560
15561         # clean up
15562         rm -f $file1
15563 }
15564 run_test 187a "Test data version change"
15565
15566 test_187b() {
15567         remote_mds_nodsh && skip "remote MDS with nodsh"
15568         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
15569                 skip "Need MDS version at least 2.3.0"
15570
15571         local dir0=$DIR/$tdir/$testnum
15572         mkdir -p $dir0 || error "creating dir $dir0"
15573
15574         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
15575         [[ ${DV[0]} != ${DV[1]} ]] ||
15576                 error "data version did not change on write"\
15577                       " ${DV[0]} == ${DV[1]}"
15578
15579         # clean up
15580         rm -f $file1
15581 }
15582 run_test 187b "Test data version change on volatile file"
15583
15584 test_200() {
15585         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15586         remote_mgs_nodsh && skip "remote MGS with nodsh"
15587         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15588
15589         local POOL=${POOL:-cea1}
15590         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
15591         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
15592         # Pool OST targets
15593         local first_ost=0
15594         local last_ost=$(($OSTCOUNT - 1))
15595         local ost_step=2
15596         local ost_list=$(seq $first_ost $ost_step $last_ost)
15597         local ost_range="$first_ost $last_ost $ost_step"
15598         local test_path=$POOL_ROOT/$POOL_DIR_NAME
15599         local file_dir=$POOL_ROOT/file_tst
15600         local subdir=$test_path/subdir
15601         local rc=0
15602
15603         while : ; do
15604                 # former test_200a test_200b
15605                 pool_add $POOL                          || { rc=$? ; break; }
15606                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
15607                 # former test_200c test_200d
15608                 mkdir -p $test_path
15609                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
15610                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
15611                 mkdir -p $subdir
15612                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
15613                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
15614                                                         || { rc=$? ; break; }
15615                 # former test_200e test_200f
15616                 local files=$((OSTCOUNT*3))
15617                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
15618                                                         || { rc=$? ; break; }
15619                 pool_create_files $POOL $file_dir $files "$ost_list" \
15620                                                         || { rc=$? ; break; }
15621                 # former test_200g test_200h
15622                 pool_lfs_df $POOL                       || { rc=$? ; break; }
15623                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
15624
15625                 # former test_201a test_201b test_201c
15626                 pool_remove_first_target $POOL          || { rc=$? ; break; }
15627
15628                 local f=$test_path/$tfile
15629                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
15630                 pool_remove $POOL $f                    || { rc=$? ; break; }
15631                 break
15632         done
15633
15634         destroy_test_pools
15635
15636         return $rc
15637 }
15638 run_test 200 "OST pools"
15639
15640 # usage: default_attr <count | size | offset>
15641 default_attr() {
15642         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
15643 }
15644
15645 # usage: check_default_stripe_attr
15646 check_default_stripe_attr() {
15647         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
15648         case $1 in
15649         --stripe-count|-c)
15650                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
15651         --stripe-size|-S)
15652                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
15653         --stripe-index|-i)
15654                 EXPECTED=-1;;
15655         *)
15656                 error "unknown getstripe attr '$1'"
15657         esac
15658
15659         [ $ACTUAL == $EXPECTED ] ||
15660                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
15661 }
15662
15663 test_204a() {
15664         test_mkdir $DIR/$tdir
15665         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
15666
15667         check_default_stripe_attr --stripe-count
15668         check_default_stripe_attr --stripe-size
15669         check_default_stripe_attr --stripe-index
15670 }
15671 run_test 204a "Print default stripe attributes"
15672
15673 test_204b() {
15674         test_mkdir $DIR/$tdir
15675         $LFS setstripe --stripe-count 1 $DIR/$tdir
15676
15677         check_default_stripe_attr --stripe-size
15678         check_default_stripe_attr --stripe-index
15679 }
15680 run_test 204b "Print default stripe size and offset"
15681
15682 test_204c() {
15683         test_mkdir $DIR/$tdir
15684         $LFS setstripe --stripe-size 65536 $DIR/$tdir
15685
15686         check_default_stripe_attr --stripe-count
15687         check_default_stripe_attr --stripe-index
15688 }
15689 run_test 204c "Print default stripe count and offset"
15690
15691 test_204d() {
15692         test_mkdir $DIR/$tdir
15693         $LFS setstripe --stripe-index 0 $DIR/$tdir
15694
15695         check_default_stripe_attr --stripe-count
15696         check_default_stripe_attr --stripe-size
15697 }
15698 run_test 204d "Print default stripe count and size"
15699
15700 test_204e() {
15701         test_mkdir $DIR/$tdir
15702         $LFS setstripe -d $DIR/$tdir
15703
15704         check_default_stripe_attr --stripe-count --raw
15705         check_default_stripe_attr --stripe-size --raw
15706         check_default_stripe_attr --stripe-index --raw
15707 }
15708 run_test 204e "Print raw stripe attributes"
15709
15710 test_204f() {
15711         test_mkdir $DIR/$tdir
15712         $LFS setstripe --stripe-count 1 $DIR/$tdir
15713
15714         check_default_stripe_attr --stripe-size --raw
15715         check_default_stripe_attr --stripe-index --raw
15716 }
15717 run_test 204f "Print raw stripe size and offset"
15718
15719 test_204g() {
15720         test_mkdir $DIR/$tdir
15721         $LFS setstripe --stripe-size 65536 $DIR/$tdir
15722
15723         check_default_stripe_attr --stripe-count --raw
15724         check_default_stripe_attr --stripe-index --raw
15725 }
15726 run_test 204g "Print raw stripe count and offset"
15727
15728 test_204h() {
15729         test_mkdir $DIR/$tdir
15730         $LFS setstripe --stripe-index 0 $DIR/$tdir
15731
15732         check_default_stripe_attr --stripe-count --raw
15733         check_default_stripe_attr --stripe-size --raw
15734 }
15735 run_test 204h "Print raw stripe count and size"
15736
15737 # Figure out which job scheduler is being used, if any,
15738 # or use a fake one
15739 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
15740         JOBENV=SLURM_JOB_ID
15741 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
15742         JOBENV=LSB_JOBID
15743 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
15744         JOBENV=PBS_JOBID
15745 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
15746         JOBENV=LOADL_STEP_ID
15747 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
15748         JOBENV=JOB_ID
15749 else
15750         $LCTL list_param jobid_name > /dev/null 2>&1
15751         if [ $? -eq 0 ]; then
15752                 JOBENV=nodelocal
15753         else
15754                 JOBENV=FAKE_JOBID
15755         fi
15756 fi
15757 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
15758
15759 verify_jobstats() {
15760         local cmd=($1)
15761         shift
15762         local facets="$@"
15763
15764 # we don't really need to clear the stats for this test to work, since each
15765 # command has a unique jobid, but it makes debugging easier if needed.
15766 #       for facet in $facets; do
15767 #               local dev=$(convert_facet2label $facet)
15768 #               # clear old jobstats
15769 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
15770 #       done
15771
15772         # use a new JobID for each test, or we might see an old one
15773         [ "$JOBENV" = "FAKE_JOBID" ] &&
15774                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
15775
15776         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
15777
15778         [ "$JOBENV" = "nodelocal" ] && {
15779                 FAKE_JOBID=id.$testnum.%e.$RANDOM
15780                 $LCTL set_param jobid_name=$FAKE_JOBID
15781                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
15782         }
15783
15784         log "Test: ${cmd[*]}"
15785         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
15786
15787         if [ $JOBENV = "FAKE_JOBID" ]; then
15788                 FAKE_JOBID=$JOBVAL ${cmd[*]}
15789         else
15790                 ${cmd[*]}
15791         fi
15792
15793         # all files are created on OST0000
15794         for facet in $facets; do
15795                 local stats="*.$(convert_facet2label $facet).job_stats"
15796
15797                 # strip out libtool wrappers for in-tree executables
15798                 if [ $(do_facet $facet lctl get_param $stats |
15799                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
15800                         do_facet $facet lctl get_param $stats
15801                         error "No jobstats for $JOBVAL found on $facet::$stats"
15802                 fi
15803         done
15804 }
15805
15806 jobstats_set() {
15807         local new_jobenv=$1
15808
15809         set_persistent_param_and_check client "jobid_var" \
15810                 "$FSNAME.sys.jobid_var" $new_jobenv
15811 }
15812
15813 test_205a() { # Job stats
15814         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15815         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
15816                 skip "Need MDS version with at least 2.7.1"
15817         remote_mgs_nodsh && skip "remote MGS with nodsh"
15818         remote_mds_nodsh && skip "remote MDS with nodsh"
15819         remote_ost_nodsh && skip "remote OST with nodsh"
15820         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
15821                 skip "Server doesn't support jobstats"
15822         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
15823
15824         local old_jobenv=$($LCTL get_param -n jobid_var)
15825         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
15826
15827         if [[ $PERM_CMD == *"set_param -P"* ]]; then
15828                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
15829         else
15830                 stack_trap "do_facet mgs $PERM_CMD \
15831                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
15832         fi
15833         changelog_register
15834
15835         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
15836                                 mdt.*.job_cleanup_interval | head -n 1)
15837         local new_interval=5
15838         do_facet $SINGLEMDS \
15839                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
15840         stack_trap "do_facet $SINGLEMDS \
15841                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
15842         local start=$SECONDS
15843
15844         local cmd
15845         # mkdir
15846         cmd="mkdir $DIR/$tdir"
15847         verify_jobstats "$cmd" "$SINGLEMDS"
15848         # rmdir
15849         cmd="rmdir $DIR/$tdir"
15850         verify_jobstats "$cmd" "$SINGLEMDS"
15851         # mkdir on secondary MDT
15852         if [ $MDSCOUNT -gt 1 ]; then
15853                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
15854                 verify_jobstats "$cmd" "mds2"
15855         fi
15856         # mknod
15857         cmd="mknod $DIR/$tfile c 1 3"
15858         verify_jobstats "$cmd" "$SINGLEMDS"
15859         # unlink
15860         cmd="rm -f $DIR/$tfile"
15861         verify_jobstats "$cmd" "$SINGLEMDS"
15862         # create all files on OST0000 so verify_jobstats can find OST stats
15863         # open & close
15864         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
15865         verify_jobstats "$cmd" "$SINGLEMDS"
15866         # setattr
15867         cmd="touch $DIR/$tfile"
15868         verify_jobstats "$cmd" "$SINGLEMDS ost1"
15869         # write
15870         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
15871         verify_jobstats "$cmd" "ost1"
15872         # read
15873         cancel_lru_locks osc
15874         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
15875         verify_jobstats "$cmd" "ost1"
15876         # truncate
15877         cmd="$TRUNCATE $DIR/$tfile 0"
15878         verify_jobstats "$cmd" "$SINGLEMDS ost1"
15879         # rename
15880         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
15881         verify_jobstats "$cmd" "$SINGLEMDS"
15882         # jobstats expiry - sleep until old stats should be expired
15883         local left=$((new_interval + 5 - (SECONDS - start)))
15884         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
15885                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
15886                         "0" $left
15887         cmd="mkdir $DIR/$tdir.expire"
15888         verify_jobstats "$cmd" "$SINGLEMDS"
15889         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
15890             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
15891
15892         # Ensure that jobid are present in changelog (if supported by MDS)
15893         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
15894                 changelog_dump | tail -10
15895                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
15896                 [ $jobids -eq 9 ] ||
15897                         error "Wrong changelog jobid count $jobids != 9"
15898
15899                 # LU-5862
15900                 JOBENV="disable"
15901                 jobstats_set $JOBENV
15902                 touch $DIR/$tfile
15903                 changelog_dump | grep $tfile
15904                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
15905                 [ $jobids -eq 0 ] ||
15906                         error "Unexpected jobids when jobid_var=$JOBENV"
15907         fi
15908
15909         lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"
15910         JOBENV="JOBCOMPLEX"
15911         JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
15912
15913         verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
15914 }
15915 run_test 205a "Verify job stats"
15916
15917 # LU-13117
15918 test_205b() {
15919         $LCTL set_param jobid_var=USER jobid_name="%e.%u"
15920         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
15921         do_facet $SINGLEMDS $LCTL get_param mdt.*.job_stats |
15922                 grep job_id: | grep foolish &&
15923                         error "Unexpected jobid found"
15924         true
15925 }
15926 run_test 205b "Verify job stats jobid parsing"
15927
15928 # LU-1480, LU-1773 and LU-1657
15929 test_206() {
15930         mkdir -p $DIR/$tdir
15931         $LFS setstripe -c -1 $DIR/$tdir
15932 #define OBD_FAIL_LOV_INIT 0x1403
15933         $LCTL set_param fail_loc=0xa0001403
15934         $LCTL set_param fail_val=1
15935         touch $DIR/$tdir/$tfile || true
15936 }
15937 run_test 206 "fail lov_init_raid0() doesn't lbug"
15938
15939 test_207a() {
15940         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
15941         local fsz=`stat -c %s $DIR/$tfile`
15942         cancel_lru_locks mdc
15943
15944         # do not return layout in getattr intent
15945 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
15946         $LCTL set_param fail_loc=0x170
15947         local sz=`stat -c %s $DIR/$tfile`
15948
15949         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
15950
15951         rm -rf $DIR/$tfile
15952 }
15953 run_test 207a "can refresh layout at glimpse"
15954
15955 test_207b() {
15956         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
15957         local cksum=`md5sum $DIR/$tfile`
15958         local fsz=`stat -c %s $DIR/$tfile`
15959         cancel_lru_locks mdc
15960         cancel_lru_locks osc
15961
15962         # do not return layout in getattr intent
15963 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
15964         $LCTL set_param fail_loc=0x171
15965
15966         # it will refresh layout after the file is opened but before read issues
15967         echo checksum is "$cksum"
15968         echo "$cksum" |md5sum -c --quiet || error "file differs"
15969
15970         rm -rf $DIR/$tfile
15971 }
15972 run_test 207b "can refresh layout at open"
15973
15974 test_208() {
15975         # FIXME: in this test suite, only RD lease is used. This is okay
15976         # for now as only exclusive open is supported. After generic lease
15977         # is done, this test suite should be revised. - Jinshan
15978
15979         remote_mds_nodsh && skip "remote MDS with nodsh"
15980         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
15981                 skip "Need MDS version at least 2.4.52"
15982
15983         echo "==== test 1: verify get lease work"
15984         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
15985
15986         echo "==== test 2: verify lease can be broken by upcoming open"
15987         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
15988         local PID=$!
15989         sleep 1
15990
15991         $MULTIOP $DIR/$tfile oO_RDONLY:c
15992         kill -USR1 $PID && wait $PID || error "break lease error"
15993
15994         echo "==== test 3: verify lease can't be granted if an open already exists"
15995         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
15996         local PID=$!
15997         sleep 1
15998
15999         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
16000         kill -USR1 $PID && wait $PID || error "open file error"
16001
16002         echo "==== test 4: lease can sustain over recovery"
16003         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
16004         PID=$!
16005         sleep 1
16006
16007         fail mds1
16008
16009         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
16010
16011         echo "==== test 5: lease broken can't be regained by replay"
16012         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
16013         PID=$!
16014         sleep 1
16015
16016         # open file to break lease and then recovery
16017         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
16018         fail mds1
16019
16020         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
16021
16022         rm -f $DIR/$tfile
16023 }
16024 run_test 208 "Exclusive open"
16025
16026 test_209() {
16027         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
16028                 skip_env "must have disp_stripe"
16029
16030         touch $DIR/$tfile
16031         sync; sleep 5; sync;
16032
16033         echo 3 > /proc/sys/vm/drop_caches
16034         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
16035
16036         # open/close 500 times
16037         for i in $(seq 500); do
16038                 cat $DIR/$tfile
16039         done
16040
16041         echo 3 > /proc/sys/vm/drop_caches
16042         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
16043
16044         echo "before: $req_before, after: $req_after"
16045         [ $((req_after - req_before)) -ge 300 ] &&
16046                 error "open/close requests are not freed"
16047         return 0
16048 }
16049 run_test 209 "read-only open/close requests should be freed promptly"
16050
16051 test_212() {
16052         size=`date +%s`
16053         size=$((size % 8192 + 1))
16054         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
16055         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
16056         rm -f $DIR/f212 $DIR/f212.xyz
16057 }
16058 run_test 212 "Sendfile test ============================================"
16059
16060 test_213() {
16061         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
16062         cancel_lru_locks osc
16063         lctl set_param fail_loc=0x8000040f
16064         # generate a read lock
16065         cat $DIR/$tfile > /dev/null
16066         # write to the file, it will try to cancel the above read lock.
16067         cat /etc/hosts >> $DIR/$tfile
16068 }
16069 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
16070
16071 test_214() { # for bug 20133
16072         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
16073         for (( i=0; i < 340; i++ )) ; do
16074                 touch $DIR/$tdir/d214c/a$i
16075         done
16076
16077         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
16078         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
16079         ls $DIR/d214c || error "ls $DIR/d214c failed"
16080         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
16081         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
16082 }
16083 run_test 214 "hash-indexed directory test - bug 20133"
16084
16085 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
16086 create_lnet_proc_files() {
16087         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
16088 }
16089
16090 # counterpart of create_lnet_proc_files
16091 remove_lnet_proc_files() {
16092         rm -f $TMP/lnet_$1.sys
16093 }
16094
16095 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
16096 # 3rd arg as regexp for body
16097 check_lnet_proc_stats() {
16098         local l=$(cat "$TMP/lnet_$1" |wc -l)
16099         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
16100
16101         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
16102 }
16103
16104 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
16105 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
16106 # optional and can be regexp for 2nd line (lnet.routes case)
16107 check_lnet_proc_entry() {
16108         local blp=2          # blp stands for 'position of 1st line of body'
16109         [ -z "$5" ] || blp=3 # lnet.routes case
16110
16111         local l=$(cat "$TMP/lnet_$1" |wc -l)
16112         # subtracting one from $blp because the body can be empty
16113         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
16114
16115         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
16116                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
16117
16118         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
16119                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
16120
16121         # bail out if any unexpected line happened
16122         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
16123         [ "$?" != 0 ] || error "$2 misformatted"
16124 }
16125
16126 test_215() { # for bugs 18102, 21079, 21517
16127         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16128
16129         local N='(0|[1-9][0-9]*)'       # non-negative numeric
16130         local P='[1-9][0-9]*'           # positive numeric
16131         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
16132         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
16133         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
16134         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
16135
16136         local L1 # regexp for 1st line
16137         local L2 # regexp for 2nd line (optional)
16138         local BR # regexp for the rest (body)
16139
16140         # lnet.stats should look as 11 space-separated non-negative numerics
16141         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
16142         create_lnet_proc_files "stats"
16143         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
16144         remove_lnet_proc_files "stats"
16145
16146         # lnet.routes should look like this:
16147         # Routing disabled/enabled
16148         # net hops priority state router
16149         # where net is a string like tcp0, hops > 0, priority >= 0,
16150         # state is up/down,
16151         # router is a string like 192.168.1.1@tcp2
16152         L1="^Routing (disabled|enabled)$"
16153         L2="^net +hops +priority +state +router$"
16154         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
16155         create_lnet_proc_files "routes"
16156         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
16157         remove_lnet_proc_files "routes"
16158
16159         # lnet.routers should look like this:
16160         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
16161         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
16162         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
16163         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
16164         L1="^ref +rtr_ref +alive +router$"
16165         BR="^$P +$P +(up|down) +$NID$"
16166         create_lnet_proc_files "routers"
16167         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
16168         remove_lnet_proc_files "routers"
16169
16170         # lnet.peers should look like this:
16171         # nid refs state last max rtr min tx min queue
16172         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
16173         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
16174         # numeric (0 or >0 or <0), queue >= 0.
16175         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
16176         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
16177         create_lnet_proc_files "peers"
16178         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
16179         remove_lnet_proc_files "peers"
16180
16181         # lnet.buffers  should look like this:
16182         # pages count credits min
16183         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
16184         L1="^pages +count +credits +min$"
16185         BR="^ +$N +$N +$I +$I$"
16186         create_lnet_proc_files "buffers"
16187         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
16188         remove_lnet_proc_files "buffers"
16189
16190         # lnet.nis should look like this:
16191         # nid status alive refs peer rtr max tx min
16192         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
16193         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
16194         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
16195         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
16196         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
16197         create_lnet_proc_files "nis"
16198         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
16199         remove_lnet_proc_files "nis"
16200
16201         # can we successfully write to lnet.stats?
16202         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
16203 }
16204 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
16205
16206 test_216() { # bug 20317
16207         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16208         remote_ost_nodsh && skip "remote OST with nodsh"
16209
16210         local node
16211         local facets=$(get_facets OST)
16212         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16213
16214         save_lustre_params client "osc.*.contention_seconds" > $p
16215         save_lustre_params $facets \
16216                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
16217         save_lustre_params $facets \
16218                 "ldlm.namespaces.filter-*.contended_locks" >> $p
16219         save_lustre_params $facets \
16220                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
16221         clear_stats osc.*.osc_stats
16222
16223         # agressive lockless i/o settings
16224         do_nodes $(comma_list $(osts_nodes)) \
16225                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
16226                         ldlm.namespaces.filter-*.contended_locks=0 \
16227                         ldlm.namespaces.filter-*.contention_seconds=60"
16228         lctl set_param -n osc.*.contention_seconds=60
16229
16230         $DIRECTIO write $DIR/$tfile 0 10 4096
16231         $CHECKSTAT -s 40960 $DIR/$tfile
16232
16233         # disable lockless i/o
16234         do_nodes $(comma_list $(osts_nodes)) \
16235                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
16236                         ldlm.namespaces.filter-*.contended_locks=32 \
16237                         ldlm.namespaces.filter-*.contention_seconds=0"
16238         lctl set_param -n osc.*.contention_seconds=0
16239         clear_stats osc.*.osc_stats
16240
16241         dd if=/dev/zero of=$DIR/$tfile count=0
16242         $CHECKSTAT -s 0 $DIR/$tfile
16243
16244         restore_lustre_params <$p
16245         rm -f $p
16246         rm $DIR/$tfile
16247 }
16248 run_test 216 "check lockless direct write updates file size and kms correctly"
16249
16250 test_217() { # bug 22430
16251         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16252
16253         local node
16254         local nid
16255
16256         for node in $(nodes_list); do
16257                 nid=$(host_nids_address $node $NETTYPE)
16258                 if [[ $nid = *-* ]] ; then
16259                         echo "lctl ping $(h2nettype $nid)"
16260                         lctl ping $(h2nettype $nid)
16261                 else
16262                         echo "skipping $node (no hyphen detected)"
16263                 fi
16264         done
16265 }
16266 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
16267
16268 test_218() {
16269        # do directio so as not to populate the page cache
16270        log "creating a 10 Mb file"
16271        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
16272        log "starting reads"
16273        dd if=$DIR/$tfile of=/dev/null bs=4096 &
16274        log "truncating the file"
16275        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
16276        log "killing dd"
16277        kill %+ || true # reads might have finished
16278        echo "wait until dd is finished"
16279        wait
16280        log "removing the temporary file"
16281        rm -rf $DIR/$tfile || error "tmp file removal failed"
16282 }
16283 run_test 218 "parallel read and truncate should not deadlock"
16284
16285 test_219() {
16286         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16287
16288         # write one partial page
16289         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
16290         # set no grant so vvp_io_commit_write will do sync write
16291         $LCTL set_param fail_loc=0x411
16292         # write a full page at the end of file
16293         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
16294
16295         $LCTL set_param fail_loc=0
16296         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
16297         $LCTL set_param fail_loc=0x411
16298         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
16299
16300         # LU-4201
16301         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
16302         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
16303 }
16304 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
16305
16306 test_220() { #LU-325
16307         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16308         remote_ost_nodsh && skip "remote OST with nodsh"
16309         remote_mds_nodsh && skip "remote MDS with nodsh"
16310         remote_mgs_nodsh && skip "remote MGS with nodsh"
16311
16312         local OSTIDX=0
16313
16314         # create on MDT0000 so the last_id and next_id are correct
16315         mkdir $DIR/$tdir
16316         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
16317         OST=${OST%_UUID}
16318
16319         # on the mdt's osc
16320         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
16321         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
16322                         osp.$mdtosc_proc1.prealloc_last_id)
16323         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
16324                         osp.$mdtosc_proc1.prealloc_next_id)
16325
16326         $LFS df -i
16327
16328         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
16329         #define OBD_FAIL_OST_ENOINO              0x229
16330         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
16331         create_pool $FSNAME.$TESTNAME || return 1
16332         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
16333
16334         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
16335
16336         MDSOBJS=$((last_id - next_id))
16337         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
16338
16339         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
16340         echo "OST still has $count kbytes free"
16341
16342         echo "create $MDSOBJS files @next_id..."
16343         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
16344
16345         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
16346                         osp.$mdtosc_proc1.prealloc_last_id)
16347         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
16348                         osp.$mdtosc_proc1.prealloc_next_id)
16349
16350         echo "after creation, last_id=$last_id2, next_id=$next_id2"
16351         $LFS df -i
16352
16353         echo "cleanup..."
16354
16355         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
16356         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
16357
16358         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
16359                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
16360         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
16361                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
16362         echo "unlink $MDSOBJS files @$next_id..."
16363         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
16364 }
16365 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
16366
16367 test_221() {
16368         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16369
16370         dd if=`which date` of=$MOUNT/date oflag=sync
16371         chmod +x $MOUNT/date
16372
16373         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
16374         $LCTL set_param fail_loc=0x80001401
16375
16376         $MOUNT/date > /dev/null
16377         rm -f $MOUNT/date
16378 }
16379 run_test 221 "make sure fault and truncate race to not cause OOM"
16380
16381 test_222a () {
16382         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16383
16384         rm -rf $DIR/$tdir
16385         test_mkdir $DIR/$tdir
16386         $LFS setstripe -c 1 -i 0 $DIR/$tdir
16387         createmany -o $DIR/$tdir/$tfile 10
16388         cancel_lru_locks mdc
16389         cancel_lru_locks osc
16390         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
16391         $LCTL set_param fail_loc=0x31a
16392         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
16393         $LCTL set_param fail_loc=0
16394         rm -r $DIR/$tdir
16395 }
16396 run_test 222a "AGL for ls should not trigger CLIO lock failure"
16397
16398 test_222b () {
16399         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16400
16401         rm -rf $DIR/$tdir
16402         test_mkdir $DIR/$tdir
16403         $LFS setstripe -c 1 -i 0 $DIR/$tdir
16404         createmany -o $DIR/$tdir/$tfile 10
16405         cancel_lru_locks mdc
16406         cancel_lru_locks osc
16407         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
16408         $LCTL set_param fail_loc=0x31a
16409         rm -r $DIR/$tdir || error "AGL for rmdir failed"
16410         $LCTL set_param fail_loc=0
16411 }
16412 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
16413
16414 test_223 () {
16415         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16416
16417         rm -rf $DIR/$tdir
16418         test_mkdir $DIR/$tdir
16419         $LFS setstripe -c 1 -i 0 $DIR/$tdir
16420         createmany -o $DIR/$tdir/$tfile 10
16421         cancel_lru_locks mdc
16422         cancel_lru_locks osc
16423         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
16424         $LCTL set_param fail_loc=0x31b
16425         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
16426         $LCTL set_param fail_loc=0
16427         rm -r $DIR/$tdir
16428 }
16429 run_test 223 "osc reenqueue if without AGL lock granted ======================="
16430
16431 test_224a() { # LU-1039, MRP-303
16432         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16433
16434         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
16435         $LCTL set_param fail_loc=0x508
16436         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
16437         $LCTL set_param fail_loc=0
16438         df $DIR
16439 }
16440 run_test 224a "Don't panic on bulk IO failure"
16441
16442 test_224b() { # LU-1039, MRP-303
16443         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16444
16445         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
16446         cancel_lru_locks osc
16447         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
16448         $LCTL set_param fail_loc=0x515
16449         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
16450         $LCTL set_param fail_loc=0
16451         df $DIR
16452 }
16453 run_test 224b "Don't panic on bulk IO failure"
16454
16455 test_224c() { # LU-6441
16456         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16457         remote_mds_nodsh && skip "remote MDS with nodsh"
16458
16459         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16460         save_writethrough $p
16461         set_cache writethrough on
16462
16463         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
16464         local at_max=$($LCTL get_param -n at_max)
16465         local timeout=$($LCTL get_param -n timeout)
16466         local test_at="at_max"
16467         local param_at="$FSNAME.sys.at_max"
16468         local test_timeout="timeout"
16469         local param_timeout="$FSNAME.sys.timeout"
16470
16471         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
16472
16473         set_persistent_param_and_check client "$test_at" "$param_at" 0
16474         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
16475
16476         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
16477         do_facet ost1 "$LCTL set_param fail_loc=0x520"
16478         $LFS setstripe -c 1 -i 0 $DIR/$tfile
16479         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
16480         sync
16481         do_facet ost1 "$LCTL set_param fail_loc=0"
16482
16483         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
16484         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
16485                 $timeout
16486
16487         $LCTL set_param -n $pages_per_rpc
16488         restore_lustre_params < $p
16489         rm -f $p
16490 }
16491 run_test 224c "Don't hang if one of md lost during large bulk RPC"
16492
16493 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
16494 test_225a () {
16495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16496         if [ -z ${MDSSURVEY} ]; then
16497                 skip_env "mds-survey not found"
16498         fi
16499         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
16500                 skip "Need MDS version at least 2.2.51"
16501
16502         local mds=$(facet_host $SINGLEMDS)
16503         local target=$(do_nodes $mds 'lctl dl' |
16504                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
16505
16506         local cmd1="file_count=1000 thrhi=4"
16507         local cmd2="dir_count=2 layer=mdd stripe_count=0"
16508         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
16509         local cmd="$cmd1 $cmd2 $cmd3"
16510
16511         rm -f ${TMP}/mds_survey*
16512         echo + $cmd
16513         eval $cmd || error "mds-survey with zero-stripe failed"
16514         cat ${TMP}/mds_survey*
16515         rm -f ${TMP}/mds_survey*
16516 }
16517 run_test 225a "Metadata survey sanity with zero-stripe"
16518
16519 test_225b () {
16520         if [ -z ${MDSSURVEY} ]; then
16521                 skip_env "mds-survey not found"
16522         fi
16523         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
16524                 skip "Need MDS version at least 2.2.51"
16525         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16526         remote_mds_nodsh && skip "remote MDS with nodsh"
16527         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
16528                 skip_env "Need to mount OST to test"
16529         fi
16530
16531         local mds=$(facet_host $SINGLEMDS)
16532         local target=$(do_nodes $mds 'lctl dl' |
16533                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
16534
16535         local cmd1="file_count=1000 thrhi=4"
16536         local cmd2="dir_count=2 layer=mdd stripe_count=1"
16537         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
16538         local cmd="$cmd1 $cmd2 $cmd3"
16539
16540         rm -f ${TMP}/mds_survey*
16541         echo + $cmd
16542         eval $cmd || error "mds-survey with stripe_count failed"
16543         cat ${TMP}/mds_survey*
16544         rm -f ${TMP}/mds_survey*
16545 }
16546 run_test 225b "Metadata survey sanity with stripe_count = 1"
16547
16548 mcreate_path2fid () {
16549         local mode=$1
16550         local major=$2
16551         local minor=$3
16552         local name=$4
16553         local desc=$5
16554         local path=$DIR/$tdir/$name
16555         local fid
16556         local rc
16557         local fid_path
16558
16559         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
16560                 error "cannot create $desc"
16561
16562         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
16563         rc=$?
16564         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
16565
16566         fid_path=$($LFS fid2path $MOUNT $fid)
16567         rc=$?
16568         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
16569
16570         [ "$path" == "$fid_path" ] ||
16571                 error "fid2path returned $fid_path, expected $path"
16572
16573         echo "pass with $path and $fid"
16574 }
16575
16576 test_226a () {
16577         rm -rf $DIR/$tdir
16578         mkdir -p $DIR/$tdir
16579
16580         mcreate_path2fid 0010666 0 0 fifo "FIFO"
16581         mcreate_path2fid 0020666 1 3 null "character special file (null)"
16582         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
16583         mcreate_path2fid 0040666 0 0 dir "directory"
16584         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
16585         mcreate_path2fid 0100666 0 0 file "regular file"
16586         mcreate_path2fid 0120666 0 0 link "symbolic link"
16587         mcreate_path2fid 0140666 0 0 sock "socket"
16588 }
16589 run_test 226a "call path2fid and fid2path on files of all type"
16590
16591 test_226b () {
16592         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16593
16594         local MDTIDX=1
16595
16596         rm -rf $DIR/$tdir
16597         mkdir -p $DIR/$tdir
16598         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
16599                 error "create remote directory failed"
16600         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
16601         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
16602                                 "character special file (null)"
16603         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
16604                                 "character special file (no device)"
16605         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
16606         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
16607                                 "block special file (loop)"
16608         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
16609         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
16610         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
16611 }
16612 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
16613
16614 # LU-1299 Executing or running ldd on a truncated executable does not
16615 # cause an out-of-memory condition.
16616 test_227() {
16617         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16618         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
16619
16620         dd if=$(which date) of=$MOUNT/date bs=1k count=1
16621         chmod +x $MOUNT/date
16622
16623         $MOUNT/date > /dev/null
16624         ldd $MOUNT/date > /dev/null
16625         rm -f $MOUNT/date
16626 }
16627 run_test 227 "running truncated executable does not cause OOM"
16628
16629 # LU-1512 try to reuse idle OI blocks
16630 test_228a() {
16631         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16632         remote_mds_nodsh && skip "remote MDS with nodsh"
16633         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
16634
16635         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
16636         local myDIR=$DIR/$tdir
16637
16638         mkdir -p $myDIR
16639         #define OBD_FAIL_SEQ_EXHAUST             0x1002
16640         $LCTL set_param fail_loc=0x80001002
16641         createmany -o $myDIR/t- 10000
16642         $LCTL set_param fail_loc=0
16643         # The guard is current the largest FID holder
16644         touch $myDIR/guard
16645         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
16646                     tr -d '[')
16647         local IDX=$(($SEQ % 64))
16648
16649         do_facet $SINGLEMDS sync
16650         # Make sure journal flushed.
16651         sleep 6
16652         local blk1=$(do_facet $SINGLEMDS \
16653                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16654                      grep Blockcount | awk '{print $4}')
16655
16656         # Remove old files, some OI blocks will become idle.
16657         unlinkmany $myDIR/t- 10000
16658         # Create new files, idle OI blocks should be reused.
16659         createmany -o $myDIR/t- 2000
16660         do_facet $SINGLEMDS sync
16661         # Make sure journal flushed.
16662         sleep 6
16663         local blk2=$(do_facet $SINGLEMDS \
16664                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16665                      grep Blockcount | awk '{print $4}')
16666
16667         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
16668 }
16669 run_test 228a "try to reuse idle OI blocks"
16670
16671 test_228b() {
16672         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16673         remote_mds_nodsh && skip "remote MDS with nodsh"
16674         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
16675
16676         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
16677         local myDIR=$DIR/$tdir
16678
16679         mkdir -p $myDIR
16680         #define OBD_FAIL_SEQ_EXHAUST             0x1002
16681         $LCTL set_param fail_loc=0x80001002
16682         createmany -o $myDIR/t- 10000
16683         $LCTL set_param fail_loc=0
16684         # The guard is current the largest FID holder
16685         touch $myDIR/guard
16686         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
16687                     tr -d '[')
16688         local IDX=$(($SEQ % 64))
16689
16690         do_facet $SINGLEMDS sync
16691         # Make sure journal flushed.
16692         sleep 6
16693         local blk1=$(do_facet $SINGLEMDS \
16694                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16695                      grep Blockcount | awk '{print $4}')
16696
16697         # Remove old files, some OI blocks will become idle.
16698         unlinkmany $myDIR/t- 10000
16699
16700         # stop the MDT
16701         stop $SINGLEMDS || error "Fail to stop MDT."
16702         # remount the MDT
16703         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
16704
16705         df $MOUNT || error "Fail to df."
16706         # Create new files, idle OI blocks should be reused.
16707         createmany -o $myDIR/t- 2000
16708         do_facet $SINGLEMDS sync
16709         # Make sure journal flushed.
16710         sleep 6
16711         local blk2=$(do_facet $SINGLEMDS \
16712                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16713                      grep Blockcount | awk '{print $4}')
16714
16715         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
16716 }
16717 run_test 228b "idle OI blocks can be reused after MDT restart"
16718
16719 #LU-1881
16720 test_228c() {
16721         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16722         remote_mds_nodsh && skip "remote MDS with nodsh"
16723         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
16724
16725         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
16726         local myDIR=$DIR/$tdir
16727
16728         mkdir -p $myDIR
16729         #define OBD_FAIL_SEQ_EXHAUST             0x1002
16730         $LCTL set_param fail_loc=0x80001002
16731         # 20000 files can guarantee there are index nodes in the OI file
16732         createmany -o $myDIR/t- 20000
16733         $LCTL set_param fail_loc=0
16734         # The guard is current the largest FID holder
16735         touch $myDIR/guard
16736         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
16737                     tr -d '[')
16738         local IDX=$(($SEQ % 64))
16739
16740         do_facet $SINGLEMDS sync
16741         # Make sure journal flushed.
16742         sleep 6
16743         local blk1=$(do_facet $SINGLEMDS \
16744                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16745                      grep Blockcount | awk '{print $4}')
16746
16747         # Remove old files, some OI blocks will become idle.
16748         unlinkmany $myDIR/t- 20000
16749         rm -f $myDIR/guard
16750         # The OI file should become empty now
16751
16752         # Create new files, idle OI blocks should be reused.
16753         createmany -o $myDIR/t- 2000
16754         do_facet $SINGLEMDS sync
16755         # Make sure journal flushed.
16756         sleep 6
16757         local blk2=$(do_facet $SINGLEMDS \
16758                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16759                      grep Blockcount | awk '{print $4}')
16760
16761         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
16762 }
16763 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
16764
16765 test_229() { # LU-2482, LU-3448
16766         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16767         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
16768         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
16769                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
16770
16771         rm -f $DIR/$tfile
16772
16773         # Create a file with a released layout and stripe count 2.
16774         $MULTIOP $DIR/$tfile H2c ||
16775                 error "failed to create file with released layout"
16776
16777         $LFS getstripe -v $DIR/$tfile
16778
16779         local pattern=$($LFS getstripe -L $DIR/$tfile)
16780         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
16781
16782         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
16783                 error "getstripe"
16784         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
16785         stat $DIR/$tfile || error "failed to stat released file"
16786
16787         chown $RUNAS_ID $DIR/$tfile ||
16788                 error "chown $RUNAS_ID $DIR/$tfile failed"
16789
16790         chgrp $RUNAS_ID $DIR/$tfile ||
16791                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
16792
16793         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
16794         rm $DIR/$tfile || error "failed to remove released file"
16795 }
16796 run_test 229 "getstripe/stat/rm/attr changes work on released files"
16797
16798 test_230a() {
16799         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16800         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16801         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16802                 skip "Need MDS version at least 2.11.52"
16803
16804         local MDTIDX=1
16805
16806         test_mkdir $DIR/$tdir
16807         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
16808         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
16809         [ $mdt_idx -ne 0 ] &&
16810                 error "create local directory on wrong MDT $mdt_idx"
16811
16812         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
16813                         error "create remote directory failed"
16814         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
16815         [ $mdt_idx -ne $MDTIDX ] &&
16816                 error "create remote directory on wrong MDT $mdt_idx"
16817
16818         createmany -o $DIR/$tdir/test_230/t- 10 ||
16819                 error "create files on remote directory failed"
16820         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
16821         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
16822         rm -r $DIR/$tdir || error "unlink remote directory failed"
16823 }
16824 run_test 230a "Create remote directory and files under the remote directory"
16825
16826 test_230b() {
16827         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16828         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16829         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16830                 skip "Need MDS version at least 2.11.52"
16831
16832         local MDTIDX=1
16833         local mdt_index
16834         local i
16835         local file
16836         local pid
16837         local stripe_count
16838         local migrate_dir=$DIR/$tdir/migrate_dir
16839         local other_dir=$DIR/$tdir/other_dir
16840
16841         test_mkdir $DIR/$tdir
16842         test_mkdir -i0 -c1 $migrate_dir
16843         test_mkdir -i0 -c1 $other_dir
16844         for ((i=0; i<10; i++)); do
16845                 mkdir -p $migrate_dir/dir_${i}
16846                 createmany -o $migrate_dir/dir_${i}/f 10 ||
16847                         error "create files under remote dir failed $i"
16848         done
16849
16850         cp /etc/passwd $migrate_dir/$tfile
16851         cp /etc/passwd $other_dir/$tfile
16852         chattr +SAD $migrate_dir
16853         chattr +SAD $migrate_dir/$tfile
16854
16855         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
16856         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
16857         local old_dir_mode=$(stat -c%f $migrate_dir)
16858         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
16859
16860         mkdir -p $migrate_dir/dir_default_stripe2
16861         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
16862         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
16863
16864         mkdir -p $other_dir
16865         ln $migrate_dir/$tfile $other_dir/luna
16866         ln $migrate_dir/$tfile $migrate_dir/sofia
16867         ln $other_dir/$tfile $migrate_dir/david
16868         ln -s $migrate_dir/$tfile $other_dir/zachary
16869         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
16870         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
16871
16872         local len
16873         local lnktgt
16874
16875         # inline symlink
16876         for len in 58 59 60; do
16877                 lnktgt=$(str_repeat 'l' $len)
16878                 touch $migrate_dir/$lnktgt
16879                 ln -s $lnktgt $migrate_dir/${len}char_ln
16880         done
16881
16882         # PATH_MAX
16883         for len in 4094 4095; do
16884                 lnktgt=$(str_repeat 'l' $len)
16885                 ln -s $lnktgt $migrate_dir/${len}char_ln
16886         done
16887
16888         # NAME_MAX
16889         for len in 254 255; do
16890                 touch $migrate_dir/$(str_repeat 'l' $len)
16891         done
16892
16893         $LFS migrate -m $MDTIDX $migrate_dir ||
16894                 error "fails on migrating remote dir to MDT1"
16895
16896         echo "migratate to MDT1, then checking.."
16897         for ((i = 0; i < 10; i++)); do
16898                 for file in $(find $migrate_dir/dir_${i}); do
16899                         mdt_index=$($LFS getstripe -m $file)
16900                         # broken symlink getstripe will fail
16901                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
16902                                 error "$file is not on MDT${MDTIDX}"
16903                 done
16904         done
16905
16906         # the multiple link file should still in MDT0
16907         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
16908         [ $mdt_index == 0 ] ||
16909                 error "$file is not on MDT${MDTIDX}"
16910
16911         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
16912         [ "$old_dir_flag" = "$new_dir_flag" ] ||
16913                 error " expect $old_dir_flag get $new_dir_flag"
16914
16915         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
16916         [ "$old_file_flag" = "$new_file_flag" ] ||
16917                 error " expect $old_file_flag get $new_file_flag"
16918
16919         local new_dir_mode=$(stat -c%f $migrate_dir)
16920         [ "$old_dir_mode" = "$new_dir_mode" ] ||
16921                 error "expect mode $old_dir_mode get $new_dir_mode"
16922
16923         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
16924         [ "$old_file_mode" = "$new_file_mode" ] ||
16925                 error "expect mode $old_file_mode get $new_file_mode"
16926
16927         diff /etc/passwd $migrate_dir/$tfile ||
16928                 error "$tfile different after migration"
16929
16930         diff /etc/passwd $other_dir/luna ||
16931                 error "luna different after migration"
16932
16933         diff /etc/passwd $migrate_dir/sofia ||
16934                 error "sofia different after migration"
16935
16936         diff /etc/passwd $migrate_dir/david ||
16937                 error "david different after migration"
16938
16939         diff /etc/passwd $other_dir/zachary ||
16940                 error "zachary different after migration"
16941
16942         diff /etc/passwd $migrate_dir/${tfile}_ln ||
16943                 error "${tfile}_ln different after migration"
16944
16945         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
16946                 error "${tfile}_ln_other different after migration"
16947
16948         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
16949         [ $stripe_count = 2 ] ||
16950                 error "dir strpe_count $d != 2 after migration."
16951
16952         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
16953         [ $stripe_count = 2 ] ||
16954                 error "file strpe_count $d != 2 after migration."
16955
16956         #migrate back to MDT0
16957         MDTIDX=0
16958
16959         $LFS migrate -m $MDTIDX $migrate_dir ||
16960                 error "fails on migrating remote dir to MDT0"
16961
16962         echo "migrate back to MDT0, checking.."
16963         for file in $(find $migrate_dir); do
16964                 mdt_index=$($LFS getstripe -m $file)
16965                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
16966                         error "$file is not on MDT${MDTIDX}"
16967         done
16968
16969         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
16970         [ "$old_dir_flag" = "$new_dir_flag" ] ||
16971                 error " expect $old_dir_flag get $new_dir_flag"
16972
16973         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
16974         [ "$old_file_flag" = "$new_file_flag" ] ||
16975                 error " expect $old_file_flag get $new_file_flag"
16976
16977         local new_dir_mode=$(stat -c%f $migrate_dir)
16978         [ "$old_dir_mode" = "$new_dir_mode" ] ||
16979                 error "expect mode $old_dir_mode get $new_dir_mode"
16980
16981         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
16982         [ "$old_file_mode" = "$new_file_mode" ] ||
16983                 error "expect mode $old_file_mode get $new_file_mode"
16984
16985         diff /etc/passwd ${migrate_dir}/$tfile ||
16986                 error "$tfile different after migration"
16987
16988         diff /etc/passwd ${other_dir}/luna ||
16989                 error "luna different after migration"
16990
16991         diff /etc/passwd ${migrate_dir}/sofia ||
16992                 error "sofia different after migration"
16993
16994         diff /etc/passwd ${other_dir}/zachary ||
16995                 error "zachary different after migration"
16996
16997         diff /etc/passwd $migrate_dir/${tfile}_ln ||
16998                 error "${tfile}_ln different after migration"
16999
17000         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
17001                 error "${tfile}_ln_other different after migration"
17002
17003         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
17004         [ $stripe_count = 2 ] ||
17005                 error "dir strpe_count $d != 2 after migration."
17006
17007         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
17008         [ $stripe_count = 2 ] ||
17009                 error "file strpe_count $d != 2 after migration."
17010
17011         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17012 }
17013 run_test 230b "migrate directory"
17014
17015 test_230c() {
17016         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17017         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17018         remote_mds_nodsh && skip "remote MDS with nodsh"
17019         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17020                 skip "Need MDS version at least 2.11.52"
17021
17022         local MDTIDX=1
17023         local total=3
17024         local mdt_index
17025         local file
17026         local migrate_dir=$DIR/$tdir/migrate_dir
17027
17028         #If migrating directory fails in the middle, all entries of
17029         #the directory is still accessiable.
17030         test_mkdir $DIR/$tdir
17031         test_mkdir -i0 -c1 $migrate_dir
17032         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
17033         stat $migrate_dir
17034         createmany -o $migrate_dir/f $total ||
17035                 error "create files under ${migrate_dir} failed"
17036
17037         # fail after migrating top dir, and this will fail only once, so the
17038         # first sub file migration will fail (currently f3), others succeed.
17039         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
17040         do_facet mds1 lctl set_param fail_loc=0x1801
17041         local t=$(ls $migrate_dir | wc -l)
17042         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
17043                 error "migrate should fail"
17044         local u=$(ls $migrate_dir | wc -l)
17045         [ "$u" == "$t" ] || error "$u != $t during migration"
17046
17047         # add new dir/file should succeed
17048         mkdir $migrate_dir/dir ||
17049                 error "mkdir failed under migrating directory"
17050         touch $migrate_dir/file ||
17051                 error "create file failed under migrating directory"
17052
17053         # add file with existing name should fail
17054         for file in $migrate_dir/f*; do
17055                 stat $file > /dev/null || error "stat $file failed"
17056                 $OPENFILE -f O_CREAT:O_EXCL $file &&
17057                         error "open(O_CREAT|O_EXCL) $file should fail"
17058                 $MULTIOP $file m && error "create $file should fail"
17059                 touch $DIR/$tdir/remote_dir/$tfile ||
17060                         error "touch $tfile failed"
17061                 ln $DIR/$tdir/remote_dir/$tfile $file &&
17062                         error "link $file should fail"
17063                 mdt_index=$($LFS getstripe -m $file)
17064                 if [ $mdt_index == 0 ]; then
17065                         # file failed to migrate is not allowed to rename to
17066                         mv $DIR/$tdir/remote_dir/$tfile $file &&
17067                                 error "rename to $file should fail"
17068                 else
17069                         mv $DIR/$tdir/remote_dir/$tfile $file ||
17070                                 error "rename to $file failed"
17071                 fi
17072                 echo hello >> $file || error "write $file failed"
17073         done
17074
17075         # resume migration with different options should fail
17076         $LFS migrate -m 0 $migrate_dir &&
17077                 error "migrate -m 0 $migrate_dir should fail"
17078
17079         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
17080                 error "migrate -c 2 $migrate_dir should fail"
17081
17082         # resume migration should succeed
17083         $LFS migrate -m $MDTIDX $migrate_dir ||
17084                 error "migrate $migrate_dir failed"
17085
17086         echo "Finish migration, then checking.."
17087         for file in $(find $migrate_dir); do
17088                 mdt_index=$($LFS getstripe -m $file)
17089                 [ $mdt_index == $MDTIDX ] ||
17090                         error "$file is not on MDT${MDTIDX}"
17091         done
17092
17093         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17094 }
17095 run_test 230c "check directory accessiblity if migration failed"
17096
17097 test_230d() {
17098         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17099         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17100         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17101                 skip "Need MDS version at least 2.11.52"
17102         # LU-11235
17103         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
17104
17105         local migrate_dir=$DIR/$tdir/migrate_dir
17106         local old_index
17107         local new_index
17108         local old_count
17109         local new_count
17110         local new_hash
17111         local mdt_index
17112         local i
17113         local j
17114
17115         old_index=$((RANDOM % MDSCOUNT))
17116         old_count=$((MDSCOUNT - old_index))
17117         new_index=$((RANDOM % MDSCOUNT))
17118         new_count=$((MDSCOUNT - new_index))
17119         new_hash=1 # for all_char
17120
17121         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
17122         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
17123
17124         test_mkdir $DIR/$tdir
17125         test_mkdir -i $old_index -c $old_count $migrate_dir
17126
17127         for ((i=0; i<100; i++)); do
17128                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
17129                 createmany -o $migrate_dir/dir_${i}/f 100 ||
17130                         error "create files under remote dir failed $i"
17131         done
17132
17133         echo -n "Migrate from MDT$old_index "
17134         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
17135         echo -n "to MDT$new_index"
17136         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
17137         echo
17138
17139         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
17140         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
17141                 error "migrate remote dir error"
17142
17143         echo "Finish migration, then checking.."
17144         for file in $(find $migrate_dir); do
17145                 mdt_index=$($LFS getstripe -m $file)
17146                 if [ $mdt_index -lt $new_index ] ||
17147                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
17148                         error "$file is on MDT$mdt_index"
17149                 fi
17150         done
17151
17152         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17153 }
17154 run_test 230d "check migrate big directory"
17155
17156 test_230e() {
17157         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17158         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17159         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17160                 skip "Need MDS version at least 2.11.52"
17161
17162         local i
17163         local j
17164         local a_fid
17165         local b_fid
17166
17167         mkdir -p $DIR/$tdir
17168         mkdir $DIR/$tdir/migrate_dir
17169         mkdir $DIR/$tdir/other_dir
17170         touch $DIR/$tdir/migrate_dir/a
17171         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
17172         ls $DIR/$tdir/other_dir
17173
17174         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
17175                 error "migrate dir fails"
17176
17177         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
17178         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
17179
17180         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17181         [ $mdt_index == 0 ] || error "a is not on MDT0"
17182
17183         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
17184                 error "migrate dir fails"
17185
17186         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
17187         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
17188
17189         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17190         [ $mdt_index == 1 ] || error "a is not on MDT1"
17191
17192         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
17193         [ $mdt_index == 1 ] || error "b is not on MDT1"
17194
17195         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
17196         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
17197
17198         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
17199
17200         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17201 }
17202 run_test 230e "migrate mulitple local link files"
17203
17204 test_230f() {
17205         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17206         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17207         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17208                 skip "Need MDS version at least 2.11.52"
17209
17210         local a_fid
17211         local ln_fid
17212
17213         mkdir -p $DIR/$tdir
17214         mkdir $DIR/$tdir/migrate_dir
17215         $LFS mkdir -i1 $DIR/$tdir/other_dir
17216         touch $DIR/$tdir/migrate_dir/a
17217         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
17218         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
17219         ls $DIR/$tdir/other_dir
17220
17221         # a should be migrated to MDT1, since no other links on MDT0
17222         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
17223                 error "#1 migrate dir fails"
17224         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
17225         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
17226         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17227         [ $mdt_index == 1 ] || error "a is not on MDT1"
17228
17229         # a should stay on MDT1, because it is a mulitple link file
17230         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
17231                 error "#2 migrate dir fails"
17232         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17233         [ $mdt_index == 1 ] || error "a is not on MDT1"
17234
17235         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
17236                 error "#3 migrate dir fails"
17237
17238         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
17239         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
17240         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
17241
17242         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
17243         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
17244
17245         # a should be migrated to MDT0, since no other links on MDT1
17246         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
17247                 error "#4 migrate dir fails"
17248         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17249         [ $mdt_index == 0 ] || error "a is not on MDT0"
17250
17251         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17252 }
17253 run_test 230f "migrate mulitple remote link files"
17254
17255 test_230g() {
17256         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17257         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17258         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17259                 skip "Need MDS version at least 2.11.52"
17260
17261         mkdir -p $DIR/$tdir/migrate_dir
17262
17263         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
17264                 error "migrating dir to non-exist MDT succeeds"
17265         true
17266 }
17267 run_test 230g "migrate dir to non-exist MDT"
17268
17269 test_230h() {
17270         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17271         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17272         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17273                 skip "Need MDS version at least 2.11.52"
17274
17275         local mdt_index
17276
17277         mkdir -p $DIR/$tdir/migrate_dir
17278
17279         $LFS migrate -m1 $DIR &&
17280                 error "migrating mountpoint1 should fail"
17281
17282         $LFS migrate -m1 $DIR/$tdir/.. &&
17283                 error "migrating mountpoint2 should fail"
17284
17285         # same as mv
17286         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
17287                 error "migrating $tdir/migrate_dir/.. should fail"
17288
17289         true
17290 }
17291 run_test 230h "migrate .. and root"
17292
17293 test_230i() {
17294         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17295         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17296         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17297                 skip "Need MDS version at least 2.11.52"
17298
17299         mkdir -p $DIR/$tdir/migrate_dir
17300
17301         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
17302                 error "migration fails with a tailing slash"
17303
17304         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
17305                 error "migration fails with two tailing slashes"
17306 }
17307 run_test 230i "lfs migrate -m tolerates trailing slashes"
17308
17309 test_230j() {
17310         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
17311         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17312                 skip "Need MDS version at least 2.11.52"
17313
17314         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
17315         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
17316                 error "create $tfile failed"
17317         cat /etc/passwd > $DIR/$tdir/$tfile
17318
17319         $LFS migrate -m 1 $DIR/$tdir
17320
17321         cmp /etc/passwd $DIR/$tdir/$tfile ||
17322                 error "DoM file mismatch after migration"
17323 }
17324 run_test 230j "DoM file data not changed after dir migration"
17325
17326 test_230k() {
17327         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
17328         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
17329                 skip "Need MDS version at least 2.11.56"
17330
17331         local total=20
17332         local files_on_starting_mdt=0
17333
17334         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
17335         $LFS getdirstripe $DIR/$tdir
17336         for i in $(seq $total); do
17337                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
17338                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
17339                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
17340         done
17341
17342         echo "$files_on_starting_mdt files on MDT0"
17343
17344         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
17345         $LFS getdirstripe $DIR/$tdir
17346
17347         files_on_starting_mdt=0
17348         for i in $(seq $total); do
17349                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
17350                         error "file $tfile.$i mismatch after migration"
17351                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
17352                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
17353         done
17354
17355         echo "$files_on_starting_mdt files on MDT1 after migration"
17356         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
17357
17358         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
17359         $LFS getdirstripe $DIR/$tdir
17360
17361         files_on_starting_mdt=0
17362         for i in $(seq $total); do
17363                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
17364                         error "file $tfile.$i mismatch after 2nd migration"
17365                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
17366                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
17367         done
17368
17369         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
17370         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
17371
17372         true
17373 }
17374 run_test 230k "file data not changed after dir migration"
17375
17376 test_230l() {
17377         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
17378         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
17379                 skip "Need MDS version at least 2.11.56"
17380
17381         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
17382         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
17383                 error "create files under remote dir failed $i"
17384         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
17385 }
17386 run_test 230l "readdir between MDTs won't crash"
17387
17388 test_230m() {
17389         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
17390         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
17391                 skip "Need MDS version at least 2.11.56"
17392
17393         local MDTIDX=1
17394         local mig_dir=$DIR/$tdir/migrate_dir
17395         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
17396         local shortstr="b"
17397         local val
17398
17399         echo "Creating files and dirs with xattrs"
17400         test_mkdir $DIR/$tdir
17401         test_mkdir -i0 -c1 $mig_dir
17402         mkdir $mig_dir/dir
17403         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
17404                 error "cannot set xattr attr1 on dir"
17405         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
17406                 error "cannot set xattr attr2 on dir"
17407         touch $mig_dir/dir/f0
17408         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
17409                 error "cannot set xattr attr1 on file"
17410         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
17411                 error "cannot set xattr attr2 on file"
17412         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
17413         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
17414         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
17415         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
17416         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
17417         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
17418         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
17419         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
17420         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
17421
17422         echo "Migrating to MDT1"
17423         $LFS migrate -m $MDTIDX $mig_dir ||
17424                 error "fails on migrating dir to MDT1"
17425
17426         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
17427         echo "Checking xattrs"
17428         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
17429         [ "$val" = $longstr ] ||
17430                 error "expecting xattr1 $longstr on dir, found $val"
17431         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
17432         [ "$val" = $shortstr ] ||
17433                 error "expecting xattr2 $shortstr on dir, found $val"
17434         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
17435         [ "$val" = $longstr ] ||
17436                 error "expecting xattr1 $longstr on file, found $val"
17437         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
17438         [ "$val" = $shortstr ] ||
17439                 error "expecting xattr2 $shortstr on file, found $val"
17440 }
17441 run_test 230m "xattrs not changed after dir migration"
17442
17443 test_230n() {
17444         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
17445         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
17446                 skip "Need MDS version at least 2.13.53"
17447
17448         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
17449         cat /etc/hosts > $DIR/$tdir/$tfile
17450         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
17451         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
17452
17453         cmp /etc/hosts $DIR/$tdir/$tfile ||
17454                 error "File data mismatch after migration"
17455 }
17456 run_test 230n "Dir migration with mirrored file"
17457
17458 test_231a()
17459 {
17460         # For simplicity this test assumes that max_pages_per_rpc
17461         # is the same across all OSCs
17462         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
17463         local bulk_size=$((max_pages * PAGE_SIZE))
17464         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
17465                                        head -n 1)
17466
17467         mkdir -p $DIR/$tdir
17468         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
17469                 error "failed to set stripe with -S ${brw_size}M option"
17470
17471         # clear the OSC stats
17472         $LCTL set_param osc.*.stats=0 &>/dev/null
17473         stop_writeback
17474
17475         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
17476         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
17477                 oflag=direct &>/dev/null || error "dd failed"
17478
17479         sync; sleep 1; sync # just to be safe
17480         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
17481         if [ x$nrpcs != "x1" ]; then
17482                 $LCTL get_param osc.*.stats
17483                 error "found $nrpcs ost_write RPCs, not 1 as expected"
17484         fi
17485
17486         start_writeback
17487         # Drop the OSC cache, otherwise we will read from it
17488         cancel_lru_locks osc
17489
17490         # clear the OSC stats
17491         $LCTL set_param osc.*.stats=0 &>/dev/null
17492
17493         # Client reads $bulk_size.
17494         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
17495                 iflag=direct &>/dev/null || error "dd failed"
17496
17497         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
17498         if [ x$nrpcs != "x1" ]; then
17499                 $LCTL get_param osc.*.stats
17500                 error "found $nrpcs ost_read RPCs, not 1 as expected"
17501         fi
17502 }
17503 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
17504
17505 test_231b() {
17506         mkdir -p $DIR/$tdir
17507         local i
17508         for i in {0..1023}; do
17509                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
17510                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
17511                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
17512         done
17513         sync
17514 }
17515 run_test 231b "must not assert on fully utilized OST request buffer"
17516
17517 test_232a() {
17518         mkdir -p $DIR/$tdir
17519         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
17520
17521         #define OBD_FAIL_LDLM_OST_LVB            0x31c
17522         do_facet ost1 $LCTL set_param fail_loc=0x31c
17523
17524         # ignore dd failure
17525         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
17526
17527         do_facet ost1 $LCTL set_param fail_loc=0
17528         umount_client $MOUNT || error "umount failed"
17529         mount_client $MOUNT || error "mount failed"
17530         stop ost1 || error "cannot stop ost1"
17531         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
17532 }
17533 run_test 232a "failed lock should not block umount"
17534
17535 test_232b() {
17536         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
17537                 skip "Need MDS version at least 2.10.58"
17538
17539         mkdir -p $DIR/$tdir
17540         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
17541         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
17542         sync
17543         cancel_lru_locks osc
17544
17545         #define OBD_FAIL_LDLM_OST_LVB            0x31c
17546         do_facet ost1 $LCTL set_param fail_loc=0x31c
17547
17548         # ignore failure
17549         $LFS data_version $DIR/$tdir/$tfile || true
17550
17551         do_facet ost1 $LCTL set_param fail_loc=0
17552         umount_client $MOUNT || error "umount failed"
17553         mount_client $MOUNT || error "mount failed"
17554         stop ost1 || error "cannot stop ost1"
17555         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
17556 }
17557 run_test 232b "failed data version lock should not block umount"
17558
17559 test_233a() {
17560         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
17561                 skip "Need MDS version at least 2.3.64"
17562         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
17563
17564         local fid=$($LFS path2fid $MOUNT)
17565
17566         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
17567                 error "cannot access $MOUNT using its FID '$fid'"
17568 }
17569 run_test 233a "checking that OBF of the FS root succeeds"
17570
17571 test_233b() {
17572         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
17573                 skip "Need MDS version at least 2.5.90"
17574         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
17575
17576         local fid=$($LFS path2fid $MOUNT/.lustre)
17577
17578         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
17579                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
17580
17581         fid=$($LFS path2fid $MOUNT/.lustre/fid)
17582         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
17583                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
17584 }
17585 run_test 233b "checking that OBF of the FS .lustre succeeds"
17586
17587 test_234() {
17588         local p="$TMP/sanityN-$TESTNAME.parameters"
17589         save_lustre_params client "llite.*.xattr_cache" > $p
17590         lctl set_param llite.*.xattr_cache 1 ||
17591                 skip_env "xattr cache is not supported"
17592
17593         mkdir -p $DIR/$tdir || error "mkdir failed"
17594         touch $DIR/$tdir/$tfile || error "touch failed"
17595         # OBD_FAIL_LLITE_XATTR_ENOMEM
17596         $LCTL set_param fail_loc=0x1405
17597         getfattr -n user.attr $DIR/$tdir/$tfile &&
17598                 error "getfattr should have failed with ENOMEM"
17599         $LCTL set_param fail_loc=0x0
17600         rm -rf $DIR/$tdir
17601
17602         restore_lustre_params < $p
17603         rm -f $p
17604 }
17605 run_test 234 "xattr cache should not crash on ENOMEM"
17606
17607 test_235() {
17608         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
17609                 skip "Need MDS version at least 2.4.52"
17610
17611         flock_deadlock $DIR/$tfile
17612         local RC=$?
17613         case $RC in
17614                 0)
17615                 ;;
17616                 124) error "process hangs on a deadlock"
17617                 ;;
17618                 *) error "error executing flock_deadlock $DIR/$tfile"
17619                 ;;
17620         esac
17621 }
17622 run_test 235 "LU-1715: flock deadlock detection does not work properly"
17623
17624 #LU-2935
17625 test_236() {
17626         check_swap_layouts_support
17627
17628         local ref1=/etc/passwd
17629         local ref2=/etc/group
17630         local file1=$DIR/$tdir/f1
17631         local file2=$DIR/$tdir/f2
17632
17633         test_mkdir -c1 $DIR/$tdir
17634         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
17635         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
17636         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
17637         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
17638         local fd=$(free_fd)
17639         local cmd="exec $fd<>$file2"
17640         eval $cmd
17641         rm $file2
17642         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
17643                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
17644         cmd="exec $fd>&-"
17645         eval $cmd
17646         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
17647
17648         #cleanup
17649         rm -rf $DIR/$tdir
17650 }
17651 run_test 236 "Layout swap on open unlinked file"
17652
17653 # LU-4659 linkea consistency
17654 test_238() {
17655         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
17656                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
17657                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
17658                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
17659
17660         touch $DIR/$tfile
17661         ln $DIR/$tfile $DIR/$tfile.lnk
17662         touch $DIR/$tfile.new
17663         mv $DIR/$tfile.new $DIR/$tfile
17664         local fid1=$($LFS path2fid $DIR/$tfile)
17665         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
17666         local path1=$($LFS fid2path $FSNAME "$fid1")
17667         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
17668         local path2=$($LFS fid2path $FSNAME "$fid2")
17669         [ $tfile.lnk == $path2 ] ||
17670                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
17671         rm -f $DIR/$tfile*
17672 }
17673 run_test 238 "Verify linkea consistency"
17674
17675 test_239A() { # was test_239
17676         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
17677                 skip "Need MDS version at least 2.5.60"
17678
17679         local list=$(comma_list $(mdts_nodes))
17680
17681         mkdir -p $DIR/$tdir
17682         createmany -o $DIR/$tdir/f- 5000
17683         unlinkmany $DIR/$tdir/f- 5000
17684         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
17685                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
17686         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
17687                         osp.*MDT*.sync_in_flight" | calc_sum)
17688         [ "$changes" -eq 0 ] || error "$changes not synced"
17689 }
17690 run_test 239A "osp_sync test"
17691
17692 test_239a() { #LU-5297
17693         remote_mds_nodsh && skip "remote MDS with nodsh"
17694
17695         touch $DIR/$tfile
17696         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
17697         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
17698         chgrp $RUNAS_GID $DIR/$tfile
17699         wait_delete_completed
17700 }
17701 run_test 239a "process invalid osp sync record correctly"
17702
17703 test_239b() { #LU-5297
17704         remote_mds_nodsh && skip "remote MDS with nodsh"
17705
17706         touch $DIR/$tfile1
17707         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
17708         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
17709         chgrp $RUNAS_GID $DIR/$tfile1
17710         wait_delete_completed
17711         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
17712         touch $DIR/$tfile2
17713         chgrp $RUNAS_GID $DIR/$tfile2
17714         wait_delete_completed
17715 }
17716 run_test 239b "process osp sync record with ENOMEM error correctly"
17717
17718 test_240() {
17719         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17720         remote_mds_nodsh && skip "remote MDS with nodsh"
17721
17722         mkdir -p $DIR/$tdir
17723
17724         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
17725                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
17726         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
17727                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
17728
17729         umount_client $MOUNT || error "umount failed"
17730         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
17731         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
17732         mount_client $MOUNT || error "failed to mount client"
17733
17734         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
17735         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
17736 }
17737 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
17738
17739 test_241_bio() {
17740         local count=$1
17741         local bsize=$2
17742
17743         for LOOP in $(seq $count); do
17744                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
17745                 cancel_lru_locks $OSC || true
17746         done
17747 }
17748
17749 test_241_dio() {
17750         local count=$1
17751         local bsize=$2
17752
17753         for LOOP in $(seq $1); do
17754                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
17755                         2>/dev/null
17756         done
17757 }
17758
17759 test_241a() { # was test_241
17760         local bsize=$PAGE_SIZE
17761
17762         (( bsize < 40960 )) && bsize=40960
17763         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
17764         ls -la $DIR/$tfile
17765         cancel_lru_locks $OSC
17766         test_241_bio 1000 $bsize &
17767         PID=$!
17768         test_241_dio 1000 $bsize
17769         wait $PID
17770 }
17771 run_test 241a "bio vs dio"
17772
17773 test_241b() {
17774         local bsize=$PAGE_SIZE
17775
17776         (( bsize < 40960 )) && bsize=40960
17777         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
17778         ls -la $DIR/$tfile
17779         test_241_dio 1000 $bsize &
17780         PID=$!
17781         test_241_dio 1000 $bsize
17782         wait $PID
17783 }
17784 run_test 241b "dio vs dio"
17785
17786 test_242() {
17787         remote_mds_nodsh && skip "remote MDS with nodsh"
17788
17789         mkdir -p $DIR/$tdir
17790         touch $DIR/$tdir/$tfile
17791
17792         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
17793         do_facet mds1 lctl set_param fail_loc=0x105
17794         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
17795
17796         do_facet mds1 lctl set_param fail_loc=0
17797         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
17798 }
17799 run_test 242 "mdt_readpage failure should not cause directory unreadable"
17800
17801 test_243()
17802 {
17803         test_mkdir $DIR/$tdir
17804         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
17805 }
17806 run_test 243 "various group lock tests"
17807
17808 test_244a()
17809 {
17810         test_mkdir $DIR/$tdir
17811         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
17812         sendfile_grouplock $DIR/$tdir/$tfile || \
17813                 error "sendfile+grouplock failed"
17814         rm -rf $DIR/$tdir
17815 }
17816 run_test 244a "sendfile with group lock tests"
17817
17818 test_244b()
17819 {
17820         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
17821
17822         local threads=50
17823         local size=$((1024*1024))
17824
17825         test_mkdir $DIR/$tdir
17826         for i in $(seq 1 $threads); do
17827                 local file=$DIR/$tdir/file_$((i / 10))
17828                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
17829                 local pids[$i]=$!
17830         done
17831         for i in $(seq 1 $threads); do
17832                 wait ${pids[$i]}
17833         done
17834 }
17835 run_test 244b "multi-threaded write with group lock"
17836
17837 test_245() {
17838         local flagname="multi_mod_rpcs"
17839         local connect_data_name="max_mod_rpcs"
17840         local out
17841
17842         # check if multiple modify RPCs flag is set
17843         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
17844                 grep "connect_flags:")
17845         echo "$out"
17846
17847         echo "$out" | grep -qw $flagname
17848         if [ $? -ne 0 ]; then
17849                 echo "connect flag $flagname is not set"
17850                 return
17851         fi
17852
17853         # check if multiple modify RPCs data is set
17854         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
17855         echo "$out"
17856
17857         echo "$out" | grep -qw $connect_data_name ||
17858                 error "import should have connect data $connect_data_name"
17859 }
17860 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
17861
17862 cleanup_247() {
17863         local submount=$1
17864
17865         trap 0
17866         umount_client $submount
17867         rmdir $submount
17868 }
17869
17870 test_247a() {
17871         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
17872                 grep -q subtree ||
17873                 skip_env "Fileset feature is not supported"
17874
17875         local submount=${MOUNT}_$tdir
17876
17877         mkdir $MOUNT/$tdir
17878         mkdir -p $submount || error "mkdir $submount failed"
17879         FILESET="$FILESET/$tdir" mount_client $submount ||
17880                 error "mount $submount failed"
17881         trap "cleanup_247 $submount" EXIT
17882         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
17883         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
17884                 error "read $MOUNT/$tdir/$tfile failed"
17885         cleanup_247 $submount
17886 }
17887 run_test 247a "mount subdir as fileset"
17888
17889 test_247b() {
17890         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
17891                 skip_env "Fileset feature is not supported"
17892
17893         local submount=${MOUNT}_$tdir
17894
17895         rm -rf $MOUNT/$tdir
17896         mkdir -p $submount || error "mkdir $submount failed"
17897         SKIP_FILESET=1
17898         FILESET="$FILESET/$tdir" mount_client $submount &&
17899                 error "mount $submount should fail"
17900         rmdir $submount
17901 }
17902 run_test 247b "mount subdir that dose not exist"
17903
17904 test_247c() {
17905         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
17906                 skip_env "Fileset feature is not supported"
17907
17908         local submount=${MOUNT}_$tdir
17909
17910         mkdir -p $MOUNT/$tdir/dir1
17911         mkdir -p $submount || error "mkdir $submount failed"
17912         trap "cleanup_247 $submount" EXIT
17913         FILESET="$FILESET/$tdir" mount_client $submount ||
17914                 error "mount $submount failed"
17915         local fid=$($LFS path2fid $MOUNT/)
17916         $LFS fid2path $submount $fid && error "fid2path should fail"
17917         cleanup_247 $submount
17918 }
17919 run_test 247c "running fid2path outside root"
17920
17921 test_247d() {
17922         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
17923                 skip "Fileset feature is not supported"
17924
17925         local submount=${MOUNT}_$tdir
17926
17927         mkdir -p $MOUNT/$tdir/dir1
17928         mkdir -p $submount || error "mkdir $submount failed"
17929         FILESET="$FILESET/$tdir" mount_client $submount ||
17930                 error "mount $submount failed"
17931         trap "cleanup_247 $submount" EXIT
17932         local fid=$($LFS path2fid $submount/dir1)
17933         $LFS fid2path $submount $fid || error "fid2path should succeed"
17934         cleanup_247 $submount
17935 }
17936 run_test 247d "running fid2path inside root"
17937
17938 # LU-8037
17939 test_247e() {
17940         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
17941                 grep -q subtree ||
17942                 skip "Fileset feature is not supported"
17943
17944         local submount=${MOUNT}_$tdir
17945
17946         mkdir $MOUNT/$tdir
17947         mkdir -p $submount || error "mkdir $submount failed"
17948         FILESET="$FILESET/.." mount_client $submount &&
17949                 error "mount $submount should fail"
17950         rmdir $submount
17951 }
17952 run_test 247e "mount .. as fileset"
17953
17954 test_248a() {
17955         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
17956         [ -z "$fast_read_sav" ] && skip "no fast read support"
17957
17958         # create a large file for fast read verification
17959         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
17960
17961         # make sure the file is created correctly
17962         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
17963                 { rm -f $DIR/$tfile; skip "file creation error"; }
17964
17965         echo "Test 1: verify that fast read is 4 times faster on cache read"
17966
17967         # small read with fast read enabled
17968         $LCTL set_param -n llite.*.fast_read=1
17969         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
17970                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
17971                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
17972         # small read with fast read disabled
17973         $LCTL set_param -n llite.*.fast_read=0
17974         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
17975                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
17976                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
17977
17978         # verify that fast read is 4 times faster for cache read
17979         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
17980                 error_not_in_vm "fast read was not 4 times faster: " \
17981                            "$t_fast vs $t_slow"
17982
17983         echo "Test 2: verify the performance between big and small read"
17984         $LCTL set_param -n llite.*.fast_read=1
17985
17986         # 1k non-cache read
17987         cancel_lru_locks osc
17988         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
17989                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
17990                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
17991
17992         # 1M non-cache read
17993         cancel_lru_locks osc
17994         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
17995                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
17996                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
17997
17998         # verify that big IO is not 4 times faster than small IO
17999         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
18000                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
18001
18002         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
18003         rm -f $DIR/$tfile
18004 }
18005 run_test 248a "fast read verification"
18006
18007 test_248b() {
18008         # Default short_io_bytes=16384, try both smaller and larger sizes.
18009         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
18010         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
18011         echo "bs=53248 count=113 normal buffered write"
18012         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
18013                 error "dd of initial data file failed"
18014         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
18015
18016         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
18017         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
18018                 error "dd with sync normal writes failed"
18019         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
18020
18021         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
18022         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
18023                 error "dd with sync small writes failed"
18024         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
18025
18026         cancel_lru_locks osc
18027
18028         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
18029         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
18030         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
18031         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
18032                 iflag=direct || error "dd with O_DIRECT small read failed"
18033         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
18034         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
18035                 error "compare $TMP/$tfile.1 failed"
18036
18037         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
18038         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
18039
18040         # just to see what the maximum tunable value is, and test parsing
18041         echo "test invalid parameter 2MB"
18042         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
18043                 error "too-large short_io_bytes allowed"
18044         echo "test maximum parameter 512KB"
18045         # if we can set a larger short_io_bytes, run test regardless of version
18046         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
18047                 # older clients may not allow setting it this large, that's OK
18048                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
18049                         skip "Need at least client version 2.13.50"
18050                 error "medium short_io_bytes failed"
18051         fi
18052         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
18053         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
18054
18055         echo "test large parameter 64KB"
18056         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
18057         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
18058
18059         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
18060         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
18061                 error "dd with sync large writes failed"
18062         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
18063
18064         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
18065         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
18066         num=$((113 * 4096 / PAGE_SIZE))
18067         echo "bs=$size count=$num oflag=direct large write $tfile.3"
18068         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
18069                 error "dd with O_DIRECT large writes failed"
18070         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
18071                 error "compare $DIR/$tfile.3 failed"
18072
18073         cancel_lru_locks osc
18074
18075         echo "bs=$size count=$num iflag=direct large read $tfile.2"
18076         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
18077                 error "dd with O_DIRECT large read failed"
18078         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
18079                 error "compare $TMP/$tfile.2 failed"
18080
18081         echo "bs=$size count=$num iflag=direct large read $tfile.3"
18082         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
18083                 error "dd with O_DIRECT large read failed"
18084         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
18085                 error "compare $TMP/$tfile.3 failed"
18086 }
18087 run_test 248b "test short_io read and write for both small and large sizes"
18088
18089 test_249() { # LU-7890
18090         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
18091                 skip "Need at least version 2.8.54"
18092
18093         rm -f $DIR/$tfile
18094         $LFS setstripe -c 1 $DIR/$tfile
18095         # Offset 2T == 4k * 512M
18096         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
18097                 error "dd to 2T offset failed"
18098 }
18099 run_test 249 "Write above 2T file size"
18100
18101 test_250() {
18102         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
18103          && skip "no 16TB file size limit on ZFS"
18104
18105         $LFS setstripe -c 1 $DIR/$tfile
18106         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
18107         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
18108         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
18109         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
18110                 conv=notrunc,fsync && error "append succeeded"
18111         return 0
18112 }
18113 run_test 250 "Write above 16T limit"
18114
18115 test_251() {
18116         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
18117
18118         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
18119         #Skip once - writing the first stripe will succeed
18120         $LCTL set_param fail_loc=0xa0001407 fail_val=1
18121         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
18122                 error "short write happened"
18123
18124         $LCTL set_param fail_loc=0xa0001407 fail_val=1
18125         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
18126                 error "short read happened"
18127
18128         rm -f $DIR/$tfile
18129 }
18130 run_test 251 "Handling short read and write correctly"
18131
18132 test_252() {
18133         remote_mds_nodsh && skip "remote MDS with nodsh"
18134         remote_ost_nodsh && skip "remote OST with nodsh"
18135         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
18136                 skip_env "ldiskfs only test"
18137         fi
18138
18139         local tgt
18140         local dev
18141         local out
18142         local uuid
18143         local num
18144         local gen
18145
18146         # check lr_reader on OST0000
18147         tgt=ost1
18148         dev=$(facet_device $tgt)
18149         out=$(do_facet $tgt $LR_READER $dev)
18150         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
18151         echo "$out"
18152         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
18153         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
18154                 error "Invalid uuid returned by $LR_READER on target $tgt"
18155         echo -e "uuid returned by $LR_READER is '$uuid'\n"
18156
18157         # check lr_reader -c on MDT0000
18158         tgt=mds1
18159         dev=$(facet_device $tgt)
18160         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
18161                 skip "$LR_READER does not support additional options"
18162         fi
18163         out=$(do_facet $tgt $LR_READER -c $dev)
18164         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
18165         echo "$out"
18166         num=$(echo "$out" | grep -c "mdtlov")
18167         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
18168                 error "Invalid number of mdtlov clients returned by $LR_READER"
18169         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
18170
18171         # check lr_reader -cr on MDT0000
18172         out=$(do_facet $tgt $LR_READER -cr $dev)
18173         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
18174         echo "$out"
18175         echo "$out" | grep -q "^reply_data:$" ||
18176                 error "$LR_READER should have returned 'reply_data' section"
18177         num=$(echo "$out" | grep -c "client_generation")
18178         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
18179 }
18180 run_test 252 "check lr_reader tool"
18181
18182 test_253() {
18183         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18184         remote_mds_nodsh && skip "remote MDS with nodsh"
18185         remote_mgs_nodsh && skip "remote MGS with nodsh"
18186
18187         local ostidx=0
18188         local rc=0
18189         local ost_name=$(ostname_from_index $ostidx)
18190
18191         # on the mdt's osc
18192         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
18193         do_facet $SINGLEMDS $LCTL get_param -n \
18194                 osp.$mdtosc_proc1.reserved_mb_high ||
18195                 skip  "remote MDS does not support reserved_mb_high"
18196
18197         rm -rf $DIR/$tdir
18198         wait_mds_ost_sync
18199         wait_delete_completed
18200         mkdir $DIR/$tdir
18201
18202         pool_add $TESTNAME || error "Pool creation failed"
18203         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
18204
18205         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
18206                 error "Setstripe failed"
18207
18208         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
18209
18210         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
18211                     grep "watermarks")
18212         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
18213
18214         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
18215                         osp.$mdtosc_proc1.prealloc_status)
18216         echo "prealloc_status $oa_status"
18217
18218         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
18219                 error "File creation should fail"
18220
18221         #object allocation was stopped, but we still able to append files
18222         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
18223                 oflag=append || error "Append failed"
18224
18225         rm -f $DIR/$tdir/$tfile.0
18226
18227         # For this test, we want to delete the files we created to go out of
18228         # space but leave the watermark, so we remain nearly out of space
18229         ost_watermarks_enospc_delete_files $tfile $ostidx
18230
18231         wait_delete_completed
18232
18233         sleep_maxage
18234
18235         for i in $(seq 10 12); do
18236                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
18237                         2>/dev/null || error "File creation failed after rm"
18238         done
18239
18240         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
18241                         osp.$mdtosc_proc1.prealloc_status)
18242         echo "prealloc_status $oa_status"
18243
18244         if (( oa_status != 0 )); then
18245                 error "Object allocation still disable after rm"
18246         fi
18247 }
18248 run_test 253 "Check object allocation limit"
18249
18250 test_254() {
18251         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18252         remote_mds_nodsh && skip "remote MDS with nodsh"
18253         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
18254                 skip "MDS does not support changelog_size"
18255
18256         local cl_user
18257         local MDT0=$(facet_svc $SINGLEMDS)
18258
18259         changelog_register || error "changelog_register failed"
18260
18261         changelog_clear 0 || error "changelog_clear failed"
18262
18263         local size1=$(do_facet $SINGLEMDS \
18264                       $LCTL get_param -n mdd.$MDT0.changelog_size)
18265         echo "Changelog size $size1"
18266
18267         rm -rf $DIR/$tdir
18268         $LFS mkdir -i 0 $DIR/$tdir
18269         # change something
18270         mkdir -p $DIR/$tdir/pics/2008/zachy
18271         touch $DIR/$tdir/pics/2008/zachy/timestamp
18272         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
18273         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
18274         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
18275         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
18276         rm $DIR/$tdir/pics/desktop.jpg
18277
18278         local size2=$(do_facet $SINGLEMDS \
18279                       $LCTL get_param -n mdd.$MDT0.changelog_size)
18280         echo "Changelog size after work $size2"
18281
18282         (( $size2 > $size1 )) ||
18283                 error "new Changelog size=$size2 less than old size=$size1"
18284 }
18285 run_test 254 "Check changelog size"
18286
18287 ladvise_no_type()
18288 {
18289         local type=$1
18290         local file=$2
18291
18292         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
18293                 awk -F: '{print $2}' | grep $type > /dev/null
18294         if [ $? -ne 0 ]; then
18295                 return 0
18296         fi
18297         return 1
18298 }
18299
18300 ladvise_no_ioctl()
18301 {
18302         local file=$1
18303
18304         lfs ladvise -a willread $file > /dev/null 2>&1
18305         if [ $? -eq 0 ]; then
18306                 return 1
18307         fi
18308
18309         lfs ladvise -a willread $file 2>&1 |
18310                 grep "Inappropriate ioctl for device" > /dev/null
18311         if [ $? -eq 0 ]; then
18312                 return 0
18313         fi
18314         return 1
18315 }
18316
18317 percent() {
18318         bc <<<"scale=2; ($1 - $2) * 100 / $2"
18319 }
18320
18321 # run a random read IO workload
18322 # usage: random_read_iops <filename> <filesize> <iosize>
18323 random_read_iops() {
18324         local file=$1
18325         local fsize=$2
18326         local iosize=${3:-4096}
18327
18328         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
18329                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
18330 }
18331
18332 drop_file_oss_cache() {
18333         local file="$1"
18334         local nodes="$2"
18335
18336         $LFS ladvise -a dontneed $file 2>/dev/null ||
18337                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
18338 }
18339
18340 ladvise_willread_performance()
18341 {
18342         local repeat=10
18343         local average_origin=0
18344         local average_cache=0
18345         local average_ladvise=0
18346
18347         for ((i = 1; i <= $repeat; i++)); do
18348                 echo "Iter $i/$repeat: reading without willread hint"
18349                 cancel_lru_locks osc
18350                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
18351                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
18352                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
18353                 average_origin=$(bc <<<"$average_origin + $speed_origin")
18354
18355                 cancel_lru_locks osc
18356                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
18357                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
18358                 average_cache=$(bc <<<"$average_cache + $speed_cache")
18359
18360                 cancel_lru_locks osc
18361                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
18362                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
18363                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
18364                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
18365                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
18366         done
18367         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
18368         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
18369         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
18370
18371         speedup_cache=$(percent $average_cache $average_origin)
18372         speedup_ladvise=$(percent $average_ladvise $average_origin)
18373
18374         echo "Average uncached read: $average_origin"
18375         echo "Average speedup with OSS cached read: " \
18376                 "$average_cache = +$speedup_cache%"
18377         echo "Average speedup with ladvise willread: " \
18378                 "$average_ladvise = +$speedup_ladvise%"
18379
18380         local lowest_speedup=20
18381         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
18382                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
18383                         "got $average_cache%. Skipping ladvise willread check."
18384                 return 0
18385         fi
18386
18387         # the test won't work on ZFS until it supports 'ladvise dontneed', but
18388         # it is still good to run until then to exercise 'ladvise willread'
18389         ! $LFS ladvise -a dontneed $DIR/$tfile &&
18390                 [ "$ost1_FSTYPE" = "zfs" ] &&
18391                 echo "osd-zfs does not support dontneed or drop_caches" &&
18392                 return 0
18393
18394         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
18395         [ ${average_ladvise%.*} -gt $lowest_speedup ] ||
18396                 error_not_in_vm "Speedup with willread is less than " \
18397                         "$lowest_speedup%, got $average_ladvise%"
18398 }
18399
18400 test_255a() {
18401         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
18402                 skip "lustre < 2.8.54 does not support ladvise "
18403         remote_ost_nodsh && skip "remote OST with nodsh"
18404
18405         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
18406
18407         ladvise_no_type willread $DIR/$tfile &&
18408                 skip "willread ladvise is not supported"
18409
18410         ladvise_no_ioctl $DIR/$tfile &&
18411                 skip "ladvise ioctl is not supported"
18412
18413         local size_mb=100
18414         local size=$((size_mb * 1048576))
18415         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
18416                 error "dd to $DIR/$tfile failed"
18417
18418         lfs ladvise -a willread $DIR/$tfile ||
18419                 error "Ladvise failed with no range argument"
18420
18421         lfs ladvise -a willread -s 0 $DIR/$tfile ||
18422                 error "Ladvise failed with no -l or -e argument"
18423
18424         lfs ladvise -a willread -e 1 $DIR/$tfile ||
18425                 error "Ladvise failed with only -e argument"
18426
18427         lfs ladvise -a willread -l 1 $DIR/$tfile ||
18428                 error "Ladvise failed with only -l argument"
18429
18430         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
18431                 error "End offset should not be smaller than start offset"
18432
18433         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
18434                 error "End offset should not be equal to start offset"
18435
18436         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
18437                 error "Ladvise failed with overflowing -s argument"
18438
18439         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
18440                 error "Ladvise failed with overflowing -e argument"
18441
18442         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
18443                 error "Ladvise failed with overflowing -l argument"
18444
18445         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
18446                 error "Ladvise succeeded with conflicting -l and -e arguments"
18447
18448         echo "Synchronous ladvise should wait"
18449         local delay=4
18450 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
18451         do_nodes $(comma_list $(osts_nodes)) \
18452                 $LCTL set_param fail_val=$delay fail_loc=0x237
18453
18454         local start_ts=$SECONDS
18455         lfs ladvise -a willread $DIR/$tfile ||
18456                 error "Ladvise failed with no range argument"
18457         local end_ts=$SECONDS
18458         local inteval_ts=$((end_ts - start_ts))
18459
18460         if [ $inteval_ts -lt $(($delay - 1)) ]; then
18461                 error "Synchronous advice didn't wait reply"
18462         fi
18463
18464         echo "Asynchronous ladvise shouldn't wait"
18465         local start_ts=$SECONDS
18466         lfs ladvise -a willread -b $DIR/$tfile ||
18467                 error "Ladvise failed with no range argument"
18468         local end_ts=$SECONDS
18469         local inteval_ts=$((end_ts - start_ts))
18470
18471         if [ $inteval_ts -gt $(($delay / 2)) ]; then
18472                 error "Asynchronous advice blocked"
18473         fi
18474
18475         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
18476         ladvise_willread_performance
18477 }
18478 run_test 255a "check 'lfs ladvise -a willread'"
18479
18480 facet_meminfo() {
18481         local facet=$1
18482         local info=$2
18483
18484         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
18485 }
18486
18487 test_255b() {
18488         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
18489                 skip "lustre < 2.8.54 does not support ladvise "
18490         remote_ost_nodsh && skip "remote OST with nodsh"
18491
18492         lfs setstripe -c 1 -i 0 $DIR/$tfile
18493
18494         ladvise_no_type dontneed $DIR/$tfile &&
18495                 skip "dontneed ladvise is not supported"
18496
18497         ladvise_no_ioctl $DIR/$tfile &&
18498                 skip "ladvise ioctl is not supported"
18499
18500         ! $LFS ladvise -a dontneed $DIR/$tfile &&
18501                 [ "$ost1_FSTYPE" = "zfs" ] &&
18502                 skip "zfs-osd does not support 'ladvise dontneed'"
18503
18504         local size_mb=100
18505         local size=$((size_mb * 1048576))
18506         # In order to prevent disturbance of other processes, only check 3/4
18507         # of the memory usage
18508         local kibibytes=$((size_mb * 1024 * 3 / 4))
18509
18510         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
18511                 error "dd to $DIR/$tfile failed"
18512
18513         #force write to complete before dropping OST cache & checking memory
18514         sync
18515
18516         local total=$(facet_meminfo ost1 MemTotal)
18517         echo "Total memory: $total KiB"
18518
18519         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
18520         local before_read=$(facet_meminfo ost1 Cached)
18521         echo "Cache used before read: $before_read KiB"
18522
18523         lfs ladvise -a willread $DIR/$tfile ||
18524                 error "Ladvise willread failed"
18525         local after_read=$(facet_meminfo ost1 Cached)
18526         echo "Cache used after read: $after_read KiB"
18527
18528         lfs ladvise -a dontneed $DIR/$tfile ||
18529                 error "Ladvise dontneed again failed"
18530         local no_read=$(facet_meminfo ost1 Cached)
18531         echo "Cache used after dontneed ladvise: $no_read KiB"
18532
18533         if [ $total -lt $((before_read + kibibytes)) ]; then
18534                 echo "Memory is too small, abort checking"
18535                 return 0
18536         fi
18537
18538         if [ $((before_read + kibibytes)) -gt $after_read ]; then
18539                 error "Ladvise willread should use more memory" \
18540                         "than $kibibytes KiB"
18541         fi
18542
18543         if [ $((no_read + kibibytes)) -gt $after_read ]; then
18544                 error "Ladvise dontneed should release more memory" \
18545                         "than $kibibytes KiB"
18546         fi
18547 }
18548 run_test 255b "check 'lfs ladvise -a dontneed'"
18549
18550 test_255c() {
18551         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
18552                 skip "lustre < 2.10.50 does not support lockahead"
18553
18554         local count
18555         local new_count
18556         local difference
18557         local i
18558         local rc
18559
18560         test_mkdir -p $DIR/$tdir
18561         $LFS setstripe -i 0 -c 1 $DIR/$tdir
18562
18563         #test 10 returns only success/failure
18564         i=10
18565         lockahead_test -d $DIR/$tdir -t $i -f $tfile
18566         rc=$?
18567         if [ $rc -eq 255 ]; then
18568                 error "Ladvise test${i} failed, ${rc}"
18569         fi
18570
18571         #test 11 counts lock enqueue requests, all others count new locks
18572         i=11
18573         count=$(do_facet ost1 \
18574                 $LCTL get_param -n ost.OSS.ost.stats)
18575         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
18576
18577         lockahead_test -d $DIR/$tdir -t $i -f $tfile
18578         rc=$?
18579         if [ $rc -eq 255 ]; then
18580                 error "Ladvise test${i} failed, ${rc}"
18581         fi
18582
18583         new_count=$(do_facet ost1 \
18584                 $LCTL get_param -n ost.OSS.ost.stats)
18585         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
18586                    awk '{ print $2 }')
18587
18588         difference="$((new_count - count))"
18589         if [ $difference -ne $rc ]; then
18590                 error "Ladvise test${i}, bad enqueue count, returned " \
18591                       "${rc}, actual ${difference}"
18592         fi
18593
18594         for i in $(seq 12 21); do
18595                 # If we do not do this, we run the risk of having too many
18596                 # locks and starting lock cancellation while we are checking
18597                 # lock counts.
18598                 cancel_lru_locks osc
18599
18600                 count=$($LCTL get_param -n \
18601                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
18602
18603                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
18604                 rc=$?
18605                 if [ $rc -eq 255 ]; then
18606                         error "Ladvise test ${i} failed, ${rc}"
18607                 fi
18608
18609                 new_count=$($LCTL get_param -n \
18610                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
18611                 difference="$((new_count - count))"
18612
18613                 # Test 15 output is divided by 100 to map down to valid return
18614                 if [ $i -eq 15 ]; then
18615                         rc="$((rc * 100))"
18616                 fi
18617
18618                 if [ $difference -ne $rc ]; then
18619                         error "Ladvise test ${i}, bad lock count, returned " \
18620                               "${rc}, actual ${difference}"
18621                 fi
18622         done
18623
18624         #test 22 returns only success/failure
18625         i=22
18626         lockahead_test -d $DIR/$tdir -t $i -f $tfile
18627         rc=$?
18628         if [ $rc -eq 255 ]; then
18629                 error "Ladvise test${i} failed, ${rc}"
18630         fi
18631 }
18632 run_test 255c "suite of ladvise lockahead tests"
18633
18634 test_256() {
18635         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18636         remote_mds_nodsh && skip "remote MDS with nodsh"
18637         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
18638         changelog_users $SINGLEMDS | grep "^cl" &&
18639                 skip "active changelog user"
18640
18641         local cl_user
18642         local cat_sl
18643         local mdt_dev
18644
18645         mdt_dev=$(mdsdevname 1)
18646         echo $mdt_dev
18647
18648         changelog_register || error "changelog_register failed"
18649
18650         rm -rf $DIR/$tdir
18651         mkdir -p $DIR/$tdir
18652
18653         changelog_clear 0 || error "changelog_clear failed"
18654
18655         # change something
18656         touch $DIR/$tdir/{1..10}
18657
18658         # stop the MDT
18659         stop $SINGLEMDS || error "Fail to stop MDT"
18660
18661         # remount the MDT
18662
18663         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
18664
18665         #after mount new plainllog is used
18666         touch $DIR/$tdir/{11..19}
18667         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
18668         stack_trap "rm -f $tmpfile"
18669         cat_sl=$(do_facet $SINGLEMDS "sync; \
18670                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
18671                  llog_reader $tmpfile | grep -c type=1064553b")
18672         do_facet $SINGLEMDS llog_reader $tmpfile
18673
18674         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
18675
18676         changelog_clear 0 || error "changelog_clear failed"
18677
18678         cat_sl=$(do_facet $SINGLEMDS "sync; \
18679                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
18680                  llog_reader $tmpfile | grep -c type=1064553b")
18681
18682         if (( cat_sl == 2 )); then
18683                 error "Empty plain llog was not deleted from changelog catalog"
18684         elif (( cat_sl != 1 )); then
18685                 error "Active plain llog shouldn't be deleted from catalog"
18686         fi
18687 }
18688 run_test 256 "Check llog delete for empty and not full state"
18689
18690 test_257() {
18691         remote_mds_nodsh && skip "remote MDS with nodsh"
18692         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
18693                 skip "Need MDS version at least 2.8.55"
18694
18695         test_mkdir $DIR/$tdir
18696
18697         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
18698                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
18699         stat $DIR/$tdir
18700
18701 #define OBD_FAIL_MDS_XATTR_REP                  0x161
18702         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
18703         local facet=mds$((mdtidx + 1))
18704         set_nodes_failloc $(facet_active_host $facet) 0x80000161
18705         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
18706
18707         stop $facet || error "stop MDS failed"
18708         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
18709                 error "start MDS fail"
18710         wait_recovery_complete $facet
18711 }
18712 run_test 257 "xattr locks are not lost"
18713
18714 # Verify we take the i_mutex when security requires it
18715 test_258a() {
18716 #define OBD_FAIL_IMUTEX_SEC 0x141c
18717         $LCTL set_param fail_loc=0x141c
18718         touch $DIR/$tfile
18719         chmod u+s $DIR/$tfile
18720         chmod a+rwx $DIR/$tfile
18721         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
18722         RC=$?
18723         if [ $RC -ne 0 ]; then
18724                 error "error, failed to take i_mutex, rc=$?"
18725         fi
18726         rm -f $DIR/$tfile
18727 }
18728 run_test 258a "verify i_mutex security behavior when suid attributes is set"
18729
18730 # Verify we do NOT take the i_mutex in the normal case
18731 test_258b() {
18732 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
18733         $LCTL set_param fail_loc=0x141d
18734         touch $DIR/$tfile
18735         chmod a+rwx $DIR
18736         chmod a+rw $DIR/$tfile
18737         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
18738         RC=$?
18739         if [ $RC -ne 0 ]; then
18740                 error "error, took i_mutex unnecessarily, rc=$?"
18741         fi
18742         rm -f $DIR/$tfile
18743
18744 }
18745 run_test 258b "verify i_mutex security behavior"
18746
18747 test_259() {
18748         local file=$DIR/$tfile
18749         local before
18750         local after
18751
18752         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
18753
18754         stack_trap "rm -f $file" EXIT
18755
18756         wait_delete_completed
18757         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
18758         echo "before: $before"
18759
18760         $LFS setstripe -i 0 -c 1 $file
18761         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
18762         sync_all_data
18763         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
18764         echo "after write: $after"
18765
18766 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
18767         do_facet ost1 $LCTL set_param fail_loc=0x2301
18768         $TRUNCATE $file 0
18769         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
18770         echo "after truncate: $after"
18771
18772         stop ost1
18773         do_facet ost1 $LCTL set_param fail_loc=0
18774         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18775         sleep 2
18776         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
18777         echo "after restart: $after"
18778         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
18779                 error "missing truncate?"
18780
18781         return 0
18782 }
18783 run_test 259 "crash at delayed truncate"
18784
18785 test_260() {
18786 #define OBD_FAIL_MDC_CLOSE               0x806
18787         $LCTL set_param fail_loc=0x80000806
18788         touch $DIR/$tfile
18789
18790 }
18791 run_test 260 "Check mdc_close fail"
18792
18793 ### Data-on-MDT sanity tests ###
18794 test_270a() {
18795         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18796                 skip "Need MDS version at least 2.10.55 for DoM"
18797
18798         # create DoM file
18799         local dom=$DIR/$tdir/dom_file
18800         local tmp=$DIR/$tdir/tmp_file
18801
18802         mkdir -p $DIR/$tdir
18803
18804         # basic checks for DoM component creation
18805         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
18806                 error "Can set MDT layout to non-first entry"
18807
18808         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
18809                 error "Can define multiple entries as MDT layout"
18810
18811         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
18812
18813         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
18814         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
18815         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
18816
18817         local mdtidx=$($LFS getstripe -m $dom)
18818         local mdtname=MDT$(printf %04x $mdtidx)
18819         local facet=mds$((mdtidx + 1))
18820         local space_check=1
18821
18822         # Skip free space checks with ZFS
18823         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
18824
18825         # write
18826         sync
18827         local size_tmp=$((65536 * 3))
18828         local mdtfree1=$(do_facet $facet \
18829                          lctl get_param -n osd*.*$mdtname.kbytesfree)
18830
18831         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
18832         # check also direct IO along write
18833         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
18834         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
18835         sync
18836         cmp $tmp $dom || error "file data is different"
18837         [ $(stat -c%s $dom) == $size_tmp ] ||
18838                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
18839         if [ $space_check == 1 ]; then
18840                 local mdtfree2=$(do_facet $facet \
18841                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
18842
18843                 # increase in usage from by $size_tmp
18844                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
18845                         error "MDT free space wrong after write: " \
18846                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
18847         fi
18848
18849         # truncate
18850         local size_dom=10000
18851
18852         $TRUNCATE $dom $size_dom
18853         [ $(stat -c%s $dom) == $size_dom ] ||
18854                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
18855         if [ $space_check == 1 ]; then
18856                 mdtfree1=$(do_facet $facet \
18857                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18858                 # decrease in usage from $size_tmp to new $size_dom
18859                 [ $(($mdtfree1 - $mdtfree2)) -ge \
18860                   $(((size_tmp - size_dom) / 1024)) ] ||
18861                         error "MDT free space is wrong after truncate: " \
18862                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
18863         fi
18864
18865         # append
18866         cat $tmp >> $dom
18867         sync
18868         size_dom=$((size_dom + size_tmp))
18869         [ $(stat -c%s $dom) == $size_dom ] ||
18870                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
18871         if [ $space_check == 1 ]; then
18872                 mdtfree2=$(do_facet $facet \
18873                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18874                 # increase in usage by $size_tmp from previous
18875                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
18876                         error "MDT free space is wrong after append: " \
18877                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
18878         fi
18879
18880         # delete
18881         rm $dom
18882         if [ $space_check == 1 ]; then
18883                 mdtfree1=$(do_facet $facet \
18884                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18885                 # decrease in usage by $size_dom from previous
18886                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
18887                         error "MDT free space is wrong after removal: " \
18888                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
18889         fi
18890
18891         # combined striping
18892         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
18893                 error "Can't create DoM + OST striping"
18894
18895         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
18896         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
18897         # check also direct IO along write
18898         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
18899         sync
18900         cmp $tmp $dom || error "file data is different"
18901         [ $(stat -c%s $dom) == $size_tmp ] ||
18902                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
18903         rm $dom $tmp
18904
18905         return 0
18906 }
18907 run_test 270a "DoM: basic functionality tests"
18908
18909 test_270b() {
18910         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18911                 skip "Need MDS version at least 2.10.55"
18912
18913         local dom=$DIR/$tdir/dom_file
18914         local max_size=1048576
18915
18916         mkdir -p $DIR/$tdir
18917         $LFS setstripe -E $max_size -L mdt $dom
18918
18919         # truncate over the limit
18920         $TRUNCATE $dom $(($max_size + 1)) &&
18921                 error "successful truncate over the maximum size"
18922         # write over the limit
18923         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
18924                 error "successful write over the maximum size"
18925         # append over the limit
18926         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
18927         echo "12345" >> $dom && error "successful append over the maximum size"
18928         rm $dom
18929
18930         return 0
18931 }
18932 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
18933
18934 test_270c() {
18935         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18936                 skip "Need MDS version at least 2.10.55"
18937
18938         mkdir -p $DIR/$tdir
18939         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18940
18941         # check files inherit DoM EA
18942         touch $DIR/$tdir/first
18943         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
18944                 error "bad pattern"
18945         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
18946                 error "bad stripe count"
18947         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
18948                 error "bad stripe size"
18949
18950         # check directory inherits DoM EA and uses it as default
18951         mkdir $DIR/$tdir/subdir
18952         touch $DIR/$tdir/subdir/second
18953         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
18954                 error "bad pattern in sub-directory"
18955         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
18956                 error "bad stripe count in sub-directory"
18957         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
18958                 error "bad stripe size in sub-directory"
18959         return 0
18960 }
18961 run_test 270c "DoM: DoM EA inheritance tests"
18962
18963 test_270d() {
18964         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18965                 skip "Need MDS version at least 2.10.55"
18966
18967         mkdir -p $DIR/$tdir
18968         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18969
18970         # inherit default DoM striping
18971         mkdir $DIR/$tdir/subdir
18972         touch $DIR/$tdir/subdir/f1
18973
18974         # change default directory striping
18975         $LFS setstripe -c 1 $DIR/$tdir/subdir
18976         touch $DIR/$tdir/subdir/f2
18977         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
18978                 error "wrong default striping in file 2"
18979         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
18980                 error "bad pattern in file 2"
18981         return 0
18982 }
18983 run_test 270d "DoM: change striping from DoM to RAID0"
18984
18985 test_270e() {
18986         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18987                 skip "Need MDS version at least 2.10.55"
18988
18989         mkdir -p $DIR/$tdir/dom
18990         mkdir -p $DIR/$tdir/norm
18991         DOMFILES=20
18992         NORMFILES=10
18993         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
18994         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
18995
18996         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
18997         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
18998
18999         # find DoM files by layout
19000         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
19001         [ $NUM -eq  $DOMFILES ] ||
19002                 error "lfs find -L: found $NUM, expected $DOMFILES"
19003         echo "Test 1: lfs find 20 DOM files by layout: OK"
19004
19005         # there should be 1 dir with default DOM striping
19006         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
19007         [ $NUM -eq  1 ] ||
19008                 error "lfs find -L: found $NUM, expected 1 dir"
19009         echo "Test 2: lfs find 1 DOM dir by layout: OK"
19010
19011         # find DoM files by stripe size
19012         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
19013         [ $NUM -eq  $DOMFILES ] ||
19014                 error "lfs find -S: found $NUM, expected $DOMFILES"
19015         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
19016
19017         # find files by stripe offset except DoM files
19018         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
19019         [ $NUM -eq  $NORMFILES ] ||
19020                 error "lfs find -i: found $NUM, expected $NORMFILES"
19021         echo "Test 5: lfs find no DOM files by stripe index: OK"
19022         return 0
19023 }
19024 run_test 270e "DoM: lfs find with DoM files test"
19025
19026 test_270f() {
19027         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19028                 skip "Need MDS version at least 2.10.55"
19029
19030         local mdtname=${FSNAME}-MDT0000-mdtlov
19031         local dom=$DIR/$tdir/dom_file
19032         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
19033                                                 lod.$mdtname.dom_stripesize)
19034         local dom_limit=131072
19035
19036         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
19037         local dom_current=$(do_facet mds1 $LCTL get_param -n \
19038                                                 lod.$mdtname.dom_stripesize)
19039         [ ${dom_limit} -eq ${dom_current} ] ||
19040                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
19041
19042         $LFS mkdir -i 0 -c 1 $DIR/$tdir
19043         $LFS setstripe -d $DIR/$tdir
19044         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
19045                 error "Can't set directory default striping"
19046
19047         # exceed maximum stripe size
19048         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
19049                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
19050         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
19051                 error "Able to create DoM component size more than LOD limit"
19052
19053         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
19054         dom_current=$(do_facet mds1 $LCTL get_param -n \
19055                                                 lod.$mdtname.dom_stripesize)
19056         [ 0 -eq ${dom_current} ] ||
19057                 error "Can't set zero DoM stripe limit"
19058         rm $dom
19059
19060         # attempt to create DoM file on server with disabled DoM should
19061         # remove DoM entry from layout and be succeed
19062         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
19063                 error "Can't create DoM file (DoM is disabled)"
19064         [ $($LFS getstripe -L $dom) == "mdt" ] &&
19065                 error "File has DoM component while DoM is disabled"
19066         rm $dom
19067
19068         # attempt to create DoM file with only DoM stripe should return error
19069         $LFS setstripe -E $dom_limit -L mdt $dom &&
19070                 error "Able to create DoM-only file while DoM is disabled"
19071
19072         # too low values to be aligned with smallest stripe size 64K
19073         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
19074         dom_current=$(do_facet mds1 $LCTL get_param -n \
19075                                                 lod.$mdtname.dom_stripesize)
19076         [ 30000 -eq ${dom_current} ] &&
19077                 error "Can set too small DoM stripe limit"
19078
19079         # 64K is a minimal stripe size in Lustre, expect limit of that size
19080         [ 65536 -eq ${dom_current} ] ||
19081                 error "Limit is not set to 64K but ${dom_current}"
19082
19083         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
19084         dom_current=$(do_facet mds1 $LCTL get_param -n \
19085                                                 lod.$mdtname.dom_stripesize)
19086         echo $dom_current
19087         [ 2147483648 -eq ${dom_current} ] &&
19088                 error "Can set too large DoM stripe limit"
19089
19090         do_facet mds1 $LCTL set_param -n \
19091                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
19092         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
19093                 error "Can't create DoM component size after limit change"
19094         do_facet mds1 $LCTL set_param -n \
19095                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
19096         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
19097                 error "Can't create DoM file after limit decrease"
19098         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
19099                 error "Can create big DoM component after limit decrease"
19100         touch ${dom}_def ||
19101                 error "Can't create file with old default layout"
19102
19103         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
19104         return 0
19105 }
19106 run_test 270f "DoM: maximum DoM stripe size checks"
19107
19108 test_270g() {
19109         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
19110                 skip "Need MDS version at least 2.13.52"
19111         local dom=$DIR/$tdir/$tfile
19112
19113         $LFS mkdir -i 0 -c 1 $DIR/$tdir
19114         local lodname=${FSNAME}-MDT0000-mdtlov
19115
19116         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
19117         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
19118         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
19119         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
19120
19121         local dom_limit=1024
19122         local dom_threshold="50%"
19123
19124         $LFS setstripe -d $DIR/$tdir
19125         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
19126                 error "Can't set directory default striping"
19127
19128         do_facet mds1 $LCTL set_param -n \
19129                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
19130         # set 0 threshold and create DOM file to change tunable stripesize
19131         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
19132         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
19133                 error "Failed to create $dom file"
19134         # now tunable dom_cur_stripesize should reach maximum
19135         local dom_current=$(do_facet mds1 $LCTL get_param -n \
19136                                         lod.${lodname}.dom_stripesize_cur_kb)
19137         [[ $dom_current == $dom_limit ]] ||
19138                 error "Current DOM stripesize is not maximum"
19139         rm $dom
19140
19141         # set threshold for further tests
19142         do_facet mds1 $LCTL set_param -n \
19143                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
19144         echo "DOM threshold is $dom_threshold free space"
19145         local dom_def
19146         local dom_set
19147         # Spoof bfree to exceed threshold
19148         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
19149         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
19150         for spfree in 40 20 0 15 30 55; do
19151                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
19152                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
19153                         error "Failed to create $dom file"
19154                 dom_def=$(do_facet mds1 $LCTL get_param -n \
19155                                         lod.${lodname}.dom_stripesize_cur_kb)
19156                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
19157                 [[ $dom_def != $dom_current ]] ||
19158                         error "Default stripe size was not changed"
19159                 if [[ $spfree > 0 ]] ; then
19160                         dom_set=$($LFS getstripe -S $dom)
19161                         [[ $dom_set == $((dom_def * 1024)) ]] ||
19162                                 error "DOM component size is still old"
19163                 else
19164                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
19165                                 error "DoM component is set with no free space"
19166                 fi
19167                 rm $dom
19168                 dom_current=$dom_def
19169         done
19170 }
19171 run_test 270g "DoM: default DoM stripe size depends on free space"
19172
19173 test_271a() {
19174         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19175                 skip "Need MDS version at least 2.10.55"
19176
19177         local dom=$DIR/$tdir/dom
19178
19179         mkdir -p $DIR/$tdir
19180
19181         $LFS setstripe -E 1024K -L mdt $dom
19182
19183         lctl set_param -n mdc.*.stats=clear
19184         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
19185         cat $dom > /dev/null
19186         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
19187         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
19188         ls $dom
19189         rm -f $dom
19190 }
19191 run_test 271a "DoM: data is cached for read after write"
19192
19193 test_271b() {
19194         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19195                 skip "Need MDS version at least 2.10.55"
19196
19197         local dom=$DIR/$tdir/dom
19198
19199         mkdir -p $DIR/$tdir
19200
19201         $LFS setstripe -E 1024K -L mdt -E EOF $dom
19202
19203         lctl set_param -n mdc.*.stats=clear
19204         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
19205         cancel_lru_locks mdc
19206         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
19207         # second stat to check size is cached on client
19208         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
19209         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
19210         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
19211         rm -f $dom
19212 }
19213 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
19214
19215 test_271ba() {
19216         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19217                 skip "Need MDS version at least 2.10.55"
19218
19219         local dom=$DIR/$tdir/dom
19220
19221         mkdir -p $DIR/$tdir
19222
19223         $LFS setstripe -E 1024K -L mdt -E EOF $dom
19224
19225         lctl set_param -n mdc.*.stats=clear
19226         lctl set_param -n osc.*.stats=clear
19227         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
19228         cancel_lru_locks mdc
19229         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
19230         # second stat to check size is cached on client
19231         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
19232         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
19233         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
19234         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
19235         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
19236         rm -f $dom
19237 }
19238 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
19239
19240
19241 get_mdc_stats() {
19242         local mdtidx=$1
19243         local param=$2
19244         local mdt=MDT$(printf %04x $mdtidx)
19245
19246         if [ -z $param ]; then
19247                 lctl get_param -n mdc.*$mdt*.stats
19248         else
19249                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
19250         fi
19251 }
19252
19253 test_271c() {
19254         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19255                 skip "Need MDS version at least 2.10.55"
19256
19257         local dom=$DIR/$tdir/dom
19258
19259         mkdir -p $DIR/$tdir
19260
19261         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
19262
19263         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
19264         local facet=mds$((mdtidx + 1))
19265
19266         cancel_lru_locks mdc
19267         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
19268         createmany -o $dom 1000
19269         lctl set_param -n mdc.*.stats=clear
19270         smalliomany -w $dom 1000 200
19271         get_mdc_stats $mdtidx
19272         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
19273         # Each file has 1 open, 1 IO enqueues, total 2000
19274         # but now we have also +1 getxattr for security.capability, total 3000
19275         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
19276         unlinkmany $dom 1000
19277
19278         cancel_lru_locks mdc
19279         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
19280         createmany -o $dom 1000
19281         lctl set_param -n mdc.*.stats=clear
19282         smalliomany -w $dom 1000 200
19283         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
19284         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
19285         # for OPEN and IO lock.
19286         [ $((enq - enq_2)) -ge 1000 ] ||
19287                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
19288         unlinkmany $dom 1000
19289         return 0
19290 }
19291 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
19292
19293 cleanup_271def_tests() {
19294         trap 0
19295         rm -f $1
19296 }
19297
19298 test_271d() {
19299         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
19300                 skip "Need MDS version at least 2.10.57"
19301
19302         local dom=$DIR/$tdir/dom
19303         local tmp=$TMP/$tfile
19304         trap "cleanup_271def_tests $tmp" EXIT
19305
19306         mkdir -p $DIR/$tdir
19307
19308         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
19309
19310         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
19311
19312         cancel_lru_locks mdc
19313         dd if=/dev/urandom of=$tmp bs=1000 count=1
19314         dd if=$tmp of=$dom bs=1000 count=1
19315         cancel_lru_locks mdc
19316
19317         cat /etc/hosts >> $tmp
19318         lctl set_param -n mdc.*.stats=clear
19319
19320         # append data to the same file it should update local page
19321         echo "Append to the same page"
19322         cat /etc/hosts >> $dom
19323         local num=$(get_mdc_stats $mdtidx ost_read)
19324         local ra=$(get_mdc_stats $mdtidx req_active)
19325         local rw=$(get_mdc_stats $mdtidx req_waittime)
19326
19327         [ -z $num ] || error "$num READ RPC occured"
19328         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
19329         echo "... DONE"
19330
19331         # compare content
19332         cmp $tmp $dom || error "file miscompare"
19333
19334         cancel_lru_locks mdc
19335         lctl set_param -n mdc.*.stats=clear
19336
19337         echo "Open and read file"
19338         cat $dom > /dev/null
19339         local num=$(get_mdc_stats $mdtidx ost_read)
19340         local ra=$(get_mdc_stats $mdtidx req_active)
19341         local rw=$(get_mdc_stats $mdtidx req_waittime)
19342
19343         [ -z $num ] || error "$num READ RPC occured"
19344         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
19345         echo "... DONE"
19346
19347         # compare content
19348         cmp $tmp $dom || error "file miscompare"
19349
19350         return 0
19351 }
19352 run_test 271d "DoM: read on open (1K file in reply buffer)"
19353
19354 test_271f() {
19355         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
19356                 skip "Need MDS version at least 2.10.57"
19357
19358         local dom=$DIR/$tdir/dom
19359         local tmp=$TMP/$tfile
19360         trap "cleanup_271def_tests $tmp" EXIT
19361
19362         mkdir -p $DIR/$tdir
19363
19364         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
19365
19366         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
19367
19368         cancel_lru_locks mdc
19369         dd if=/dev/urandom of=$tmp bs=265000 count=1
19370         dd if=$tmp of=$dom bs=265000 count=1
19371         cancel_lru_locks mdc
19372         cat /etc/hosts >> $tmp
19373         lctl set_param -n mdc.*.stats=clear
19374
19375         echo "Append to the same page"
19376         cat /etc/hosts >> $dom
19377         local num=$(get_mdc_stats $mdtidx ost_read)
19378         local ra=$(get_mdc_stats $mdtidx req_active)
19379         local rw=$(get_mdc_stats $mdtidx req_waittime)
19380
19381         [ -z $num ] || error "$num READ RPC occured"
19382         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
19383         echo "... DONE"
19384
19385         # compare content
19386         cmp $tmp $dom || error "file miscompare"
19387
19388         cancel_lru_locks mdc
19389         lctl set_param -n mdc.*.stats=clear
19390
19391         echo "Open and read file"
19392         cat $dom > /dev/null
19393         local num=$(get_mdc_stats $mdtidx ost_read)
19394         local ra=$(get_mdc_stats $mdtidx req_active)
19395         local rw=$(get_mdc_stats $mdtidx req_waittime)
19396
19397         [ -z $num ] && num=0
19398         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
19399         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
19400         echo "... DONE"
19401
19402         # compare content
19403         cmp $tmp $dom || error "file miscompare"
19404
19405         return 0
19406 }
19407 run_test 271f "DoM: read on open (200K file and read tail)"
19408
19409 test_271g() {
19410         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
19411                 skip "Skipping due to old client or server version"
19412
19413         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
19414         # to get layout
19415         $CHECKSTAT -t file $DIR1/$tfile
19416
19417         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
19418         MULTIOP_PID=$!
19419         sleep 1
19420         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
19421         $LCTL set_param fail_loc=0x80000314
19422         rm $DIR1/$tfile || error "Unlink fails"
19423         RC=$?
19424         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
19425         [ $RC -eq 0 ] || error "Failed write to stale object"
19426 }
19427 run_test 271g "Discard DoM data vs client flush race"
19428
19429 test_272a() {
19430         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
19431                 skip "Need MDS version at least 2.11.50"
19432
19433         local dom=$DIR/$tdir/dom
19434         mkdir -p $DIR/$tdir
19435
19436         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
19437         dd if=/dev/urandom of=$dom bs=512K count=1 ||
19438                 error "failed to write data into $dom"
19439         local old_md5=$(md5sum $dom)
19440
19441         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
19442                 error "failed to migrate to the same DoM component"
19443
19444         local new_md5=$(md5sum $dom)
19445
19446         [ "$old_md5" == "$new_md5" ] ||
19447                 error "md5sum differ: $old_md5, $new_md5"
19448
19449         [ $($LFS getstripe -c $dom) -eq 2 ] ||
19450                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
19451 }
19452 run_test 272a "DoM migration: new layout with the same DOM component"
19453
19454 test_272b() {
19455         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
19456                 skip "Need MDS version at least 2.11.50"
19457
19458         local dom=$DIR/$tdir/dom
19459         mkdir -p $DIR/$tdir
19460         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
19461
19462         local mdtidx=$($LFS getstripe -m $dom)
19463         local mdtname=MDT$(printf %04x $mdtidx)
19464         local facet=mds$((mdtidx + 1))
19465
19466         local mdtfree1=$(do_facet $facet \
19467                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19468         dd if=/dev/urandom of=$dom bs=2M count=1 ||
19469                 error "failed to write data into $dom"
19470         local old_md5=$(md5sum $dom)
19471         cancel_lru_locks mdc
19472         local mdtfree1=$(do_facet $facet \
19473                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19474
19475         $LFS migrate -c2 $dom ||
19476                 error "failed to migrate to the new composite layout"
19477         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
19478                 error "MDT stripe was not removed"
19479
19480         cancel_lru_locks mdc
19481         local new_md5=$(md5sum $dom)
19482         [ "$old_md5" == "$new_md5" ] ||
19483                 error "$old_md5 != $new_md5"
19484
19485         # Skip free space checks with ZFS
19486         if [ "$(facet_fstype $facet)" != "zfs" ]; then
19487                 local mdtfree2=$(do_facet $facet \
19488                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19489                 [ $mdtfree2 -gt $mdtfree1 ] ||
19490                         error "MDT space is not freed after migration"
19491         fi
19492         return 0
19493 }
19494 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
19495
19496 test_272c() {
19497         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
19498                 skip "Need MDS version at least 2.11.50"
19499
19500         local dom=$DIR/$tdir/$tfile
19501         mkdir -p $DIR/$tdir
19502         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
19503
19504         local mdtidx=$($LFS getstripe -m $dom)
19505         local mdtname=MDT$(printf %04x $mdtidx)
19506         local facet=mds$((mdtidx + 1))
19507
19508         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
19509                 error "failed to write data into $dom"
19510         local old_md5=$(md5sum $dom)
19511         cancel_lru_locks mdc
19512         local mdtfree1=$(do_facet $facet \
19513                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19514
19515         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
19516                 error "failed to migrate to the new composite layout"
19517         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
19518                 error "MDT stripe was not removed"
19519
19520         cancel_lru_locks mdc
19521         local new_md5=$(md5sum $dom)
19522         [ "$old_md5" == "$new_md5" ] ||
19523                 error "$old_md5 != $new_md5"
19524
19525         # Skip free space checks with ZFS
19526         if [ "$(facet_fstype $facet)" != "zfs" ]; then
19527                 local mdtfree2=$(do_facet $facet \
19528                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19529                 [ $mdtfree2 -gt $mdtfree1 ] ||
19530                         error "MDS space is not freed after migration"
19531         fi
19532         return 0
19533 }
19534 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
19535
19536 test_272d() {
19537         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
19538                 skip "Need MDS version at least 2.12.55"
19539
19540         local dom=$DIR/$tdir/$tfile
19541         mkdir -p $DIR/$tdir
19542         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
19543
19544         local mdtidx=$($LFS getstripe -m $dom)
19545         local mdtname=MDT$(printf %04x $mdtidx)
19546         local facet=mds$((mdtidx + 1))
19547
19548         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
19549                 error "failed to write data into $dom"
19550         local old_md5=$(md5sum $dom)
19551         cancel_lru_locks mdc
19552         local mdtfree1=$(do_facet $facet \
19553                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19554
19555         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
19556                 error "failed mirroring to the new composite layout"
19557         $LFS mirror resync $dom ||
19558                 error "failed mirror resync"
19559         $LFS mirror split --mirror-id 1 -d $dom ||
19560                 error "failed mirror split"
19561
19562         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
19563                 error "MDT stripe was not removed"
19564
19565         cancel_lru_locks mdc
19566         local new_md5=$(md5sum $dom)
19567         [ "$old_md5" == "$new_md5" ] ||
19568                 error "$old_md5 != $new_md5"
19569
19570         # Skip free space checks with ZFS
19571         if [ "$(facet_fstype $facet)" != "zfs" ]; then
19572                 local mdtfree2=$(do_facet $facet \
19573                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19574                 [ $mdtfree2 -gt $mdtfree1 ] ||
19575                         error "MDS space is not freed after DOM mirror deletion"
19576         fi
19577         return 0
19578 }
19579 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
19580
19581 test_272e() {
19582         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
19583                 skip "Need MDS version at least 2.12.55"
19584
19585         local dom=$DIR/$tdir/$tfile
19586         mkdir -p $DIR/$tdir
19587         $LFS setstripe -c 2 $dom
19588
19589         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
19590                 error "failed to write data into $dom"
19591         local old_md5=$(md5sum $dom)
19592         cancel_lru_locks mdc
19593
19594         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
19595                 error "failed mirroring to the DOM layout"
19596         $LFS mirror resync $dom ||
19597                 error "failed mirror resync"
19598         $LFS mirror split --mirror-id 1 -d $dom ||
19599                 error "failed mirror split"
19600
19601         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
19602                 error "MDT stripe was not removed"
19603
19604         cancel_lru_locks mdc
19605         local new_md5=$(md5sum $dom)
19606         [ "$old_md5" == "$new_md5" ] ||
19607                 error "$old_md5 != $new_md5"
19608
19609         return 0
19610 }
19611 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
19612
19613 test_272f() {
19614         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
19615                 skip "Need MDS version at least 2.12.55"
19616
19617         local dom=$DIR/$tdir/$tfile
19618         mkdir -p $DIR/$tdir
19619         $LFS setstripe -c 2 $dom
19620
19621         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
19622                 error "failed to write data into $dom"
19623         local old_md5=$(md5sum $dom)
19624         cancel_lru_locks mdc
19625
19626         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
19627                 error "failed migrating to the DOM file"
19628
19629         cancel_lru_locks mdc
19630         local new_md5=$(md5sum $dom)
19631         [ "$old_md5" != "$new_md5" ] &&
19632                 error "$old_md5 != $new_md5"
19633
19634         return 0
19635 }
19636 run_test 272f "DoM migration: OST-striped file to DOM file"
19637
19638 test_273a() {
19639         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
19640                 skip "Need MDS version at least 2.11.50"
19641
19642         # Layout swap cannot be done if either file has DOM component,
19643         # this will never be supported, migration should be used instead
19644
19645         local dom=$DIR/$tdir/$tfile
19646         mkdir -p $DIR/$tdir
19647
19648         $LFS setstripe -c2 ${dom}_plain
19649         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
19650         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
19651                 error "can swap layout with DoM component"
19652         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
19653                 error "can swap layout with DoM component"
19654
19655         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
19656         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
19657                 error "can swap layout with DoM component"
19658         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
19659                 error "can swap layout with DoM component"
19660         return 0
19661 }
19662 run_test 273a "DoM: layout swapping should fail with DOM"
19663
19664 test_275() {
19665         remote_ost_nodsh && skip "remote OST with nodsh"
19666         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
19667                 skip "Need OST version >= 2.10.57"
19668
19669         local file=$DIR/$tfile
19670         local oss
19671
19672         oss=$(comma_list $(osts_nodes))
19673
19674         dd if=/dev/urandom of=$file bs=1M count=2 ||
19675                 error "failed to create a file"
19676         cancel_lru_locks osc
19677
19678         #lock 1
19679         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
19680                 error "failed to read a file"
19681
19682 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
19683         $LCTL set_param fail_loc=0x8000031f
19684
19685         cancel_lru_locks osc &
19686         sleep 1
19687
19688 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
19689         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
19690         #IO takes another lock, but matches the PENDING one
19691         #and places it to the IO RPC
19692         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
19693                 error "failed to read a file with PENDING lock"
19694 }
19695 run_test 275 "Read on a canceled duplicate lock"
19696
19697 test_276() {
19698         remote_ost_nodsh && skip "remote OST with nodsh"
19699         local pid
19700
19701         do_facet ost1 "(while true; do \
19702                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
19703                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
19704         pid=$!
19705
19706         for LOOP in $(seq 20); do
19707                 stop ost1
19708                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
19709         done
19710         kill -9 $pid
19711         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
19712                 rm $TMP/sanity_276_pid"
19713 }
19714 run_test 276 "Race between mount and obd_statfs"
19715
19716 test_277() {
19717         $LCTL set_param ldlm.namespaces.*.lru_size=0
19718         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
19719         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
19720                         grep ^used_mb | awk '{print $2}')
19721         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
19722         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
19723                 oflag=direct conv=notrunc
19724         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
19725                         grep ^used_mb | awk '{print $2}')
19726         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
19727 }
19728 run_test 277 "Direct IO shall drop page cache"
19729
19730 test_278() {
19731         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
19732         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
19733         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
19734                 skip "needs the same host for mdt1 mdt2" && return
19735
19736         local pid1
19737         local pid2
19738
19739 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
19740         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
19741         stop mds2 &
19742         pid2=$!
19743
19744         stop mds1
19745
19746         echo "Starting MDTs"
19747         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
19748         wait $pid2
19749 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
19750 #will return NULL
19751         do_facet mds2 $LCTL set_param fail_loc=0
19752
19753         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
19754         wait_recovery_complete mds2
19755 }
19756 run_test 278 "Race starting MDS between MDTs stop/start"
19757
19758 test_280() {
19759         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
19760                 skip "Need MGS version at least 2.13.52"
19761         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19762         combined_mgs_mds || skip "needs combined MGS/MDT"
19763
19764         umount_client $MOUNT
19765 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
19766         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
19767
19768         mount_client $MOUNT &
19769         sleep 1
19770         stop mgs || error "stop mgs failed"
19771         #for a race mgs would crash
19772         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
19773         mount_client $MOUNT || error "mount client failed"
19774 }
19775 run_test 280 "Race between MGS umount and client llog processing"
19776
19777 cleanup_test_300() {
19778         trap 0
19779         umask $SAVE_UMASK
19780 }
19781 test_striped_dir() {
19782         local mdt_index=$1
19783         local stripe_count
19784         local stripe_index
19785
19786         mkdir -p $DIR/$tdir
19787
19788         SAVE_UMASK=$(umask)
19789         trap cleanup_test_300 RETURN EXIT
19790
19791         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
19792                                                 $DIR/$tdir/striped_dir ||
19793                 error "set striped dir error"
19794
19795         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
19796         [ "$mode" = "755" ] || error "expect 755 got $mode"
19797
19798         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
19799                 error "getdirstripe failed"
19800         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
19801         if [ "$stripe_count" != "2" ]; then
19802                 error "1:stripe_count is $stripe_count, expect 2"
19803         fi
19804         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
19805         if [ "$stripe_count" != "2" ]; then
19806                 error "2:stripe_count is $stripe_count, expect 2"
19807         fi
19808
19809         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
19810         if [ "$stripe_index" != "$mdt_index" ]; then
19811                 error "stripe_index is $stripe_index, expect $mdt_index"
19812         fi
19813
19814         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
19815                 error "nlink error after create striped dir"
19816
19817         mkdir $DIR/$tdir/striped_dir/a
19818         mkdir $DIR/$tdir/striped_dir/b
19819
19820         stat $DIR/$tdir/striped_dir/a ||
19821                 error "create dir under striped dir failed"
19822         stat $DIR/$tdir/striped_dir/b ||
19823                 error "create dir under striped dir failed"
19824
19825         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
19826                 error "nlink error after mkdir"
19827
19828         rmdir $DIR/$tdir/striped_dir/a
19829         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
19830                 error "nlink error after rmdir"
19831
19832         rmdir $DIR/$tdir/striped_dir/b
19833         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
19834                 error "nlink error after rmdir"
19835
19836         chattr +i $DIR/$tdir/striped_dir
19837         createmany -o $DIR/$tdir/striped_dir/f 10 &&
19838                 error "immutable flags not working under striped dir!"
19839         chattr -i $DIR/$tdir/striped_dir
19840
19841         rmdir $DIR/$tdir/striped_dir ||
19842                 error "rmdir striped dir error"
19843
19844         cleanup_test_300
19845
19846         true
19847 }
19848
19849 test_300a() {
19850         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
19851                 skip "skipped for lustre < 2.7.0"
19852         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19853         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19854
19855         test_striped_dir 0 || error "failed on striped dir on MDT0"
19856         test_striped_dir 1 || error "failed on striped dir on MDT0"
19857 }
19858 run_test 300a "basic striped dir sanity test"
19859
19860 test_300b() {
19861         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
19862                 skip "skipped for lustre < 2.7.0"
19863         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19864         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19865
19866         local i
19867         local mtime1
19868         local mtime2
19869         local mtime3
19870
19871         test_mkdir $DIR/$tdir || error "mkdir fail"
19872         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
19873                 error "set striped dir error"
19874         for i in {0..9}; do
19875                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
19876                 sleep 1
19877                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
19878                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
19879                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
19880                 sleep 1
19881                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
19882                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
19883                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
19884         done
19885         true
19886 }
19887 run_test 300b "check ctime/mtime for striped dir"
19888
19889 test_300c() {
19890         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
19891                 skip "skipped for lustre < 2.7.0"
19892         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19893         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19894
19895         local file_count
19896
19897         mkdir -p $DIR/$tdir
19898         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
19899                 error "set striped dir error"
19900
19901         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
19902                 error "chown striped dir failed"
19903
19904         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
19905                 error "create 5k files failed"
19906
19907         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
19908
19909         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
19910
19911         rm -rf $DIR/$tdir
19912 }
19913 run_test 300c "chown && check ls under striped directory"
19914
19915 test_300d() {
19916         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
19917                 skip "skipped for lustre < 2.7.0"
19918         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19919         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19920
19921         local stripe_count
19922         local file
19923
19924         mkdir -p $DIR/$tdir
19925         $LFS setstripe -c 2 $DIR/$tdir
19926
19927         #local striped directory
19928         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
19929                 error "set striped dir error"
19930         #look at the directories for debug purposes
19931         ls -l $DIR/$tdir
19932         $LFS getdirstripe $DIR/$tdir
19933         ls -l $DIR/$tdir/striped_dir
19934         $LFS getdirstripe $DIR/$tdir/striped_dir
19935         createmany -o $DIR/$tdir/striped_dir/f 10 ||
19936                 error "create 10 files failed"
19937
19938         #remote striped directory
19939         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
19940                 error "set striped dir error"
19941         #look at the directories for debug purposes
19942         ls -l $DIR/$tdir
19943         $LFS getdirstripe $DIR/$tdir
19944         ls -l $DIR/$tdir/remote_striped_dir
19945         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
19946         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
19947                 error "create 10 files failed"
19948
19949         for file in $(find $DIR/$tdir); do
19950                 stripe_count=$($LFS getstripe -c $file)
19951                 [ $stripe_count -eq 2 ] ||
19952                         error "wrong stripe $stripe_count for $file"
19953         done
19954
19955         rm -rf $DIR/$tdir
19956 }
19957 run_test 300d "check default stripe under striped directory"
19958
19959 test_300e() {
19960         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19961                 skip "Need MDS version at least 2.7.55"
19962         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19963         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19964
19965         local stripe_count
19966         local file
19967
19968         mkdir -p $DIR/$tdir
19969
19970         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
19971                 error "set striped dir error"
19972
19973         touch $DIR/$tdir/striped_dir/a
19974         touch $DIR/$tdir/striped_dir/b
19975         touch $DIR/$tdir/striped_dir/c
19976
19977         mkdir $DIR/$tdir/striped_dir/dir_a
19978         mkdir $DIR/$tdir/striped_dir/dir_b
19979         mkdir $DIR/$tdir/striped_dir/dir_c
19980
19981         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
19982                 error "set striped adir under striped dir error"
19983
19984         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
19985                 error "set striped bdir under striped dir error"
19986
19987         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
19988                 error "set striped cdir under striped dir error"
19989
19990         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
19991                 error "rename dir under striped dir fails"
19992
19993         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
19994                 error "rename dir under different stripes fails"
19995
19996         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
19997                 error "rename file under striped dir should succeed"
19998
19999         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
20000                 error "rename dir under striped dir should succeed"
20001
20002         rm -rf $DIR/$tdir
20003 }
20004 run_test 300e "check rename under striped directory"
20005
20006 test_300f() {
20007         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20008         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20009         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20010                 skip "Need MDS version at least 2.7.55"
20011
20012         local stripe_count
20013         local file
20014
20015         rm -rf $DIR/$tdir
20016         mkdir -p $DIR/$tdir
20017
20018         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
20019                 error "set striped dir error"
20020
20021         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
20022                 error "set striped dir error"
20023
20024         touch $DIR/$tdir/striped_dir/a
20025         mkdir $DIR/$tdir/striped_dir/dir_a
20026         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
20027                 error "create striped dir under striped dir fails"
20028
20029         touch $DIR/$tdir/striped_dir1/b
20030         mkdir $DIR/$tdir/striped_dir1/dir_b
20031         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
20032                 error "create striped dir under striped dir fails"
20033
20034         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
20035                 error "rename dir under different striped dir should fail"
20036
20037         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
20038                 error "rename striped dir under diff striped dir should fail"
20039
20040         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
20041                 error "rename file under diff striped dirs fails"
20042
20043         rm -rf $DIR/$tdir
20044 }
20045 run_test 300f "check rename cross striped directory"
20046
20047 test_300_check_default_striped_dir()
20048 {
20049         local dirname=$1
20050         local default_count=$2
20051         local default_index=$3
20052         local stripe_count
20053         local stripe_index
20054         local dir_stripe_index
20055         local dir
20056
20057         echo "checking $dirname $default_count $default_index"
20058         $LFS setdirstripe -D -c $default_count -i $default_index \
20059                                 -t all_char $DIR/$tdir/$dirname ||
20060                 error "set default stripe on striped dir error"
20061         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
20062         [ $stripe_count -eq $default_count ] ||
20063                 error "expect $default_count get $stripe_count for $dirname"
20064
20065         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
20066         [ $stripe_index -eq $default_index ] ||
20067                 error "expect $default_index get $stripe_index for $dirname"
20068
20069         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
20070                                                 error "create dirs failed"
20071
20072         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
20073         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
20074         for dir in $(find $DIR/$tdir/$dirname/*); do
20075                 stripe_count=$($LFS getdirstripe -c $dir)
20076                 [ $stripe_count -eq $default_count ] ||
20077                 [ $stripe_count -eq 0 ] || [ $default_count -eq 1 ] ||
20078                 error "stripe count $default_count != $stripe_count for $dir"
20079
20080                 stripe_index=$($LFS getdirstripe -i $dir)
20081                 [ $default_index -eq -1 ] ||
20082                         [ $stripe_index -eq $default_index ] ||
20083                         error "$stripe_index != $default_index for $dir"
20084
20085                 #check default stripe
20086                 stripe_count=$($LFS getdirstripe -D -c $dir)
20087                 [ $stripe_count -eq $default_count ] ||
20088                 error "default count $default_count != $stripe_count for $dir"
20089
20090                 stripe_index=$($LFS getdirstripe -D -i $dir)
20091                 [ $stripe_index -eq $default_index ] ||
20092                 error "default index $default_index != $stripe_index for $dir"
20093         done
20094         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
20095 }
20096
20097 test_300g() {
20098         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20099         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20100                 skip "Need MDS version at least 2.7.55"
20101
20102         local dir
20103         local stripe_count
20104         local stripe_index
20105
20106         mkdir $DIR/$tdir
20107         mkdir $DIR/$tdir/normal_dir
20108
20109         #Checking when client cache stripe index
20110         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
20111         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
20112                 error "create striped_dir failed"
20113
20114         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
20115                 error "create dir0 fails"
20116         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
20117         [ $stripe_index -eq 0 ] ||
20118                 error "dir0 expect index 0 got $stripe_index"
20119
20120         mkdir $DIR/$tdir/striped_dir/dir1 ||
20121                 error "create dir1 fails"
20122         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
20123         [ $stripe_index -eq 1 ] ||
20124                 error "dir1 expect index 1 got $stripe_index"
20125
20126         #check default stripe count/stripe index
20127         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
20128         test_300_check_default_striped_dir normal_dir 1 0
20129         test_300_check_default_striped_dir normal_dir 2 1
20130         test_300_check_default_striped_dir normal_dir 2 -1
20131
20132         #delete default stripe information
20133         echo "delete default stripeEA"
20134         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
20135                 error "set default stripe on striped dir error"
20136
20137         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
20138         for dir in $(find $DIR/$tdir/normal_dir/*); do
20139                 stripe_count=$($LFS getdirstripe -c $dir)
20140                 [ $stripe_count -eq 0 ] ||
20141                         error "expect 1 get $stripe_count for $dir"
20142                 stripe_index=$($LFS getdirstripe -i $dir)
20143                 [ $stripe_index -eq 0 ] ||
20144                         error "expect 0 get $stripe_index for $dir"
20145         done
20146 }
20147 run_test 300g "check default striped directory for normal directory"
20148
20149 test_300h() {
20150         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20151         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20152                 skip "Need MDS version at least 2.7.55"
20153
20154         local dir
20155         local stripe_count
20156
20157         mkdir $DIR/$tdir
20158         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
20159                 error "set striped dir error"
20160
20161         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
20162         test_300_check_default_striped_dir striped_dir 1 0
20163         test_300_check_default_striped_dir striped_dir 2 1
20164         test_300_check_default_striped_dir striped_dir 2 -1
20165
20166         #delete default stripe information
20167         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
20168                 error "set default stripe on striped dir error"
20169
20170         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
20171         for dir in $(find $DIR/$tdir/striped_dir/*); do
20172                 stripe_count=$($LFS getdirstripe -c $dir)
20173                 [ $stripe_count -eq 0 ] ||
20174                         error "expect 1 get $stripe_count for $dir"
20175         done
20176 }
20177 run_test 300h "check default striped directory for striped directory"
20178
20179 test_300i() {
20180         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20181         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20182         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20183                 skip "Need MDS version at least 2.7.55"
20184
20185         local stripe_count
20186         local file
20187
20188         mkdir $DIR/$tdir
20189
20190         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
20191                 error "set striped dir error"
20192
20193         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
20194                 error "create files under striped dir failed"
20195
20196         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
20197                 error "set striped hashdir error"
20198
20199         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
20200                 error "create dir0 under hash dir failed"
20201         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
20202                 error "create dir1 under hash dir failed"
20203
20204         # unfortunately, we need to umount to clear dir layout cache for now
20205         # once we fully implement dir layout, we can drop this
20206         umount_client $MOUNT || error "umount failed"
20207         mount_client $MOUNT || error "mount failed"
20208
20209         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
20210         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
20211         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
20212
20213         #set the stripe to be unknown hash type
20214         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
20215         $LCTL set_param fail_loc=0x1901
20216         for ((i = 0; i < 10; i++)); do
20217                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
20218                         error "stat f-$i failed"
20219                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
20220         done
20221
20222         touch $DIR/$tdir/striped_dir/f0 &&
20223                 error "create under striped dir with unknown hash should fail"
20224
20225         $LCTL set_param fail_loc=0
20226
20227         umount_client $MOUNT || error "umount failed"
20228         mount_client $MOUNT || error "mount failed"
20229
20230         return 0
20231 }
20232 run_test 300i "client handle unknown hash type striped directory"
20233
20234 test_300j() {
20235         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20236         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20237         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20238                 skip "Need MDS version at least 2.7.55"
20239
20240         local stripe_count
20241         local file
20242
20243         mkdir $DIR/$tdir
20244
20245         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
20246         $LCTL set_param fail_loc=0x1702
20247         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
20248                 error "set striped dir error"
20249
20250         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
20251                 error "create files under striped dir failed"
20252
20253         $LCTL set_param fail_loc=0
20254
20255         rm -rf $DIR/$tdir || error "unlink striped dir fails"
20256
20257         return 0
20258 }
20259 run_test 300j "test large update record"
20260
20261 test_300k() {
20262         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20263         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20264         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20265                 skip "Need MDS version at least 2.7.55"
20266
20267         # this test needs a huge transaction
20268         local kb
20269         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
20270              osd*.$FSNAME-MDT0000.kbytestotal")
20271         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
20272
20273         local stripe_count
20274         local file
20275
20276         mkdir $DIR/$tdir
20277
20278         #define OBD_FAIL_LARGE_STRIPE   0x1703
20279         $LCTL set_param fail_loc=0x1703
20280         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
20281                 error "set striped dir error"
20282         $LCTL set_param fail_loc=0
20283
20284         $LFS getdirstripe $DIR/$tdir/striped_dir ||
20285                 error "getstripeddir fails"
20286         rm -rf $DIR/$tdir/striped_dir ||
20287                 error "unlink striped dir fails"
20288
20289         return 0
20290 }
20291 run_test 300k "test large striped directory"
20292
20293 test_300l() {
20294         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20295         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20296         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20297                 skip "Need MDS version at least 2.7.55"
20298
20299         local stripe_index
20300
20301         test_mkdir -p $DIR/$tdir/striped_dir
20302         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
20303                         error "chown $RUNAS_ID failed"
20304         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
20305                 error "set default striped dir failed"
20306
20307         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
20308         $LCTL set_param fail_loc=0x80000158
20309         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
20310
20311         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
20312         [ $stripe_index -eq 1 ] ||
20313                 error "expect 1 get $stripe_index for $dir"
20314 }
20315 run_test 300l "non-root user to create dir under striped dir with stale layout"
20316
20317 test_300m() {
20318         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20319         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
20320         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20321                 skip "Need MDS version at least 2.7.55"
20322
20323         mkdir -p $DIR/$tdir/striped_dir
20324         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
20325                 error "set default stripes dir error"
20326
20327         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
20328
20329         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
20330         [ $stripe_count -eq 0 ] ||
20331                         error "expect 0 get $stripe_count for a"
20332
20333         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
20334                 error "set default stripes dir error"
20335
20336         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
20337
20338         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
20339         [ $stripe_count -eq 0 ] ||
20340                         error "expect 0 get $stripe_count for b"
20341
20342         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
20343                 error "set default stripes dir error"
20344
20345         mkdir $DIR/$tdir/striped_dir/c &&
20346                 error "default stripe_index is invalid, mkdir c should fails"
20347
20348         rm -rf $DIR/$tdir || error "rmdir fails"
20349 }
20350 run_test 300m "setstriped directory on single MDT FS"
20351
20352 cleanup_300n() {
20353         local list=$(comma_list $(mdts_nodes))
20354
20355         trap 0
20356         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
20357 }
20358
20359 test_300n() {
20360         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20361         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20362         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20363                 skip "Need MDS version at least 2.7.55"
20364         remote_mds_nodsh && skip "remote MDS with nodsh"
20365
20366         local stripe_index
20367         local list=$(comma_list $(mdts_nodes))
20368
20369         trap cleanup_300n RETURN EXIT
20370         mkdir -p $DIR/$tdir
20371         chmod 777 $DIR/$tdir
20372         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
20373                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
20374                 error "create striped dir succeeds with gid=0"
20375
20376         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
20377         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
20378                 error "create striped dir fails with gid=-1"
20379
20380         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
20381         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
20382                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
20383                 error "set default striped dir succeeds with gid=0"
20384
20385
20386         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
20387         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
20388                 error "set default striped dir fails with gid=-1"
20389
20390
20391         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
20392         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
20393                                         error "create test_dir fails"
20394         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
20395                                         error "create test_dir1 fails"
20396         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
20397                                         error "create test_dir2 fails"
20398         cleanup_300n
20399 }
20400 run_test 300n "non-root user to create dir under striped dir with default EA"
20401
20402 test_300o() {
20403         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20404         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20405         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20406                 skip "Need MDS version at least 2.7.55"
20407
20408         local numfree1
20409         local numfree2
20410
20411         mkdir -p $DIR/$tdir
20412
20413         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
20414         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
20415         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
20416                 skip "not enough free inodes $numfree1 $numfree2"
20417         fi
20418
20419         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
20420         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
20421         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
20422                 skip "not enough free space $numfree1 $numfree2"
20423         fi
20424
20425         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
20426                 error "setdirstripe fails"
20427
20428         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
20429                 error "create dirs fails"
20430
20431         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
20432         ls $DIR/$tdir/striped_dir > /dev/null ||
20433                 error "ls striped dir fails"
20434         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
20435                 error "unlink big striped dir fails"
20436 }
20437 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
20438
20439 test_300p() {
20440         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20441         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20442         remote_mds_nodsh && skip "remote MDS with nodsh"
20443
20444         mkdir -p $DIR/$tdir
20445
20446         #define OBD_FAIL_OUT_ENOSPC     0x1704
20447         do_facet mds2 lctl set_param fail_loc=0x80001704
20448         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
20449                  && error "create striped directory should fail"
20450
20451         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
20452
20453         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
20454         true
20455 }
20456 run_test 300p "create striped directory without space"
20457
20458 test_300q() {
20459         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20460         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20461
20462         local fd=$(free_fd)
20463         local cmd="exec $fd<$tdir"
20464         cd $DIR
20465         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
20466         eval $cmd
20467         cmd="exec $fd<&-"
20468         trap "eval $cmd" EXIT
20469         cd $tdir || error "cd $tdir fails"
20470         rmdir  ../$tdir || error "rmdir $tdir fails"
20471         mkdir local_dir && error "create dir succeeds"
20472         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
20473         eval $cmd
20474         return 0
20475 }
20476 run_test 300q "create remote directory under orphan directory"
20477
20478 test_300r() {
20479         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20480                 skip "Need MDS version at least 2.7.55" && return
20481         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
20482
20483         mkdir $DIR/$tdir
20484
20485         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
20486                 error "set striped dir error"
20487
20488         $LFS getdirstripe $DIR/$tdir/striped_dir ||
20489                 error "getstripeddir fails"
20490
20491         local stripe_count
20492         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
20493                       awk '/lmv_stripe_count:/ { print $2 }')
20494
20495         [ $MDSCOUNT -ne $stripe_count ] &&
20496                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
20497
20498         rm -rf $DIR/$tdir/striped_dir ||
20499                 error "unlink striped dir fails"
20500 }
20501 run_test 300r "test -1 striped directory"
20502
20503 prepare_remote_file() {
20504         mkdir $DIR/$tdir/src_dir ||
20505                 error "create remote source failed"
20506
20507         cp /etc/hosts $DIR/$tdir/src_dir/a ||
20508                  error "cp to remote source failed"
20509         touch $DIR/$tdir/src_dir/a
20510
20511         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
20512                 error "create remote target dir failed"
20513
20514         touch $DIR/$tdir/tgt_dir/b
20515
20516         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
20517                 error "rename dir cross MDT failed!"
20518
20519         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
20520                 error "src_child still exists after rename"
20521
20522         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
20523                 error "missing file(a) after rename"
20524
20525         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
20526                 error "diff after rename"
20527 }
20528
20529 test_310a() {
20530         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
20531         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20532
20533         local remote_file=$DIR/$tdir/tgt_dir/b
20534
20535         mkdir -p $DIR/$tdir
20536
20537         prepare_remote_file || error "prepare remote file failed"
20538
20539         #open-unlink file
20540         $OPENUNLINK $remote_file $remote_file ||
20541                 error "openunlink $remote_file failed"
20542         $CHECKSTAT -a $remote_file || error "$remote_file exists"
20543 }
20544 run_test 310a "open unlink remote file"
20545
20546 test_310b() {
20547         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
20548         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20549
20550         local remote_file=$DIR/$tdir/tgt_dir/b
20551
20552         mkdir -p $DIR/$tdir
20553
20554         prepare_remote_file || error "prepare remote file failed"
20555
20556         ln $remote_file $DIR/$tfile || error "link failed for remote file"
20557         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
20558         $CHECKSTAT -t file $remote_file || error "check file failed"
20559 }
20560 run_test 310b "unlink remote file with multiple links while open"
20561
20562 test_310c() {
20563         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20564         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
20565
20566         local remote_file=$DIR/$tdir/tgt_dir/b
20567
20568         mkdir -p $DIR/$tdir
20569
20570         prepare_remote_file || error "prepare remote file failed"
20571
20572         ln $remote_file $DIR/$tfile || error "link failed for remote file"
20573         multiop_bg_pause $remote_file O_uc ||
20574                         error "mulitop failed for remote file"
20575         MULTIPID=$!
20576         $MULTIOP $DIR/$tfile Ouc
20577         kill -USR1 $MULTIPID
20578         wait $MULTIPID
20579 }
20580 run_test 310c "open-unlink remote file with multiple links"
20581
20582 #LU-4825
20583 test_311() {
20584         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20585         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
20586         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
20587                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
20588         remote_mds_nodsh && skip "remote MDS with nodsh"
20589
20590         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
20591         local mdts=$(comma_list $(mdts_nodes))
20592
20593         mkdir -p $DIR/$tdir
20594         $LFS setstripe -i 0 -c 1 $DIR/$tdir
20595         createmany -o $DIR/$tdir/$tfile. 1000
20596
20597         # statfs data is not real time, let's just calculate it
20598         old_iused=$((old_iused + 1000))
20599
20600         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
20601                         osp.*OST0000*MDT0000.create_count")
20602         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
20603                                 osp.*OST0000*MDT0000.max_create_count")
20604         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
20605
20606         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
20607         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
20608         [ $index -ne 0 ] || error "$tfile stripe index is 0"
20609
20610         unlinkmany $DIR/$tdir/$tfile. 1000
20611
20612         do_nodes $mdts "$LCTL set_param -n \
20613                         osp.*OST0000*.max_create_count=$max_count"
20614         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
20615                 do_nodes $mdts "$LCTL set_param -n \
20616                                 osp.*OST0000*.create_count=$count"
20617         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
20618                         grep "=0" && error "create_count is zero"
20619
20620         local new_iused
20621         for i in $(seq 120); do
20622                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
20623                 # system may be too busy to destroy all objs in time, use
20624                 # a somewhat small value to not fail autotest
20625                 [ $((old_iused - new_iused)) -gt 400 ] && break
20626                 sleep 1
20627         done
20628
20629         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
20630         [ $((old_iused - new_iused)) -gt 400 ] ||
20631                 error "objs not destroyed after unlink"
20632 }
20633 run_test 311 "disable OSP precreate, and unlink should destroy objs"
20634
20635 zfs_oid_to_objid()
20636 {
20637         local ost=$1
20638         local objid=$2
20639
20640         local vdevdir=$(dirname $(facet_vdevice $ost))
20641         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
20642         local zfs_zapid=$(do_facet $ost $cmd |
20643                           grep -w "/O/0/d$((objid%32))" -C 5 |
20644                           awk '/Object/{getline; print $1}')
20645         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
20646                           awk "/$objid = /"'{printf $3}')
20647
20648         echo $zfs_objid
20649 }
20650
20651 zfs_object_blksz() {
20652         local ost=$1
20653         local objid=$2
20654
20655         local vdevdir=$(dirname $(facet_vdevice $ost))
20656         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
20657         local blksz=$(do_facet $ost $cmd $objid |
20658                       awk '/dblk/{getline; printf $4}')
20659
20660         case "${blksz: -1}" in
20661                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
20662                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
20663                 *) ;;
20664         esac
20665
20666         echo $blksz
20667 }
20668
20669 test_312() { # LU-4856
20670         remote_ost_nodsh && skip "remote OST with nodsh"
20671         [ "$ost1_FSTYPE" = "zfs" ] ||
20672                 skip_env "the test only applies to zfs"
20673
20674         local max_blksz=$(do_facet ost1 \
20675                           $ZFS get -p recordsize $(facet_device ost1) |
20676                           awk '!/VALUE/{print $3}')
20677
20678         # to make life a little bit easier
20679         $LFS mkdir -c 1 -i 0 $DIR/$tdir
20680         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20681
20682         local tf=$DIR/$tdir/$tfile
20683         touch $tf
20684         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
20685
20686         # Get ZFS object id
20687         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
20688         # block size change by sequential overwrite
20689         local bs
20690
20691         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
20692                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
20693
20694                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
20695                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
20696         done
20697         rm -f $tf
20698
20699         # block size change by sequential append write
20700         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
20701         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
20702         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
20703         local count
20704
20705         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
20706                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
20707                         oflag=sync conv=notrunc
20708
20709                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
20710                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
20711                         error "blksz error, actual $blksz, " \
20712                                 "expected: 2 * $count * $PAGE_SIZE"
20713         done
20714         rm -f $tf
20715
20716         # random write
20717         touch $tf
20718         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
20719         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
20720
20721         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
20722         blksz=$(zfs_object_blksz ost1 $zfs_objid)
20723         [ $blksz -eq $PAGE_SIZE ] ||
20724                 error "blksz error: $blksz, expected: $PAGE_SIZE"
20725
20726         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
20727         blksz=$(zfs_object_blksz ost1 $zfs_objid)
20728         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
20729
20730         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
20731         blksz=$(zfs_object_blksz ost1 $zfs_objid)
20732         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
20733 }
20734 run_test 312 "make sure ZFS adjusts its block size by write pattern"
20735
20736 test_313() {
20737         remote_ost_nodsh && skip "remote OST with nodsh"
20738
20739         local file=$DIR/$tfile
20740
20741         rm -f $file
20742         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
20743
20744         # define OBD_FAIL_TGT_RCVD_EIO           0x720
20745         do_facet ost1 "$LCTL set_param fail_loc=0x720"
20746         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
20747                 error "write should failed"
20748         do_facet ost1 "$LCTL set_param fail_loc=0"
20749         rm -f $file
20750 }
20751 run_test 313 "io should fail after last_rcvd update fail"
20752
20753 test_314() {
20754         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
20755
20756         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
20757         do_facet ost1 "$LCTL set_param fail_loc=0x720"
20758         rm -f $DIR/$tfile
20759         wait_delete_completed
20760         do_facet ost1 "$LCTL set_param fail_loc=0"
20761 }
20762 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
20763
20764 test_315() { # LU-618
20765         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
20766
20767         local file=$DIR/$tfile
20768         rm -f $file
20769
20770         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
20771                 error "multiop file write failed"
20772         $MULTIOP $file oO_RDONLY:r4063232_c &
20773         PID=$!
20774
20775         sleep 2
20776
20777         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
20778         kill -USR1 $PID
20779
20780         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
20781         rm -f $file
20782 }
20783 run_test 315 "read should be accounted"
20784
20785 test_316() {
20786         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20787         large_xattr_enabled || skip_env "ea_inode feature disabled"
20788
20789         rm -rf $DIR/$tdir/d
20790         mkdir -p $DIR/$tdir/d
20791         chown nobody $DIR/$tdir/d
20792         touch $DIR/$tdir/d/file
20793
20794         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
20795 }
20796 run_test 316 "lfs mv"
20797
20798 test_317() {
20799         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
20800                 skip "Need MDS version at least 2.11.53"
20801         if [ "$ost1_FSTYPE" == "zfs" ]; then
20802                 skip "LU-10370: no implementation for ZFS"
20803         fi
20804
20805         local trunc_sz
20806         local grant_blk_size
20807
20808         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
20809                         awk '/grant_block_size:/ { print $2; exit; }')
20810         #
20811         # Create File of size 5M. Truncate it to below size's and verify
20812         # blocks count.
20813         #
20814         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
20815                 error "Create file $DIR/$tfile failed"
20816         stack_trap "rm -f $DIR/$tfile" EXIT
20817
20818         for trunc_sz in 2097152 4097 4000 509 0; do
20819                 $TRUNCATE $DIR/$tfile $trunc_sz ||
20820                         error "truncate $tfile to $trunc_sz failed"
20821                 local sz=$(stat --format=%s $DIR/$tfile)
20822                 local blk=$(stat --format=%b $DIR/$tfile)
20823                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
20824                                      grant_blk_size) * 8))
20825
20826                 if [[ $blk -ne $trunc_blk ]]; then
20827                         $(which stat) $DIR/$tfile
20828                         error "Expected Block $trunc_blk got $blk for $tfile"
20829                 fi
20830
20831                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
20832                         error "Expected Size $trunc_sz got $sz for $tfile"
20833         done
20834
20835         #
20836         # sparse file test
20837         # Create file with a hole and write actual two blocks. Block count
20838         # must be 16.
20839         #
20840         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
20841                 conv=fsync || error "Create file : $DIR/$tfile"
20842
20843         # Calculate the final truncate size.
20844         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
20845
20846         #
20847         # truncate to size $trunc_sz bytes. Strip the last block
20848         # The block count must drop to 8
20849         #
20850         $TRUNCATE $DIR/$tfile $trunc_sz ||
20851                 error "truncate $tfile to $trunc_sz failed"
20852
20853         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
20854         sz=$(stat --format=%s $DIR/$tfile)
20855         blk=$(stat --format=%b $DIR/$tfile)
20856
20857         if [[ $blk -ne $trunc_bsz ]]; then
20858                 $(which stat) $DIR/$tfile
20859                 error "Expected Block $trunc_bsz got $blk for $tfile"
20860         fi
20861
20862         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
20863                 error "Expected Size $trunc_sz got $sz for $tfile"
20864 }
20865 run_test 317 "Verify blocks get correctly update after truncate"
20866
20867 test_318() {
20868         local old_max_active=$($LCTL get_param -n \
20869                             llite.*.max_read_ahead_async_active 2>/dev/null)
20870
20871         $LCTL set_param llite.*.max_read_ahead_async_active=256
20872         local max_active=$($LCTL get_param -n \
20873                            llite.*.max_read_ahead_async_active 2>/dev/null)
20874         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
20875
20876         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
20877                 error "set max_read_ahead_async_active should succeed"
20878
20879         $LCTL set_param llite.*.max_read_ahead_async_active=512
20880         max_active=$($LCTL get_param -n \
20881                      llite.*.max_read_ahead_async_active 2>/dev/null)
20882         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
20883
20884         # restore @max_active
20885         [ $old_max_active -ne 0 ] && $LCTL set_param \
20886                 llite.*.max_read_ahead_async_active=$old_max_active
20887
20888         local old_threshold=$($LCTL get_param -n \
20889                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
20890         local max_per_file_mb=$($LCTL get_param -n \
20891                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
20892
20893         local invalid=$(($max_per_file_mb + 1))
20894         $LCTL set_param \
20895                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
20896                         && error "set $invalid should fail"
20897
20898         local valid=$(($invalid - 1))
20899         $LCTL set_param \
20900                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
20901                         error "set $valid should succeed"
20902         local threshold=$($LCTL get_param -n \
20903                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
20904         [ $threshold -eq $valid ] || error \
20905                 "expect threshold $valid got $threshold"
20906         $LCTL set_param \
20907                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
20908 }
20909 run_test 318 "Verify async readahead tunables"
20910
20911 test_319() {
20912         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
20913
20914         local before=$(date +%s)
20915         local evict
20916         local mdir=$DIR/$tdir
20917         local file=$mdir/xxx
20918
20919         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
20920         touch $file
20921
20922 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
20923         $LCTL set_param fail_val=5 fail_loc=0x8000032c
20924         $LFS mv -m1 $file &
20925
20926         sleep 1
20927         dd if=$file of=/dev/null
20928         wait
20929         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
20930           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
20931
20932         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
20933 }
20934 run_test 319 "lost lease lock on migrate error"
20935
20936 test_398a() { # LU-4198
20937         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20938         $LCTL set_param ldlm.namespaces.*.lru_size=clear
20939
20940         # request a new lock on client
20941         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
20942
20943         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
20944         local lock_count=$($LCTL get_param -n \
20945                            ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
20946         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
20947
20948         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
20949
20950         # no lock cached, should use lockless IO and not enqueue new lock
20951         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
20952         lock_count=$($LCTL get_param -n \
20953                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
20954         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
20955 }
20956 run_test 398a "direct IO should cancel lock otherwise lockless"
20957
20958 test_398b() { # LU-4198
20959         which fio || skip_env "no fio installed"
20960         $LFS setstripe -c -1 $DIR/$tfile
20961
20962         local size=12
20963         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
20964
20965         local njobs=4
20966         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
20967         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
20968                 --numjobs=$njobs --fallocate=none \
20969                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
20970                 --filename=$DIR/$tfile &
20971         bg_pid=$!
20972
20973         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
20974         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
20975                 --numjobs=$njobs --fallocate=none \
20976                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
20977                 --filename=$DIR/$tfile || true
20978         wait $bg_pid
20979
20980         rm -rf $DIR/$tfile
20981 }
20982 run_test 398b "DIO and buffer IO race"
20983
20984 test_398c() { # LU-4198
20985         which fio || skip_env "no fio installed"
20986
20987         saved_debug=$($LCTL get_param -n debug)
20988         $LCTL set_param debug=0
20989
20990         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
20991         ((size /= 1024)) # by megabytes
20992         ((size /= 2)) # write half of the OST at most
20993         [ $size -gt 40 ] && size=40 #reduce test time anyway
20994
20995         $LFS setstripe -c 1 $DIR/$tfile
20996
20997         # it seems like ldiskfs reserves more space than necessary if the
20998         # writing blocks are not mapped, so it extends the file firstly
20999         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
21000         cancel_lru_locks osc
21001
21002         # clear and verify rpc_stats later
21003         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
21004
21005         local njobs=4
21006         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
21007         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
21008                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
21009                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
21010                 --filename=$DIR/$tfile
21011         [ $? -eq 0 ] || error "fio write error"
21012
21013         [ $($LCTL get_param -n \
21014          ldlm.namespaces.${FSNAME}-OST0000-osc-ffff*.lock_count) -eq 0 ] ||
21015                 error "Locks were requested while doing AIO"
21016
21017         # get the percentage of 1-page I/O
21018         pct=$($LCTL get_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats |
21019                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
21020                 awk '{print $7}')
21021         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
21022
21023         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
21024         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
21025                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
21026                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
21027                 --filename=$DIR/$tfile
21028         [ $? -eq 0 ] || error "fio mixed read write error"
21029
21030         rm -rf $DIR/$tfile
21031         $LCTL set_param debug="$saved_debug"
21032 }
21033 run_test 398c "run fio to test AIO"
21034
21035 test_fake_rw() {
21036         local read_write=$1
21037         if [ "$read_write" = "write" ]; then
21038                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
21039         elif [ "$read_write" = "read" ]; then
21040                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
21041         else
21042                 error "argument error"
21043         fi
21044
21045         # turn off debug for performance testing
21046         local saved_debug=$($LCTL get_param -n debug)
21047         $LCTL set_param debug=0
21048
21049         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21050
21051         # get ost1 size - $FSNAME-OST0000
21052         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
21053         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
21054         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
21055
21056         if [ "$read_write" = "read" ]; then
21057                 truncate -s $(expr 1048576 \* $blocks) $DIR/$tfile
21058         fi
21059
21060         local start_time=$(date +%s.%N)
21061         $dd_cmd bs=1M count=$blocks oflag=sync ||
21062                 error "real dd $read_write error"
21063         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
21064
21065         if [ "$read_write" = "write" ]; then
21066                 rm -f $DIR/$tfile
21067         fi
21068
21069         # define OBD_FAIL_OST_FAKE_RW           0x238
21070         do_facet ost1 $LCTL set_param fail_loc=0x238
21071
21072         local start_time=$(date +%s.%N)
21073         $dd_cmd bs=1M count=$blocks oflag=sync ||
21074                 error "fake dd $read_write error"
21075         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
21076
21077         if [ "$read_write" = "write" ]; then
21078                 # verify file size
21079                 cancel_lru_locks osc
21080                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
21081                         error "$tfile size not $blocks MB"
21082         fi
21083         do_facet ost1 $LCTL set_param fail_loc=0
21084
21085         echo "fake $read_write $duration_fake vs. normal $read_write" \
21086                 "$duration in seconds"
21087         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
21088                 error_not_in_vm "fake write is slower"
21089
21090         $LCTL set_param -n debug="$saved_debug"
21091         rm -f $DIR/$tfile
21092 }
21093 test_399a() { # LU-7655 for OST fake write
21094         remote_ost_nodsh && skip "remote OST with nodsh"
21095
21096         test_fake_rw write
21097 }
21098 run_test 399a "fake write should not be slower than normal write"
21099
21100 test_399b() { # LU-8726 for OST fake read
21101         remote_ost_nodsh && skip "remote OST with nodsh"
21102         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
21103                 skip_env "ldiskfs only test"
21104         fi
21105
21106         test_fake_rw read
21107 }
21108 run_test 399b "fake read should not be slower than normal read"
21109
21110 test_400a() { # LU-1606, was conf-sanity test_74
21111         if ! which $CC > /dev/null 2>&1; then
21112                 skip_env "$CC is not installed"
21113         fi
21114
21115         local extra_flags=''
21116         local out=$TMP/$tfile
21117         local prefix=/usr/include/lustre
21118         local prog
21119
21120         # Oleg removes c files in his test rig so test if any c files exist
21121         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
21122                 skip_env "Needed c test files are missing"
21123
21124         if ! [[ -d $prefix ]]; then
21125                 # Assume we're running in tree and fixup the include path.
21126                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
21127                 extra_flags+=" -L$LUSTRE/utils/.lib"
21128         fi
21129
21130         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
21131                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
21132                         error "client api broken"
21133         done
21134         rm -f $out
21135 }
21136 run_test 400a "Lustre client api program can compile and link"
21137
21138 test_400b() { # LU-1606, LU-5011
21139         local header
21140         local out=$TMP/$tfile
21141         local prefix=/usr/include/linux/lustre
21142
21143         # We use a hard coded prefix so that this test will not fail
21144         # when run in tree. There are headers in lustre/include/lustre/
21145         # that are not packaged (like lustre_idl.h) and have more
21146         # complicated include dependencies (like config.h and lnet/types.h).
21147         # Since this test about correct packaging we just skip them when
21148         # they don't exist (see below) rather than try to fixup cppflags.
21149
21150         if ! which $CC > /dev/null 2>&1; then
21151                 skip_env "$CC is not installed"
21152         fi
21153
21154         for header in $prefix/*.h; do
21155                 if ! [[ -f "$header" ]]; then
21156                         continue
21157                 fi
21158
21159                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
21160                         continue # lustre_ioctl.h is internal header
21161                 fi
21162
21163                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
21164                         error "cannot compile '$header'"
21165         done
21166         rm -f $out
21167 }
21168 run_test 400b "packaged headers can be compiled"
21169
21170 test_401a() { #LU-7437
21171         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
21172         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
21173
21174         #count the number of parameters by "list_param -R"
21175         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
21176         #count the number of parameters by listing proc files
21177         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
21178         echo "proc_dirs='$proc_dirs'"
21179         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
21180         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
21181                       sort -u | wc -l)
21182
21183         [ $params -eq $procs ] ||
21184                 error "found $params parameters vs. $procs proc files"
21185
21186         # test the list_param -D option only returns directories
21187         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
21188         #count the number of parameters by listing proc directories
21189         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
21190                 sort -u | wc -l)
21191
21192         [ $params -eq $procs ] ||
21193                 error "found $params parameters vs. $procs proc files"
21194 }
21195 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
21196
21197 test_401b() {
21198         local save=$($LCTL get_param -n jobid_var)
21199         local tmp=testing
21200
21201         $LCTL set_param foo=bar jobid_var=$tmp bar=baz &&
21202                 error "no error returned when setting bad parameters"
21203
21204         local jobid_new=$($LCTL get_param -n foe jobid_var baz)
21205         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
21206
21207         $LCTL set_param -n fog=bam jobid_var=$save bat=fog
21208         local jobid_old=$($LCTL get_param -n foe jobid_var bag)
21209         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
21210 }
21211 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
21212
21213 test_401c() {
21214         local jobid_var_old=$($LCTL get_param -n jobid_var)
21215         local jobid_var_new
21216
21217         $LCTL set_param jobid_var= &&
21218                 error "no error returned for 'set_param a='"
21219
21220         jobid_var_new=$($LCTL get_param -n jobid_var)
21221         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
21222                 error "jobid_var was changed by setting without value"
21223
21224         $LCTL set_param jobid_var &&
21225                 error "no error returned for 'set_param a'"
21226
21227         jobid_var_new=$($LCTL get_param -n jobid_var)
21228         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
21229                 error "jobid_var was changed by setting without value"
21230 }
21231 run_test 401c "Verify 'lctl set_param' without value fails in either format."
21232
21233 test_401d() {
21234         local jobid_var_old=$($LCTL get_param -n jobid_var)
21235         local jobid_var_new
21236         local new_value="foo=bar"
21237
21238         $LCTL set_param jobid_var=$new_value ||
21239                 error "'set_param a=b' did not accept a value containing '='"
21240
21241         jobid_var_new=$($LCTL get_param -n jobid_var)
21242         [[ "$jobid_var_new" == "$new_value" ]] ||
21243                 error "'set_param a=b' failed on a value containing '='"
21244
21245         # Reset the jobid_var to test the other format
21246         $LCTL set_param jobid_var=$jobid_var_old
21247         jobid_var_new=$($LCTL get_param -n jobid_var)
21248         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
21249                 error "failed to reset jobid_var"
21250
21251         $LCTL set_param jobid_var $new_value ||
21252                 error "'set_param a b' did not accept a value containing '='"
21253
21254         jobid_var_new=$($LCTL get_param -n jobid_var)
21255         [[ "$jobid_var_new" == "$new_value" ]] ||
21256                 error "'set_param a b' failed on a value containing '='"
21257
21258         $LCTL set_param jobid_var $jobid_var_old
21259         jobid_var_new=$($LCTL get_param -n jobid_var)
21260         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
21261                 error "failed to reset jobid_var"
21262 }
21263 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
21264
21265 test_402() {
21266         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
21267         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
21268                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
21269         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
21270                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
21271                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
21272         remote_mds_nodsh && skip "remote MDS with nodsh"
21273
21274         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
21275 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
21276         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
21277         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
21278                 echo "Touch failed - OK"
21279 }
21280 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
21281
21282 test_403() {
21283         local file1=$DIR/$tfile.1
21284         local file2=$DIR/$tfile.2
21285         local tfile=$TMP/$tfile
21286
21287         rm -f $file1 $file2 $tfile
21288
21289         touch $file1
21290         ln $file1 $file2
21291
21292         # 30 sec OBD_TIMEOUT in ll_getattr()
21293         # right before populating st_nlink
21294         $LCTL set_param fail_loc=0x80001409
21295         stat -c %h $file1 > $tfile &
21296
21297         # create an alias, drop all locks and reclaim the dentry
21298         < $file2
21299         cancel_lru_locks mdc
21300         cancel_lru_locks osc
21301         sysctl -w vm.drop_caches=2
21302
21303         wait
21304
21305         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
21306
21307         rm -f $tfile $file1 $file2
21308 }
21309 run_test 403 "i_nlink should not drop to zero due to aliasing"
21310
21311 test_404() { # LU-6601
21312         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
21313                 skip "Need server version newer than 2.8.52"
21314         remote_mds_nodsh && skip "remote MDS with nodsh"
21315
21316         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
21317                 awk '/osp .*-osc-MDT/ { print $4}')
21318
21319         local osp
21320         for osp in $mosps; do
21321                 echo "Deactivate: " $osp
21322                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
21323                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
21324                         awk -vp=$osp '$4 == p { print $2 }')
21325                 [ $stat = IN ] || {
21326                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
21327                         error "deactivate error"
21328                 }
21329                 echo "Activate: " $osp
21330                 do_facet $SINGLEMDS $LCTL --device %$osp activate
21331                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
21332                         awk -vp=$osp '$4 == p { print $2 }')
21333                 [ $stat = UP ] || {
21334                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
21335                         error "activate error"
21336                 }
21337         done
21338 }
21339 run_test 404 "validate manual {de}activated works properly for OSPs"
21340
21341 test_405() {
21342         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
21343         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
21344                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
21345                         skip "Layout swap lock is not supported"
21346
21347         check_swap_layouts_support
21348
21349         test_mkdir $DIR/$tdir
21350         swap_lock_test -d $DIR/$tdir ||
21351                 error "One layout swap locked test failed"
21352 }
21353 run_test 405 "Various layout swap lock tests"
21354
21355 test_406() {
21356         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21357         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
21358         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
21359         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21360         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
21361                 skip "Need MDS version at least 2.8.50"
21362
21363         local def_stripe_size=$($LFS getstripe -S $MOUNT)
21364         local test_pool=$TESTNAME
21365
21366         pool_add $test_pool || error "pool_add failed"
21367         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
21368                 error "pool_add_targets failed"
21369
21370         save_layout_restore_at_exit $MOUNT
21371
21372         # parent set default stripe count only, child will stripe from both
21373         # parent and fs default
21374         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
21375                 error "setstripe $MOUNT failed"
21376         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
21377         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
21378         for i in $(seq 10); do
21379                 local f=$DIR/$tdir/$tfile.$i
21380                 touch $f || error "touch failed"
21381                 local count=$($LFS getstripe -c $f)
21382                 [ $count -eq $OSTCOUNT ] ||
21383                         error "$f stripe count $count != $OSTCOUNT"
21384                 local offset=$($LFS getstripe -i $f)
21385                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
21386                 local size=$($LFS getstripe -S $f)
21387                 [ $size -eq $((def_stripe_size * 2)) ] ||
21388                         error "$f stripe size $size != $((def_stripe_size * 2))"
21389                 local pool=$($LFS getstripe -p $f)
21390                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
21391         done
21392
21393         # change fs default striping, delete parent default striping, now child
21394         # will stripe from new fs default striping only
21395         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
21396                 error "change $MOUNT default stripe failed"
21397         $LFS setstripe -c 0 $DIR/$tdir ||
21398                 error "delete $tdir default stripe failed"
21399         for i in $(seq 11 20); do
21400                 local f=$DIR/$tdir/$tfile.$i
21401                 touch $f || error "touch $f failed"
21402                 local count=$($LFS getstripe -c $f)
21403                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
21404                 local offset=$($LFS getstripe -i $f)
21405                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
21406                 local size=$($LFS getstripe -S $f)
21407                 [ $size -eq $def_stripe_size ] ||
21408                         error "$f stripe size $size != $def_stripe_size"
21409                 local pool=$($LFS getstripe -p $f)
21410                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
21411         done
21412
21413         unlinkmany $DIR/$tdir/$tfile. 1 20
21414
21415         local f=$DIR/$tdir/$tfile
21416         pool_remove_all_targets $test_pool $f
21417         pool_remove $test_pool $f
21418 }
21419 run_test 406 "DNE support fs default striping"
21420
21421 test_407() {
21422         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21423         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
21424                 skip "Need MDS version at least 2.8.55"
21425         remote_mds_nodsh && skip "remote MDS with nodsh"
21426
21427         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
21428                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
21429         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
21430                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
21431         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
21432
21433         #define OBD_FAIL_DT_TXN_STOP    0x2019
21434         for idx in $(seq $MDSCOUNT); do
21435                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
21436         done
21437         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
21438         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
21439                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
21440         true
21441 }
21442 run_test 407 "transaction fail should cause operation fail"
21443
21444 test_408() {
21445         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
21446
21447         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
21448         lctl set_param fail_loc=0x8000040a
21449         # let ll_prepare_partial_page() fail
21450         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
21451
21452         rm -f $DIR/$tfile
21453
21454         # create at least 100 unused inodes so that
21455         # shrink_icache_memory(0) should not return 0
21456         touch $DIR/$tfile-{0..100}
21457         rm -f $DIR/$tfile-{0..100}
21458         sync
21459
21460         echo 2 > /proc/sys/vm/drop_caches
21461 }
21462 run_test 408 "drop_caches should not hang due to page leaks"
21463
21464 test_409()
21465 {
21466         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21467
21468         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
21469         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
21470         touch $DIR/$tdir/guard || error "(2) Fail to create"
21471
21472         local PREFIX=$(str_repeat 'A' 128)
21473         echo "Create 1K hard links start at $(date)"
21474         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
21475                 error "(3) Fail to hard link"
21476
21477         echo "Links count should be right although linkEA overflow"
21478         stat $DIR/$tdir/guard || error "(4) Fail to stat"
21479         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
21480         [ $linkcount -eq 1001 ] ||
21481                 error "(5) Unexpected hard links count: $linkcount"
21482
21483         echo "List all links start at $(date)"
21484         ls -l $DIR/$tdir/foo > /dev/null ||
21485                 error "(6) Fail to list $DIR/$tdir/foo"
21486
21487         echo "Unlink hard links start at $(date)"
21488         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
21489                 error "(7) Fail to unlink"
21490         echo "Unlink hard links finished at $(date)"
21491 }
21492 run_test 409 "Large amount of cross-MDTs hard links on the same file"
21493
21494 test_410()
21495 {
21496         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
21497                 skip "Need client version at least 2.9.59"
21498
21499         # Create a file, and stat it from the kernel
21500         local testfile=$DIR/$tfile
21501         touch $testfile
21502
21503         local run_id=$RANDOM
21504         local my_ino=$(stat --format "%i" $testfile)
21505
21506         # Try to insert the module. This will always fail as the
21507         # module is designed to not be inserted.
21508         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
21509             &> /dev/null
21510
21511         # Anything but success is a test failure
21512         dmesg | grep -q \
21513             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
21514             error "no inode match"
21515 }
21516 run_test 410 "Test inode number returned from kernel thread"
21517
21518 cleanup_test411_cgroup() {
21519         trap 0
21520         rmdir "$1"
21521 }
21522
21523 test_411() {
21524         local cg_basedir=/sys/fs/cgroup/memory
21525         # LU-9966
21526         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
21527                 skip "no setup for cgroup"
21528
21529         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
21530                 error "test file creation failed"
21531         cancel_lru_locks osc
21532
21533         # Create a very small memory cgroup to force a slab allocation error
21534         local cgdir=$cg_basedir/osc_slab_alloc
21535         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
21536         trap "cleanup_test411_cgroup $cgdir" EXIT
21537         echo 2M > $cgdir/memory.kmem.limit_in_bytes
21538         echo 1M > $cgdir/memory.limit_in_bytes
21539
21540         # Should not LBUG, just be killed by oom-killer
21541         # dd will return 0 even allocation failure in some environment.
21542         # So don't check return value
21543         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
21544         cleanup_test411_cgroup $cgdir
21545
21546         return 0
21547 }
21548 run_test 411 "Slab allocation error with cgroup does not LBUG"
21549
21550 test_412() {
21551         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21552         if [ $MDS1_VERSION -lt $(version_code 2.10.55) ]; then
21553                 skip "Need server version at least 2.10.55"
21554         fi
21555
21556         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
21557                 error "mkdir failed"
21558         $LFS getdirstripe $DIR/$tdir
21559         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
21560         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
21561                 error "expect $((MDSCOUT - 1)) get $stripe_index"
21562         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
21563         [ $stripe_count -eq 2 ] ||
21564                 error "expect 2 get $stripe_count"
21565 }
21566 run_test 412 "mkdir on specific MDTs"
21567
21568 test_qos_mkdir() {
21569         local mkdir_cmd=$1
21570         local stripe_count=$2
21571         local mdts=$(comma_list $(mdts_nodes))
21572
21573         local testdir
21574         local lmv_qos_prio_free
21575         local lmv_qos_threshold_rr
21576         local lmv_qos_maxage
21577         local lod_qos_prio_free
21578         local lod_qos_threshold_rr
21579         local lod_qos_maxage
21580         local count
21581         local i
21582
21583         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
21584         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
21585         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
21586                 head -n1)
21587         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
21588         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
21589         stack_trap "$LCTL set_param \
21590                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null" EXIT
21591         stack_trap "$LCTL set_param \
21592                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
21593         stack_trap "$LCTL set_param \
21594                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" EXIT
21595
21596         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
21597                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
21598         lod_qos_prio_free=${lod_qos_prio_free%%%}
21599         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
21600                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
21601         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
21602         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
21603                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
21604         stack_trap "do_nodes $mdts $LCTL set_param \
21605                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null" EXIT
21606         stack_trap "do_nodes $mdts $LCTL set_param \
21607                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null" \
21608                 EXIT
21609         stack_trap "do_nodes $mdts $LCTL set_param \
21610                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" EXIT
21611
21612         echo
21613         echo "Mkdir (stripe_count $stripe_count) roundrobin:"
21614
21615         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
21616         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
21617
21618         testdir=$DIR/$tdir-s$stripe_count/rr
21619
21620         for i in $(seq $((100 * MDSCOUNT))); do
21621                 eval $mkdir_cmd $testdir/subdir$i ||
21622                         error "$mkdir_cmd subdir$i failed"
21623         done
21624
21625         for i in $(seq $MDSCOUNT); do
21626                 count=$($LFS getdirstripe -i $testdir/* |
21627                                 grep ^$((i - 1))$ | wc -l)
21628                 echo "$count directories created on MDT$((i - 1))"
21629                 [ $count -eq 100 ] || error "subdirs are not evenly distributed"
21630
21631                 if [ $stripe_count -gt 1 ]; then
21632                         count=$($LFS getdirstripe $testdir/* |
21633                                 grep -P "^\s+$((i - 1))\t" | wc -l)
21634                         echo "$count stripes created on MDT$((i - 1))"
21635                         # deviation should < 5% of average
21636                         [ $count -lt $((95 * stripe_count)) ] ||
21637                         [ $count -gt $((105 * stripe_count)) ] &&
21638                                 error "stripes are not evenly distributed"
21639                 fi
21640         done
21641
21642         $LCTL set_param lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null
21643         do_nodes $mdts $LCTL set_param \
21644                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null
21645
21646         echo
21647         echo "Check for uneven MDTs: "
21648
21649         local ffree
21650         local bavail
21651         local max
21652         local min
21653         local max_index
21654         local min_index
21655         local tmp
21656
21657         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
21658         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
21659         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
21660
21661         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
21662         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
21663         max_index=0
21664         min_index=0
21665         for ((i = 1; i < ${#ffree[@]}; i++)); do
21666                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
21667                 if [ $tmp -gt $max ]; then
21668                         max=$tmp
21669                         max_index=$i
21670                 fi
21671                 if [ $tmp -lt $min ]; then
21672                         min=$tmp
21673                         min_index=$i
21674                 fi
21675         done
21676
21677         [ ${ffree[min_index]} -eq 0 ] &&
21678                 skip "no free files in MDT$min_index"
21679         [ ${ffree[min_index]} -gt 100000000 ] &&
21680                 skip "too much free files in MDT$min_index"
21681
21682         # Check if we need to generate uneven MDTs
21683         local threshold=50
21684         local diff=$(((max - min) * 100 / min))
21685         local value="$(generate_string 1024)"
21686
21687         while [ $diff -lt $threshold ]; do
21688                 # generate uneven MDTs, create till $threshold% diff
21689                 echo -n "weight diff=$diff% must be > $threshold% ..."
21690                 count=$((${ffree[min_index]} / 10))
21691                 # 50 sec per 10000 files in vm
21692                 [ $count -gt 40000 ] && [ "$SLOW" = "no" ] &&
21693                         skip "$count files to create"
21694                 echo "Fill MDT$min_index with $count files"
21695                 [ -d $DIR/$tdir-MDT$min_index ] ||
21696                         $LFS mkdir -i $min_index $DIR/$tdir-MDT$min_index ||
21697                         error "mkdir $tdir-MDT$min_index failed"
21698                 for i in $(seq $count); do
21699                         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE \
21700                                 $DIR/$tdir-MDT$min_index/f$j_$i > /dev/null ||
21701                                 error "create f$j_$i failed"
21702                         setfattr -n user.413b -v $value \
21703                                 $DIR/$tdir-MDT$min_index/f$j_$i ||
21704                                 error "setfattr f$j_$i failed"
21705                 done
21706
21707                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
21708                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
21709                 max=$(((${ffree[max_index]} >> 8) * \
21710                         (${bavail[max_index]} * bsize >> 16)))
21711                 min=$(((${ffree[min_index]} >> 8) * \
21712                         (${bavail[min_index]} * bsize >> 16)))
21713                 diff=$(((max - min) * 100 / min))
21714         done
21715
21716         echo "MDT filesfree available: ${ffree[@]}"
21717         echo "MDT blocks available: ${bavail[@]}"
21718         echo "weight diff=$diff%"
21719
21720         echo
21721         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
21722
21723         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
21724         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
21725         # decrease statfs age, so that it can be updated in time
21726         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
21727         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
21728
21729         sleep 1
21730
21731         testdir=$DIR/$tdir-s$stripe_count/qos
21732
21733         for i in $(seq $((100 * MDSCOUNT))); do
21734                 eval $mkdir_cmd $testdir/subdir$i ||
21735                         error "$mkdir_cmd subdir$i failed"
21736         done
21737
21738         for i in $(seq $MDSCOUNT); do
21739                 count=$($LFS getdirstripe -i $testdir/* | grep ^$((i - 1))$ |
21740                         wc -l)
21741                 echo "$count directories created on MDT$((i - 1))"
21742
21743                 if [ $stripe_count -gt 1 ]; then
21744                         count=$($LFS getdirstripe $testdir/* |
21745                                 grep -P "^\s+$((i - 1))\t" | wc -l)
21746                         echo "$count stripes created on MDT$((i - 1))"
21747                 fi
21748         done
21749
21750         max=$($LFS getdirstripe -i $testdir/* | grep ^$max_index$ | wc -l)
21751         min=$($LFS getdirstripe -i $testdir/* | grep ^$min_index$ | wc -l)
21752
21753         # D-value should > 10% of averge
21754         [ $((max - min)) -lt 10 ] &&
21755                 error "subdirs shouldn't be evenly distributed"
21756
21757         # ditto
21758         if [ $stripe_count -gt 1 ]; then
21759                 max=$($LFS getdirstripe $testdir/* |
21760                         grep -P "^\s+$max_index\t" | wc -l)
21761                 min=$($LFS getdirstripe $testdir/* |
21762                         grep -P "^\s+$min_index\t" | wc -l)
21763                 [ $((max - min)) -le $((10 * stripe_count)) ] &&
21764                         error "stripes shouldn't be evenly distributed"|| true
21765         fi
21766 }
21767
21768 test_413a() {
21769         [ $MDSCOUNT -lt 2 ] &&
21770                 skip "We need at least 2 MDTs for this test"
21771
21772         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
21773                 skip "Need server version at least 2.12.52"
21774
21775         local stripe_count
21776
21777         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
21778                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
21779                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
21780                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
21781                 test_qos_mkdir "$LFS mkdir -c $stripe_count" $stripe_count
21782         done
21783 }
21784 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
21785
21786 test_413b() {
21787         [ $MDSCOUNT -lt 2 ] &&
21788                 skip "We need at least 2 MDTs for this test"
21789
21790         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
21791                 skip "Need server version at least 2.12.52"
21792
21793         local stripe_count
21794
21795         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
21796                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
21797                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
21798                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
21799                 $LFS setdirstripe -D -c $stripe_count \
21800                         $DIR/$tdir-s$stripe_count/rr ||
21801                         error "setdirstripe failed"
21802                 $LFS setdirstripe -D -c $stripe_count \
21803                         $DIR/$tdir-s$stripe_count/qos ||
21804                         error "setdirstripe failed"
21805                 test_qos_mkdir "mkdir" $stripe_count
21806         done
21807 }
21808 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
21809
21810 test_414() {
21811 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
21812         $LCTL set_param fail_loc=0x80000521
21813         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
21814         rm -f $DIR/$tfile
21815 }
21816 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
21817
21818 test_415() {
21819         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21820         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21821                 skip "Need server version at least 2.11.52"
21822
21823         # LU-11102
21824         local total
21825         local setattr_pid
21826         local start_time
21827         local end_time
21828         local duration
21829
21830         total=500
21831         # this test may be slow on ZFS
21832         [ "$mds1_FSTYPE" == "zfs" ] && total=100
21833
21834         # though this test is designed for striped directory, let's test normal
21835         # directory too since lock is always saved as CoS lock.
21836         test_mkdir $DIR/$tdir || error "mkdir $tdir"
21837         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
21838
21839         (
21840                 while true; do
21841                         touch $DIR/$tdir
21842                 done
21843         ) &
21844         setattr_pid=$!
21845
21846         start_time=$(date +%s)
21847         for i in $(seq $total); do
21848                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
21849                         > /dev/null
21850         done
21851         end_time=$(date +%s)
21852         duration=$((end_time - start_time))
21853
21854         kill -9 $setattr_pid
21855
21856         echo "rename $total files took $duration sec"
21857         [ $duration -lt 100 ] || error "rename took $duration sec"
21858 }
21859 run_test 415 "lock revoke is not missing"
21860
21861 test_416() {
21862         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
21863                 skip "Need server version at least 2.11.55"
21864
21865         # define OBD_FAIL_OSD_TXN_START    0x19a
21866         do_facet mds1 lctl set_param fail_loc=0x19a
21867
21868         lfs mkdir -c $MDSCOUNT $DIR/$tdir
21869
21870         true
21871 }
21872 run_test 416 "transaction start failure won't cause system hung"
21873
21874 cleanup_417() {
21875         trap 0
21876         do_nodes $(comma_list $(mdts_nodes)) \
21877                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
21878         do_nodes $(comma_list $(mdts_nodes)) \
21879                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
21880         do_nodes $(comma_list $(mdts_nodes)) \
21881                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
21882 }
21883
21884 test_417() {
21885         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21886         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
21887                 skip "Need MDS version at least 2.11.56"
21888
21889         trap cleanup_417 RETURN EXIT
21890
21891         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
21892         do_nodes $(comma_list $(mdts_nodes)) \
21893                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
21894         $LFS migrate -m 0 $DIR/$tdir.1 &&
21895                 error "migrate dir $tdir.1 should fail"
21896
21897         do_nodes $(comma_list $(mdts_nodes)) \
21898                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
21899         $LFS mkdir -i 1 $DIR/$tdir.2 &&
21900                 error "create remote dir $tdir.2 should fail"
21901
21902         do_nodes $(comma_list $(mdts_nodes)) \
21903                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
21904         $LFS mkdir -c 2 $DIR/$tdir.3 &&
21905                 error "create striped dir $tdir.3 should fail"
21906         true
21907 }
21908 run_test 417 "disable remote dir, striped dir and dir migration"
21909
21910 # Checks that the outputs of df [-i] and lfs df [-i] match
21911 #
21912 # usage: check_lfs_df <blocks | inodes> <mountpoint>
21913 check_lfs_df() {
21914         local dir=$2
21915         local inodes
21916         local df_out
21917         local lfs_df_out
21918         local count
21919         local passed=false
21920
21921         # blocks or inodes
21922         [ "$1" == "blocks" ] && inodes= || inodes="-i"
21923
21924         for count in {1..100}; do
21925                 cancel_lru_locks
21926                 sync; sleep 0.2
21927
21928                 # read the lines of interest
21929                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
21930                         error "df $inodes $dir | tail -n +2 failed"
21931                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
21932                         error "lfs df $inodes $dir | grep summary: failed"
21933
21934                 # skip first substrings of each output as they are different
21935                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
21936                 # compare the two outputs
21937                 passed=true
21938                 for i in {1..5}; do
21939                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
21940                 done
21941                 $passed && break
21942         done
21943
21944         if ! $passed; then
21945                 df -P $inodes $dir
21946                 echo
21947                 lfs df $inodes $dir
21948                 error "df and lfs df $1 output mismatch: "      \
21949                       "df ${inodes}: ${df_out[*]}, "            \
21950                       "lfs df ${inodes}: ${lfs_df_out[*]}"
21951         fi
21952 }
21953
21954 test_418() {
21955         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21956
21957         local dir=$DIR/$tdir
21958         local numfiles=$((RANDOM % 4096 + 2))
21959         local numblocks=$((RANDOM % 256 + 1))
21960
21961         wait_delete_completed
21962         test_mkdir $dir
21963
21964         # check block output
21965         check_lfs_df blocks $dir
21966         # check inode output
21967         check_lfs_df inodes $dir
21968
21969         # create a single file and retest
21970         echo "Creating a single file and testing"
21971         createmany -o $dir/$tfile- 1 &>/dev/null ||
21972                 error "creating 1 file in $dir failed"
21973         check_lfs_df blocks $dir
21974         check_lfs_df inodes $dir
21975
21976         # create a random number of files
21977         echo "Creating $((numfiles - 1)) files and testing"
21978         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
21979                 error "creating $((numfiles - 1)) files in $dir failed"
21980
21981         # write a random number of blocks to the first test file
21982         echo "Writing $numblocks 4K blocks and testing"
21983         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
21984                 count=$numblocks &>/dev/null ||
21985                 error "dd to $dir/${tfile}-0 failed"
21986
21987         # retest
21988         check_lfs_df blocks $dir
21989         check_lfs_df inodes $dir
21990
21991         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
21992                 error "unlinking $numfiles files in $dir failed"
21993 }
21994 run_test 418 "df and lfs df outputs match"
21995
21996 test_419()
21997 {
21998         local dir=$DIR/$tdir
21999
22000         mkdir -p $dir
22001         touch $dir/file
22002
22003         cancel_lru_locks mdc
22004
22005         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
22006         $LCTL set_param fail_loc=0x1410
22007         cat $dir/file
22008         $LCTL set_param fail_loc=0
22009         rm -rf $dir
22010 }
22011 run_test 419 "Verify open file by name doesn't crash kernel"
22012
22013 test_420()
22014 {
22015         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
22016                 skip "Need MDS version at least 2.12.53"
22017
22018         local SAVE_UMASK=$(umask)
22019         local dir=$DIR/$tdir
22020         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
22021
22022         mkdir -p $dir
22023         umask 0000
22024         mkdir -m03777 $dir/testdir
22025         ls -dn $dir/testdir
22026         # Need to remove trailing '.' when SELinux is enabled
22027         local dirperms=$(ls -dn $dir/testdir |
22028                          awk '{ sub(/\.$/, "", $1); print $1}')
22029         [ $dirperms == "drwxrwsrwt" ] ||
22030                 error "incorrect perms on $dir/testdir"
22031
22032         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
22033                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
22034         ls -n $dir/testdir/testfile
22035         local fileperms=$(ls -n $dir/testdir/testfile |
22036                           awk '{ sub(/\.$/, "", $1); print $1}')
22037         [ $fileperms == "-rwxr-xr-x" ] ||
22038                 error "incorrect perms on $dir/testdir/testfile"
22039
22040         umask $SAVE_UMASK
22041 }
22042 run_test 420 "clear SGID bit on non-directories for non-members"
22043
22044 test_421a() {
22045         local cnt
22046         local fid1
22047         local fid2
22048
22049         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
22050                 skip "Need MDS version at least 2.12.54"
22051
22052         test_mkdir $DIR/$tdir
22053         createmany -o $DIR/$tdir/f 3
22054         cnt=$(ls -1 $DIR/$tdir | wc -l)
22055         [ $cnt != 3 ] && error "unexpected #files: $cnt"
22056
22057         fid1=$(lfs path2fid $DIR/$tdir/f1)
22058         fid2=$(lfs path2fid $DIR/$tdir/f2)
22059         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
22060
22061         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
22062         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
22063
22064         cnt=$(ls -1 $DIR/$tdir | wc -l)
22065         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
22066
22067         rm -f $DIR/$tdir/f3 || error "can't remove f3"
22068         createmany -o $DIR/$tdir/f 3
22069         cnt=$(ls -1 $DIR/$tdir | wc -l)
22070         [ $cnt != 3 ] && error "unexpected #files: $cnt"
22071
22072         fid1=$(lfs path2fid $DIR/$tdir/f1)
22073         fid2=$(lfs path2fid $DIR/$tdir/f2)
22074         echo "remove using fsname $FSNAME"
22075         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
22076
22077         cnt=$(ls -1 $DIR/$tdir | wc -l)
22078         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
22079 }
22080 run_test 421a "simple rm by fid"
22081
22082 test_421b() {
22083         local cnt
22084         local FID1
22085         local FID2
22086
22087         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
22088                 skip "Need MDS version at least 2.12.54"
22089
22090         test_mkdir $DIR/$tdir
22091         createmany -o $DIR/$tdir/f 3
22092         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
22093         MULTIPID=$!
22094
22095         FID1=$(lfs path2fid $DIR/$tdir/f1)
22096         FID2=$(lfs path2fid $DIR/$tdir/f2)
22097         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
22098
22099         kill -USR1 $MULTIPID
22100         wait
22101
22102         cnt=$(ls $DIR/$tdir | wc -l)
22103         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
22104 }
22105 run_test 421b "rm by fid on open file"
22106
22107 test_421c() {
22108         local cnt
22109         local FIDS
22110
22111         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
22112                 skip "Need MDS version at least 2.12.54"
22113
22114         test_mkdir $DIR/$tdir
22115         createmany -o $DIR/$tdir/f 3
22116         touch $DIR/$tdir/$tfile
22117         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
22118         cnt=$(ls -1 $DIR/$tdir | wc -l)
22119         [ $cnt != 184 ] && error "unexpected #files: $cnt"
22120
22121         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
22122         $LFS rmfid $DIR $FID1 || error "rmfid failed"
22123
22124         cnt=$(ls $DIR/$tdir | wc -l)
22125         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
22126 }
22127 run_test 421c "rm by fid against hardlinked files"
22128
22129 test_421d() {
22130         local cnt
22131         local FIDS
22132
22133         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
22134                 skip "Need MDS version at least 2.12.54"
22135
22136         test_mkdir $DIR/$tdir
22137         createmany -o $DIR/$tdir/f 4097
22138         cnt=$(ls -1 $DIR/$tdir | wc -l)
22139         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
22140
22141         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
22142         $LFS rmfid $DIR $FIDS || error "rmfid failed"
22143
22144         cnt=$(ls $DIR/$tdir | wc -l)
22145         rm -rf $DIR/$tdir
22146         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
22147 }
22148 run_test 421d "rmfid en masse"
22149
22150 test_421e() {
22151         local cnt
22152         local FID
22153
22154         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22155         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
22156                 skip "Need MDS version at least 2.12.54"
22157
22158         mkdir -p $DIR/$tdir
22159         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
22160         createmany -o $DIR/$tdir/striped_dir/f 512
22161         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
22162         [ $cnt != 512 ] && error "unexpected #files: $cnt"
22163
22164         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
22165                 sed "s/[/][^:]*://g")
22166         $LFS rmfid $DIR $FIDS || error "rmfid failed"
22167
22168         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
22169         rm -rf $DIR/$tdir
22170         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
22171 }
22172 run_test 421e "rmfid in DNE"
22173
22174 test_421f() {
22175         local cnt
22176         local FID
22177
22178         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
22179                 skip "Need MDS version at least 2.12.54"
22180
22181         test_mkdir $DIR/$tdir
22182         touch $DIR/$tdir/f
22183         cnt=$(ls -1 $DIR/$tdir | wc -l)
22184         [ $cnt != 1 ] && error "unexpected #files: $cnt"
22185
22186         FID=$(lfs path2fid $DIR/$tdir/f)
22187         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
22188         # rmfid should fail
22189         cnt=$(ls -1 $DIR/$tdir | wc -l)
22190         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
22191
22192         chmod a+rw $DIR/$tdir
22193         ls -la $DIR/$tdir
22194         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
22195         # rmfid should fail
22196         cnt=$(ls -1 $DIR/$tdir | wc -l)
22197         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
22198
22199         rm -f $DIR/$tdir/f
22200         $RUNAS touch $DIR/$tdir/f
22201         FID=$(lfs path2fid $DIR/$tdir/f)
22202         echo "rmfid as root"
22203         $LFS rmfid $DIR $FID || error "rmfid as root failed"
22204         cnt=$(ls -1 $DIR/$tdir | wc -l)
22205         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
22206
22207         rm -f $DIR/$tdir/f
22208         $RUNAS touch $DIR/$tdir/f
22209         cnt=$(ls -1 $DIR/$tdir | wc -l)
22210         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
22211         FID=$(lfs path2fid $DIR/$tdir/f)
22212         # rmfid w/o user_fid2path mount option should fail
22213         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
22214         cnt=$(ls -1 $DIR/$tdir | wc -l)
22215         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
22216
22217         umount_client $MOUNT || error "failed to umount client"
22218         mount_client $MOUNT "$MOUNT_OPTS,user_fid2path" ||
22219                 error "failed to mount client'"
22220
22221         $RUNAS $LFS rmfid $DIR $FID || error "rmfid failed"
22222         # rmfid should succeed
22223         cnt=$(ls -1 $DIR/$tdir | wc -l)
22224         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
22225
22226         # rmfid shouldn't allow to remove files due to dir's permission
22227         chmod a+rwx $DIR/$tdir
22228         touch $DIR/$tdir/f
22229         ls -la $DIR/$tdir
22230         FID=$(lfs path2fid $DIR/$tdir/f)
22231         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail"
22232
22233         umount_client $MOUNT || error "failed to umount client"
22234         mount_client $MOUNT "$MOUNT_OPTS" ||
22235                 error "failed to mount client'"
22236
22237 }
22238 run_test 421f "rmfid checks permissions"
22239
22240 test_421g() {
22241         local cnt
22242         local FIDS
22243
22244         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22245         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
22246                 skip "Need MDS version at least 2.12.54"
22247
22248         mkdir -p $DIR/$tdir
22249         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
22250         createmany -o $DIR/$tdir/striped_dir/f 512
22251         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
22252         [ $cnt != 512 ] && error "unexpected #files: $cnt"
22253
22254         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
22255                 sed "s/[/][^:]*://g")
22256
22257         rm -f $DIR/$tdir/striped_dir/f1*
22258         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
22259         removed=$((512 - cnt))
22260
22261         # few files have been just removed, so we expect
22262         # rmfid to fail on their fids
22263         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
22264         [ $removed != $errors ] && error "$errors != $removed"
22265
22266         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
22267         rm -rf $DIR/$tdir
22268         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
22269 }
22270 run_test 421g "rmfid to return errors properly"
22271
22272 test_422() {
22273         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
22274         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
22275         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
22276         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
22277         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
22278
22279         local amc=$(at_max_get client)
22280         local amo=$(at_max_get mds1)
22281         local timeout=`lctl get_param -n timeout`
22282
22283         at_max_set 0 client
22284         at_max_set 0 mds1
22285
22286 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
22287         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
22288                         fail_val=$(((2*timeout + 10)*1000))
22289         touch $DIR/$tdir/d3/file &
22290         sleep 2
22291 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
22292         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
22293                         fail_val=$((2*timeout + 5))
22294         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
22295         local pid=$!
22296         sleep 1
22297         kill -9 $pid
22298         sleep $((2 * timeout))
22299         echo kill $pid
22300         kill -9 $pid
22301         lctl mark touch
22302         touch $DIR/$tdir/d2/file3
22303         touch $DIR/$tdir/d2/file4
22304         touch $DIR/$tdir/d2/file5
22305
22306         wait
22307         at_max_set $amc client
22308         at_max_set $amo mds1
22309
22310         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
22311         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
22312                 error "Watchdog is always throttled"
22313 }
22314 run_test 422 "kill a process with RPC in progress"
22315
22316 stat_test() {
22317     df -h $MOUNT &
22318     df -h $MOUNT &
22319     df -h $MOUNT &
22320     df -h $MOUNT &
22321     df -h $MOUNT &
22322     df -h $MOUNT &
22323 }
22324
22325 test_423() {
22326     local _stats
22327     # ensure statfs cache is expired
22328     sleep 2;
22329
22330     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
22331     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
22332
22333     return 0
22334 }
22335 run_test 423 "statfs should return a right data"
22336
22337 prep_801() {
22338         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
22339         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
22340                 skip "Need server version at least 2.9.55"
22341
22342         start_full_debug_logging
22343 }
22344
22345 post_801() {
22346         stop_full_debug_logging
22347 }
22348
22349 barrier_stat() {
22350         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
22351                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
22352                            awk '/The barrier for/ { print $7 }')
22353                 echo $st
22354         else
22355                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
22356                 echo \'$st\'
22357         fi
22358 }
22359
22360 barrier_expired() {
22361         local expired
22362
22363         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
22364                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
22365                           awk '/will be expired/ { print $7 }')
22366         else
22367                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
22368         fi
22369
22370         echo $expired
22371 }
22372
22373 test_801a() {
22374         prep_801
22375
22376         echo "Start barrier_freeze at: $(date)"
22377         #define OBD_FAIL_BARRIER_DELAY          0x2202
22378         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
22379         # Do not reduce barrier time - See LU-11873
22380         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
22381
22382         sleep 2
22383         local b_status=$(barrier_stat)
22384         echo "Got barrier status at: $(date)"
22385         [ "$b_status" = "'freezing_p1'" ] ||
22386                 error "(1) unexpected barrier status $b_status"
22387
22388         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
22389         wait
22390         b_status=$(barrier_stat)
22391         [ "$b_status" = "'frozen'" ] ||
22392                 error "(2) unexpected barrier status $b_status"
22393
22394         local expired=$(barrier_expired)
22395         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
22396         sleep $((expired + 3))
22397
22398         b_status=$(barrier_stat)
22399         [ "$b_status" = "'expired'" ] ||
22400                 error "(3) unexpected barrier status $b_status"
22401
22402         # Do not reduce barrier time - See LU-11873
22403         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
22404                 error "(4) fail to freeze barrier"
22405
22406         b_status=$(barrier_stat)
22407         [ "$b_status" = "'frozen'" ] ||
22408                 error "(5) unexpected barrier status $b_status"
22409
22410         echo "Start barrier_thaw at: $(date)"
22411         #define OBD_FAIL_BARRIER_DELAY          0x2202
22412         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
22413         do_facet mgs $LCTL barrier_thaw $FSNAME &
22414
22415         sleep 2
22416         b_status=$(barrier_stat)
22417         echo "Got barrier status at: $(date)"
22418         [ "$b_status" = "'thawing'" ] ||
22419                 error "(6) unexpected barrier status $b_status"
22420
22421         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
22422         wait
22423         b_status=$(barrier_stat)
22424         [ "$b_status" = "'thawed'" ] ||
22425                 error "(7) unexpected barrier status $b_status"
22426
22427         #define OBD_FAIL_BARRIER_FAILURE        0x2203
22428         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
22429         do_facet mgs $LCTL barrier_freeze $FSNAME
22430
22431         b_status=$(barrier_stat)
22432         [ "$b_status" = "'failed'" ] ||
22433                 error "(8) unexpected barrier status $b_status"
22434
22435         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
22436         do_facet mgs $LCTL barrier_thaw $FSNAME
22437
22438         post_801
22439 }
22440 run_test 801a "write barrier user interfaces and stat machine"
22441
22442 test_801b() {
22443         prep_801
22444
22445         mkdir $DIR/$tdir || error "(1) fail to mkdir"
22446         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
22447         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
22448         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
22449         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
22450
22451         cancel_lru_locks mdc
22452
22453         # 180 seconds should be long enough
22454         do_facet mgs $LCTL barrier_freeze $FSNAME 180
22455
22456         local b_status=$(barrier_stat)
22457         [ "$b_status" = "'frozen'" ] ||
22458                 error "(6) unexpected barrier status $b_status"
22459
22460         mkdir $DIR/$tdir/d0/d10 &
22461         mkdir_pid=$!
22462
22463         touch $DIR/$tdir/d1/f13 &
22464         touch_pid=$!
22465
22466         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
22467         ln_pid=$!
22468
22469         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
22470         mv_pid=$!
22471
22472         rm -f $DIR/$tdir/d4/f12 &
22473         rm_pid=$!
22474
22475         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
22476
22477         # To guarantee taht the 'stat' is not blocked
22478         b_status=$(barrier_stat)
22479         [ "$b_status" = "'frozen'" ] ||
22480                 error "(8) unexpected barrier status $b_status"
22481
22482         # let above commands to run at background
22483         sleep 5
22484
22485         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
22486         ps -p $touch_pid || error "(10) touch should be blocked"
22487         ps -p $ln_pid || error "(11) link should be blocked"
22488         ps -p $mv_pid || error "(12) rename should be blocked"
22489         ps -p $rm_pid || error "(13) unlink should be blocked"
22490
22491         b_status=$(barrier_stat)
22492         [ "$b_status" = "'frozen'" ] ||
22493                 error "(14) unexpected barrier status $b_status"
22494
22495         do_facet mgs $LCTL barrier_thaw $FSNAME
22496         b_status=$(barrier_stat)
22497         [ "$b_status" = "'thawed'" ] ||
22498                 error "(15) unexpected barrier status $b_status"
22499
22500         wait $mkdir_pid || error "(16) mkdir should succeed"
22501         wait $touch_pid || error "(17) touch should succeed"
22502         wait $ln_pid || error "(18) link should succeed"
22503         wait $mv_pid || error "(19) rename should succeed"
22504         wait $rm_pid || error "(20) unlink should succeed"
22505
22506         post_801
22507 }
22508 run_test 801b "modification will be blocked by write barrier"
22509
22510 test_801c() {
22511         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
22512
22513         prep_801
22514
22515         stop mds2 || error "(1) Fail to stop mds2"
22516
22517         do_facet mgs $LCTL barrier_freeze $FSNAME 30
22518
22519         local b_status=$(barrier_stat)
22520         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
22521                 do_facet mgs $LCTL barrier_thaw $FSNAME
22522                 error "(2) unexpected barrier status $b_status"
22523         }
22524
22525         do_facet mgs $LCTL barrier_rescan $FSNAME ||
22526                 error "(3) Fail to rescan barrier bitmap"
22527
22528         # Do not reduce barrier time - See LU-11873
22529         do_facet mgs $LCTL barrier_freeze $FSNAME 20
22530
22531         b_status=$(barrier_stat)
22532         [ "$b_status" = "'frozen'" ] ||
22533                 error "(4) unexpected barrier status $b_status"
22534
22535         do_facet mgs $LCTL barrier_thaw $FSNAME
22536         b_status=$(barrier_stat)
22537         [ "$b_status" = "'thawed'" ] ||
22538                 error "(5) unexpected barrier status $b_status"
22539
22540         local devname=$(mdsdevname 2)
22541
22542         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
22543
22544         do_facet mgs $LCTL barrier_rescan $FSNAME ||
22545                 error "(7) Fail to rescan barrier bitmap"
22546
22547         post_801
22548 }
22549 run_test 801c "rescan barrier bitmap"
22550
22551 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
22552 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
22553 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
22554 saved_MOUNT_OPTS=$MOUNT_OPTS
22555
22556 cleanup_802a() {
22557         trap 0
22558
22559         stopall
22560         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
22561         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
22562         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
22563         MOUNT_OPTS=$saved_MOUNT_OPTS
22564         setupall
22565 }
22566
22567 test_802a() {
22568         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
22569         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
22570         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
22571                 skip "Need server version at least 2.9.55"
22572
22573         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
22574
22575         mkdir $DIR/$tdir || error "(1) fail to mkdir"
22576
22577         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
22578                 error "(2) Fail to copy"
22579
22580         trap cleanup_802a EXIT
22581
22582         # sync by force before remount as readonly
22583         sync; sync_all_data; sleep 3; sync_all_data
22584
22585         stopall
22586
22587         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
22588         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
22589         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
22590
22591         echo "Mount the server as read only"
22592         setupall server_only || error "(3) Fail to start servers"
22593
22594         echo "Mount client without ro should fail"
22595         mount_client $MOUNT &&
22596                 error "(4) Mount client without 'ro' should fail"
22597
22598         echo "Mount client with ro should succeed"
22599         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
22600         mount_client $MOUNT ||
22601                 error "(5) Mount client with 'ro' should succeed"
22602
22603         echo "Modify should be refused"
22604         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
22605
22606         echo "Read should be allowed"
22607         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
22608                 error "(7) Read should succeed under ro mode"
22609
22610         cleanup_802a
22611 }
22612 run_test 802a "simulate readonly device"
22613
22614 test_802b() {
22615         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22616         remote_mds_nodsh && skip "remote MDS with nodsh"
22617
22618         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
22619                 skip "readonly option not available"
22620
22621         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
22622
22623         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
22624                 error "(2) Fail to copy"
22625
22626         # write back all cached data before setting MDT to readonly
22627         cancel_lru_locks
22628         sync_all_data
22629
22630         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
22631         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
22632
22633         echo "Modify should be refused"
22634         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
22635
22636         echo "Read should be allowed"
22637         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
22638                 error "(7) Read should succeed under ro mode"
22639
22640         # disable readonly
22641         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
22642 }
22643 run_test 802b "be able to set MDTs to readonly"
22644
22645 test_803() {
22646         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
22647         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
22648                 skip "MDS needs to be newer than 2.10.54"
22649
22650         mkdir -p $DIR/$tdir
22651         # Create some objects on all MDTs to trigger related logs objects
22652         for idx in $(seq $MDSCOUNT); do
22653                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
22654                         $DIR/$tdir/dir${idx} ||
22655                         error "Fail to create $DIR/$tdir/dir${idx}"
22656         done
22657
22658         sync; sleep 3
22659         wait_delete_completed # ensure old test cleanups are finished
22660         echo "before create:"
22661         $LFS df -i $MOUNT
22662         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
22663
22664         for i in {1..10}; do
22665                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
22666                         error "Fail to create $DIR/$tdir/foo$i"
22667         done
22668
22669         sync; sleep 3
22670         echo "after create:"
22671         $LFS df -i $MOUNT
22672         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
22673
22674         # allow for an llog to be cleaned up during the test
22675         [ $after_used -ge $((before_used + 10 - 1)) ] ||
22676                 error "before ($before_used) + 10 > after ($after_used)"
22677
22678         for i in {1..10}; do
22679                 rm -rf $DIR/$tdir/foo$i ||
22680                         error "Fail to remove $DIR/$tdir/foo$i"
22681         done
22682
22683         sleep 3 # avoid MDT return cached statfs
22684         wait_delete_completed
22685         echo "after unlink:"
22686         $LFS df -i $MOUNT
22687         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
22688
22689         # allow for an llog to be created during the test
22690         [ $after_used -le $((before_used + 1)) ] ||
22691                 error "after ($after_used) > before ($before_used) + 1"
22692 }
22693 run_test 803 "verify agent object for remote object"
22694
22695 test_804() {
22696         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
22697         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
22698                 skip "MDS needs to be newer than 2.10.54"
22699         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
22700
22701         mkdir -p $DIR/$tdir
22702         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
22703                 error "Fail to create $DIR/$tdir/dir0"
22704
22705         local fid=$($LFS path2fid $DIR/$tdir/dir0)
22706         local dev=$(mdsdevname 2)
22707
22708         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
22709                 grep ${fid} || error "NOT found agent entry for dir0"
22710
22711         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
22712                 error "Fail to create $DIR/$tdir/dir1"
22713
22714         touch $DIR/$tdir/dir1/foo0 ||
22715                 error "Fail to create $DIR/$tdir/dir1/foo0"
22716         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
22717         local rc=0
22718
22719         for idx in $(seq $MDSCOUNT); do
22720                 dev=$(mdsdevname $idx)
22721                 do_facet mds${idx} \
22722                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
22723                         grep ${fid} && rc=$idx
22724         done
22725
22726         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
22727                 error "Fail to rename foo0 to foo1"
22728         if [ $rc -eq 0 ]; then
22729                 for idx in $(seq $MDSCOUNT); do
22730                         dev=$(mdsdevname $idx)
22731                         do_facet mds${idx} \
22732                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
22733                         grep ${fid} && rc=$idx
22734                 done
22735         fi
22736
22737         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
22738                 error "Fail to rename foo1 to foo2"
22739         if [ $rc -eq 0 ]; then
22740                 for idx in $(seq $MDSCOUNT); do
22741                         dev=$(mdsdevname $idx)
22742                         do_facet mds${idx} \
22743                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
22744                         grep ${fid} && rc=$idx
22745                 done
22746         fi
22747
22748         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
22749
22750         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
22751                 error "Fail to link to $DIR/$tdir/dir1/foo2"
22752         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
22753                 error "Fail to rename foo2 to foo0"
22754         unlink $DIR/$tdir/dir1/foo0 ||
22755                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
22756         rm -rf $DIR/$tdir/dir0 ||
22757                 error "Fail to rm $DIR/$tdir/dir0"
22758
22759         for idx in $(seq $MDSCOUNT); do
22760                 dev=$(mdsdevname $idx)
22761                 rc=0
22762
22763                 stop mds${idx}
22764                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
22765                         rc=$?
22766                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
22767                         error "mount mds$idx failed"
22768                 df $MOUNT > /dev/null 2>&1
22769
22770                 # e2fsck should not return error
22771                 [ $rc -eq 0 ] ||
22772                         error "e2fsck detected error on MDT${idx}: rc=$rc"
22773         done
22774 }
22775 run_test 804 "verify agent entry for remote entry"
22776
22777 cleanup_805() {
22778         do_facet $SINGLEMDS zfs set quota=$old $fsset
22779         unlinkmany $DIR/$tdir/f- 1000000
22780         trap 0
22781 }
22782
22783 test_805() {
22784         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
22785         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
22786         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
22787                 skip "netfree not implemented before 0.7"
22788         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
22789                 skip "Need MDS version at least 2.10.57"
22790
22791         local fsset
22792         local freekb
22793         local usedkb
22794         local old
22795         local quota
22796         local pref="osd-zfs.$FSNAME-MDT0000."
22797
22798         # limit available space on MDS dataset to meet nospace issue
22799         # quickly. then ZFS 0.7.2 can use reserved space if asked
22800         # properly (using netfree flag in osd_declare_destroy()
22801         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
22802         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
22803                 gawk '{print $3}')
22804         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
22805         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
22806         let "usedkb=usedkb-freekb"
22807         let "freekb=freekb/2"
22808         if let "freekb > 5000"; then
22809                 let "freekb=5000"
22810         fi
22811         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
22812         trap cleanup_805 EXIT
22813         mkdir $DIR/$tdir
22814         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
22815                 error "Can't set PFL layout"
22816         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
22817         rm -rf $DIR/$tdir || error "not able to remove"
22818         do_facet $SINGLEMDS zfs set quota=$old $fsset
22819         trap 0
22820 }
22821 run_test 805 "ZFS can remove from full fs"
22822
22823 # Size-on-MDS test
22824 check_lsom_data()
22825 {
22826         local file=$1
22827         local size=$($LFS getsom -s $file)
22828         local expect=$(stat -c %s $file)
22829
22830         [[ $size == $expect ]] ||
22831                 error "$file expected size: $expect, got: $size"
22832
22833         local blocks=$($LFS getsom -b $file)
22834         expect=$(stat -c %b $file)
22835         [[ $blocks == $expect ]] ||
22836                 error "$file expected blocks: $expect, got: $blocks"
22837 }
22838
22839 check_lsom_size()
22840 {
22841         local size=$($LFS getsom -s $1)
22842         local expect=$2
22843
22844         [[ $size == $expect ]] ||
22845                 error "$file expected size: $expect, got: $size"
22846 }
22847
22848 test_806() {
22849         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22850                 skip "Need MDS version at least 2.11.52"
22851
22852         local bs=1048576
22853
22854         touch $DIR/$tfile || error "touch $tfile failed"
22855
22856         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22857         save_lustre_params client "llite.*.xattr_cache" > $save
22858         lctl set_param llite.*.xattr_cache=0
22859         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22860
22861         # single-threaded write
22862         echo "Test SOM for single-threaded write"
22863         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
22864                 error "write $tfile failed"
22865         check_lsom_size $DIR/$tfile $bs
22866
22867         local num=32
22868         local size=$(($num * $bs))
22869         local offset=0
22870         local i
22871
22872         echo "Test SOM for single client multi-threaded($num) write"
22873         $TRUNCATE $DIR/$tfile 0
22874         for ((i = 0; i < $num; i++)); do
22875                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
22876                 local pids[$i]=$!
22877                 offset=$((offset + $bs))
22878         done
22879         for (( i=0; i < $num; i++ )); do
22880                 wait ${pids[$i]}
22881         done
22882         check_lsom_size $DIR/$tfile $size
22883
22884         $TRUNCATE $DIR/$tfile 0
22885         for ((i = 0; i < $num; i++)); do
22886                 offset=$((offset - $bs))
22887                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
22888                 local pids[$i]=$!
22889         done
22890         for (( i=0; i < $num; i++ )); do
22891                 wait ${pids[$i]}
22892         done
22893         check_lsom_size $DIR/$tfile $size
22894
22895         # multi-client writes
22896         num=$(get_node_count ${CLIENTS//,/ })
22897         size=$(($num * $bs))
22898         offset=0
22899         i=0
22900
22901         echo "Test SOM for multi-client ($num) writes"
22902         $TRUNCATE $DIR/$tfile 0
22903         for client in ${CLIENTS//,/ }; do
22904                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
22905                 local pids[$i]=$!
22906                 i=$((i + 1))
22907                 offset=$((offset + $bs))
22908         done
22909         for (( i=0; i < $num; i++ )); do
22910                 wait ${pids[$i]}
22911         done
22912         check_lsom_size $DIR/$tfile $offset
22913
22914         i=0
22915         $TRUNCATE $DIR/$tfile 0
22916         for client in ${CLIENTS//,/ }; do
22917                 offset=$((offset - $bs))
22918                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
22919                 local pids[$i]=$!
22920                 i=$((i + 1))
22921         done
22922         for (( i=0; i < $num; i++ )); do
22923                 wait ${pids[$i]}
22924         done
22925         check_lsom_size $DIR/$tfile $size
22926
22927         # verify truncate
22928         echo "Test SOM for truncate"
22929         $TRUNCATE $DIR/$tfile 1048576
22930         check_lsom_size $DIR/$tfile 1048576
22931         $TRUNCATE $DIR/$tfile 1234
22932         check_lsom_size $DIR/$tfile 1234
22933
22934         # verify SOM blocks count
22935         echo "Verify SOM block count"
22936         $TRUNCATE $DIR/$tfile 0
22937         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
22938                 error "failed to write file $tfile"
22939         check_lsom_data $DIR/$tfile
22940 }
22941 run_test 806 "Verify Lazy Size on MDS"
22942
22943 test_807() {
22944         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
22945         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22946                 skip "Need MDS version at least 2.11.52"
22947
22948         # Registration step
22949         changelog_register || error "changelog_register failed"
22950         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
22951         changelog_users $SINGLEMDS | grep -q $cl_user ||
22952                 error "User $cl_user not found in changelog_users"
22953
22954         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22955         save_lustre_params client "llite.*.xattr_cache" > $save
22956         lctl set_param llite.*.xattr_cache=0
22957         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22958
22959         rm -rf $DIR/$tdir || error "rm $tdir failed"
22960         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
22961         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
22962         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
22963         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
22964                 error "truncate $tdir/trunc failed"
22965
22966         local bs=1048576
22967         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
22968                 error "write $tfile failed"
22969
22970         # multi-client wirtes
22971         local num=$(get_node_count ${CLIENTS//,/ })
22972         local offset=0
22973         local i=0
22974
22975         echo "Test SOM for multi-client ($num) writes"
22976         touch $DIR/$tfile || error "touch $tfile failed"
22977         $TRUNCATE $DIR/$tfile 0
22978         for client in ${CLIENTS//,/ }; do
22979                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
22980                 local pids[$i]=$!
22981                 i=$((i + 1))
22982                 offset=$((offset + $bs))
22983         done
22984         for (( i=0; i < $num; i++ )); do
22985                 wait ${pids[$i]}
22986         done
22987
22988         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
22989         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
22990         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
22991         check_lsom_data $DIR/$tdir/trunc
22992         check_lsom_data $DIR/$tdir/single_dd
22993         check_lsom_data $DIR/$tfile
22994
22995         rm -rf $DIR/$tdir
22996         # Deregistration step
22997         changelog_deregister || error "changelog_deregister failed"
22998 }
22999 run_test 807 "verify LSOM syncing tool"
23000
23001 check_som_nologged()
23002 {
23003         local lines=$($LFS changelog $FSNAME-MDT0000 |
23004                 grep 'x=trusted.som' | wc -l)
23005         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
23006 }
23007
23008 test_808() {
23009         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
23010                 skip "Need MDS version at least 2.11.55"
23011
23012         # Registration step
23013         changelog_register || error "changelog_register failed"
23014
23015         touch $DIR/$tfile || error "touch $tfile failed"
23016         check_som_nologged
23017
23018         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
23019                 error "write $tfile failed"
23020         check_som_nologged
23021
23022         $TRUNCATE $DIR/$tfile 1234
23023         check_som_nologged
23024
23025         $TRUNCATE $DIR/$tfile 1048576
23026         check_som_nologged
23027
23028         # Deregistration step
23029         changelog_deregister || error "changelog_deregister failed"
23030 }
23031 run_test 808 "Check trusted.som xattr not logged in Changelogs"
23032
23033 check_som_nodata()
23034 {
23035         $LFS getsom $1
23036         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
23037 }
23038
23039 test_809() {
23040         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
23041                 skip "Need MDS version at least 2.11.56"
23042
23043         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
23044                 error "failed to create DoM-only file $DIR/$tfile"
23045         touch $DIR/$tfile || error "touch $tfile failed"
23046         check_som_nodata $DIR/$tfile
23047
23048         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
23049                 error "write $tfile failed"
23050         check_som_nodata $DIR/$tfile
23051
23052         $TRUNCATE $DIR/$tfile 1234
23053         check_som_nodata $DIR/$tfile
23054
23055         $TRUNCATE $DIR/$tfile 4097
23056         check_som_nodata $DIR/$file
23057 }
23058 run_test 809 "Verify no SOM xattr store for DoM-only files"
23059
23060 test_810() {
23061         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23062         $GSS && skip_env "could not run with gss"
23063         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
23064                 skip "OST < 2.12.58 doesn't align checksum"
23065
23066         set_checksums 1
23067         stack_trap "set_checksums $ORIG_CSUM" EXIT
23068         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
23069
23070         local csum
23071         local before
23072         local after
23073         for csum in $CKSUM_TYPES; do
23074                 #define OBD_FAIL_OSC_NO_GRANT   0x411
23075                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
23076                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
23077                         eval set -- $i
23078                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
23079                         before=$(md5sum $DIR/$tfile)
23080                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
23081                         after=$(md5sum $DIR/$tfile)
23082                         [ "$before" == "$after" ] ||
23083                                 error "$csum: $before != $after bs=$1 seek=$2"
23084                 done
23085         done
23086 }
23087 run_test 810 "partial page writes on ZFS (LU-11663)"
23088
23089 test_812a() {
23090         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
23091                 skip "OST < 2.12.51 doesn't support this fail_loc"
23092         [ "$SHARED_KEY" = true ] &&
23093                 skip "OSC connections never go IDLE with Shared-Keys enabled"
23094
23095         $LFS setstripe -c 1 -i 0 $DIR/$tfile
23096         # ensure ost1 is connected
23097         stat $DIR/$tfile >/dev/null || error "can't stat"
23098         wait_osc_import_state client ost1 FULL
23099         # no locks, no reqs to let the connection idle
23100         cancel_lru_locks osc
23101
23102         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
23103 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
23104         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
23105         wait_osc_import_state client ost1 CONNECTING
23106         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
23107
23108         stat $DIR/$tfile >/dev/null || error "can't stat file"
23109 }
23110 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
23111
23112 test_812b() { # LU-12378
23113         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
23114                 skip "OST < 2.12.51 doesn't support this fail_loc"
23115         [ "$SHARED_KEY" = true ] &&
23116                 skip "OSC connections never go IDLE with Shared-Keys enabled"
23117
23118         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
23119         # ensure ost1 is connected
23120         stat $DIR/$tfile >/dev/null || error "can't stat"
23121         wait_osc_import_state client ost1 FULL
23122         # no locks, no reqs to let the connection idle
23123         cancel_lru_locks osc
23124
23125         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
23126 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
23127         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
23128         wait_osc_import_state client ost1 CONNECTING
23129         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
23130
23131         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
23132         wait_osc_import_state client ost1 IDLE
23133 }
23134 run_test 812b "do not drop no resend request for idle connect"
23135
23136 test_813() {
23137         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
23138         [ -z "$file_heat_sav" ] && skip "no file heat support"
23139
23140         local readsample
23141         local writesample
23142         local readbyte
23143         local writebyte
23144         local readsample1
23145         local writesample1
23146         local readbyte1
23147         local writebyte1
23148
23149         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
23150         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
23151
23152         $LCTL set_param -n llite.*.file_heat=1
23153         echo "Turn on file heat"
23154         echo "Period second: $period_second, Decay percentage: $decay_pct"
23155
23156         echo "QQQQ" > $DIR/$tfile
23157         echo "QQQQ" > $DIR/$tfile
23158         echo "QQQQ" > $DIR/$tfile
23159         cat $DIR/$tfile > /dev/null
23160         cat $DIR/$tfile > /dev/null
23161         cat $DIR/$tfile > /dev/null
23162         cat $DIR/$tfile > /dev/null
23163
23164         local out=$($LFS heat_get $DIR/$tfile)
23165
23166         $LFS heat_get $DIR/$tfile
23167         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
23168         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
23169         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
23170         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
23171
23172         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
23173         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
23174         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
23175         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
23176
23177         sleep $((period_second + 3))
23178         echo "Sleep $((period_second + 3)) seconds..."
23179         # The recursion formula to calculate the heat of the file f is as
23180         # follow:
23181         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
23182         # Where Hi is the heat value in the period between time points i*I and
23183         # (i+1)*I; Ci is the access count in the period; the symbol P refers
23184         # to the weight of Ci.
23185         out=$($LFS heat_get $DIR/$tfile)
23186         $LFS heat_get $DIR/$tfile
23187         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
23188         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
23189         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
23190         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
23191
23192         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
23193                 error "read sample ($readsample) is wrong"
23194         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
23195                 error "write sample ($writesample) is wrong"
23196         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
23197                 error "read bytes ($readbyte) is wrong"
23198         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
23199                 error "write bytes ($writebyte) is wrong"
23200
23201         echo "QQQQ" > $DIR/$tfile
23202         echo "QQQQ" > $DIR/$tfile
23203         echo "QQQQ" > $DIR/$tfile
23204         cat $DIR/$tfile > /dev/null
23205         cat $DIR/$tfile > /dev/null
23206         cat $DIR/$tfile > /dev/null
23207         cat $DIR/$tfile > /dev/null
23208
23209         sleep $((period_second + 3))
23210         echo "Sleep $((period_second + 3)) seconds..."
23211
23212         out=$($LFS heat_get $DIR/$tfile)
23213         $LFS heat_get $DIR/$tfile
23214         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
23215         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
23216         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
23217         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
23218
23219         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
23220                 4 * $decay_pct) / 100") -eq 1 ] ||
23221                 error "read sample ($readsample1) is wrong"
23222         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
23223                 3 * $decay_pct) / 100") -eq 1 ] ||
23224                 error "write sample ($writesample1) is wrong"
23225         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
23226                 20 * $decay_pct) / 100") -eq 1 ] ||
23227                 error "read bytes ($readbyte1) is wrong"
23228         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
23229                 15 * $decay_pct) / 100") -eq 1 ] ||
23230                 error "write bytes ($writebyte1) is wrong"
23231
23232         echo "Turn off file heat for the file $DIR/$tfile"
23233         $LFS heat_set -o $DIR/$tfile
23234
23235         echo "QQQQ" > $DIR/$tfile
23236         echo "QQQQ" > $DIR/$tfile
23237         echo "QQQQ" > $DIR/$tfile
23238         cat $DIR/$tfile > /dev/null
23239         cat $DIR/$tfile > /dev/null
23240         cat $DIR/$tfile > /dev/null
23241         cat $DIR/$tfile > /dev/null
23242
23243         out=$($LFS heat_get $DIR/$tfile)
23244         $LFS heat_get $DIR/$tfile
23245         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
23246         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
23247         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
23248         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
23249
23250         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
23251         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
23252         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
23253         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
23254
23255         echo "Trun on file heat for the file $DIR/$tfile"
23256         $LFS heat_set -O $DIR/$tfile
23257
23258         echo "QQQQ" > $DIR/$tfile
23259         echo "QQQQ" > $DIR/$tfile
23260         echo "QQQQ" > $DIR/$tfile
23261         cat $DIR/$tfile > /dev/null
23262         cat $DIR/$tfile > /dev/null
23263         cat $DIR/$tfile > /dev/null
23264         cat $DIR/$tfile > /dev/null
23265
23266         out=$($LFS heat_get $DIR/$tfile)
23267         $LFS heat_get $DIR/$tfile
23268         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
23269         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
23270         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
23271         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
23272
23273         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
23274         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
23275         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
23276         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
23277
23278         $LFS heat_set -c $DIR/$tfile
23279         $LCTL set_param -n llite.*.file_heat=0
23280         echo "Turn off file heat support for the Lustre filesystem"
23281
23282         echo "QQQQ" > $DIR/$tfile
23283         echo "QQQQ" > $DIR/$tfile
23284         echo "QQQQ" > $DIR/$tfile
23285         cat $DIR/$tfile > /dev/null
23286         cat $DIR/$tfile > /dev/null
23287         cat $DIR/$tfile > /dev/null
23288         cat $DIR/$tfile > /dev/null
23289
23290         out=$($LFS heat_get $DIR/$tfile)
23291         $LFS heat_get $DIR/$tfile
23292         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
23293         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
23294         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
23295         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
23296
23297         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
23298         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
23299         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
23300         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
23301
23302         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
23303         rm -f $DIR/$tfile
23304 }
23305 run_test 813 "File heat verfication"
23306
23307 test_814()
23308 {
23309         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
23310         echo -n y >> $DIR/$tfile
23311         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
23312         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
23313 }
23314 run_test 814 "sparse cp works as expected (LU-12361)"
23315
23316 test_815()
23317 {
23318         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
23319         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
23320 }
23321 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
23322
23323 test_816() {
23324         [ "$SHARED_KEY" = true ] &&
23325                 skip "OSC connections never go IDLE with Shared-Keys enabled"
23326
23327         $LFS setstripe -c 1 -i 0 $DIR/$tfile
23328         # ensure ost1 is connected
23329         stat $DIR/$tfile >/dev/null || error "can't stat"
23330         wait_osc_import_state client ost1 FULL
23331         # no locks, no reqs to let the connection idle
23332         cancel_lru_locks osc
23333         lru_resize_disable osc
23334         local before
23335         local now
23336         before=$($LCTL get_param -n \
23337                  ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
23338
23339         wait_osc_import_state client ost1 IDLE
23340         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
23341         now=$($LCTL get_param -n \
23342               ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
23343         [ $before == $now ] || error "lru_size changed $before != $now"
23344 }
23345 run_test 816 "do not reset lru_resize on idle reconnect"
23346
23347 cleanup_817() {
23348         umount $tmpdir
23349         exportfs -u localhost:$DIR/nfsexp
23350         rm -rf $DIR/nfsexp
23351 }
23352
23353 test_817() {
23354         systemctl restart nfs-server.service || skip "failed to restart nfsd"
23355
23356         mkdir -p $DIR/nfsexp
23357         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
23358                 error "failed to export nfs"
23359
23360         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
23361         stack_trap cleanup_817 EXIT
23362
23363         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
23364                 error "failed to mount nfs to $tmpdir"
23365
23366         cp /bin/true $tmpdir
23367         $DIR/nfsexp/true || error "failed to execute 'true' command"
23368 }
23369 run_test 817 "nfsd won't cache write lock for exec file"
23370
23371 test_818() {
23372         mkdir $DIR/$tdir
23373         $LFS setstripe -c1 -i0 $DIR/$tfile
23374         $LFS setstripe -c1 -i1 $DIR/$tfile
23375         stop $SINGLEMDS
23376         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
23377         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
23378         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
23379                 error "start $SINGLEMDS failed"
23380         rm -rf $DIR/$tdir
23381 }
23382 run_test 818 "unlink with failed llog"
23383
23384 test_819a() {
23385         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23386         cancel_lru_locks osc
23387         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
23388         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
23389         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
23390         rm -f $TDIR/$tfile
23391 }
23392 run_test 819a "too big niobuf in read"
23393
23394 test_819b() {
23395         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
23396         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
23397         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23398         cancel_lru_locks osc
23399         sleep 1
23400         rm -f $TDIR/$tfile
23401 }
23402 run_test 819b "too big niobuf in write"
23403
23404
23405 function test_820_start_ost() {
23406         sleep 5
23407
23408         for num in $(seq $OSTCOUNT); do
23409                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
23410         done
23411 }
23412
23413 test_820() {
23414         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
23415
23416         mkdir $DIR/$tdir
23417         umount_client $MOUNT || error "umount failed"
23418         for num in $(seq $OSTCOUNT); do
23419                 stop ost$num
23420         done
23421
23422         # mount client with no active OSTs
23423         # so that the client can't initialize max LOV EA size
23424         # from OSC notifications
23425         mount_client $MOUNT || error "mount failed"
23426         # delay OST starting to keep this 0 max EA size for a while
23427         test_820_start_ost &
23428
23429         # create a directory on MDS2
23430         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
23431                 error "Failed to create directory"
23432         # open intent should update default EA size
23433         # see mdc_update_max_ea_from_body()
23434         # notice this is the very first RPC to MDS2
23435         cp /etc/services $DIR/$tdir/mds2 ||
23436                 error "Failed to copy files to mds$n"
23437 }
23438 run_test 820 "update max EA from open intent"
23439
23440 #
23441 # tests that do cleanup/setup should be run at the end
23442 #
23443
23444 test_900() {
23445         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23446         local ls
23447
23448         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
23449         $LCTL set_param fail_loc=0x903
23450
23451         cancel_lru_locks MGC
23452
23453         FAIL_ON_ERROR=true cleanup
23454         FAIL_ON_ERROR=true setup
23455 }
23456 run_test 900 "umount should not race with any mgc requeue thread"
23457
23458 # LUS-6253/LU-11185
23459 test_901() {
23460         local oldc
23461         local newc
23462         local olds
23463         local news
23464         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23465
23466         # some get_param have a bug to handle dot in param name
23467         cancel_lru_locks MGC
23468         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
23469         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
23470         umount_client $MOUNT || error "umount failed"
23471         mount_client $MOUNT || error "mount failed"
23472         cancel_lru_locks MGC
23473         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
23474         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
23475
23476         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
23477         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
23478
23479         return 0
23480 }
23481 run_test 901 "don't leak a mgc lock on client umount"
23482
23483 # LU-13377
23484 test_902() {
23485         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
23486                 skip "client does not have LU-13377 fix"
23487         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
23488         $LCTL set_param fail_loc=0x1415
23489         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23490         cancel_lru_locks osc
23491         rm -f $DIR/$tfile
23492 }
23493 run_test 902 "test short write doesn't hang lustre"
23494
23495 complete $SECONDS
23496 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
23497 check_and_cleanup_lustre
23498 if [ "$I_MOUNTED" != "yes" ]; then
23499         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
23500 fi
23501 exit_status