Whamcloud - gitweb
LU-12826 mdt: limit root to change project state by default
[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_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
35 LUSTRE=${LUSTRE:-$(dirname $0)/..}
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
45 ALWAYS_EXCEPT+=" 407     312 "
46
47 if $SHARED_KEY; then
48         # bug number:    LU-9795 LU-9795 LU-9795 LU-9795 LU-12781
49         ALWAYS_EXCEPT+=" 17n     60a     133g    300f    272a"
50 fi
51
52 selinux_status=$(getenforce)
53 if [ "$selinux_status" != "Disabled" ]; then
54         # bug number:    LU-12469 LU-12469
55         ALWAYS_EXCEPT+=" 230b     230d"
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 LU-4398
63         ALWAYS_EXCEPT+=" 45       317      817"
64 fi
65
66 #                                  5          12          (min)"
67 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 64b 68 71 115 300o"
68
69 if [ "$mds1_FSTYPE" = "zfs" ]; then
70         # bug number for skipped test:
71         ALWAYS_EXCEPT="$ALWAYS_EXCEPT  "
72         #                                               13    (min)"
73         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
74 fi
75
76 # Get the SLES distro version
77 #
78 # Returns a version string that should only be used in comparing
79 # strings returned by version_code()
80 sles_version_code()
81 {
82         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
83
84         # All SuSE Linux versions have one decimal. version_code expects two
85         local sles_version=$version.0
86         version_code $sles_version
87 }
88
89 # Check if we are running on Ubuntu or SLES so we can make decisions on
90 # what tests to run
91 if [ -r /etc/SuSE-release ]; then
92         sles_version=$(sles_version_code)
93         [ $sles_version -lt $(version_code 11.4.0) ] &&
94                 # bug number for skipped test: LU-4341
95                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  170"
96         [ $sles_version -lt $(version_code 12.0.0) ] &&
97                 # bug number for skipped test: LU-3703
98                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  234"
99 elif [ -r /etc/os-release ]; then
100         if grep -qi ubuntu /etc/os-release; then
101                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
102                                                 -e 's/^VERSION=//p' \
103                                                 /etc/os-release |
104                                                 awk '{ print $1 }'))
105
106                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
107                         # bug number for skipped test:
108                         #                LU-10334 LU-10366
109                         ALWAYS_EXCEPT+=" 103a     410"
110                 fi
111         fi
112 fi
113
114 build_test_filter
115 FAIL_ON_ERROR=false
116
117 cleanup() {
118         echo -n "cln.."
119         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
120         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
121 }
122 setup() {
123         echo -n "mnt.."
124         load_modules
125         setupall || exit 10
126         echo "done"
127 }
128
129 check_swap_layouts_support()
130 {
131         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
132                 skip "Does not support layout lock."
133 }
134
135 check_and_setup_lustre
136 DIR=${DIR:-$MOUNT}
137 assert_DIR
138
139 MAXFREE=${MAXFREE:-$((200000 * $OSTCOUNT))}
140
141 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
142 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
143 rm -rf $DIR/[Rdfs][0-9]*
144
145 # $RUNAS_ID may get set incorrectly somewhere else
146 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
147         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
148
149 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
150
151 if [ "${ONLY}" = "MOUNT" ] ; then
152         echo "Lustre is up, please go on"
153         exit
154 fi
155
156 echo "preparing for tests involving mounts"
157 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
158 touch $EXT2_DEV
159 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
160 echo # add a newline after mke2fs.
161
162 umask 077
163
164 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
165 lctl set_param debug=-1 2> /dev/null || true
166 test_0a() {
167         touch $DIR/$tfile
168         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
169         rm $DIR/$tfile
170         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
171 }
172 run_test 0a "touch; rm ====================="
173
174 test_0b() {
175         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
176         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
177 }
178 run_test 0b "chmod 0755 $DIR ============================="
179
180 test_0c() {
181         $LCTL get_param mdc.*.import | grep "state: FULL" ||
182                 error "import not FULL"
183         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
184                 error "bad target"
185 }
186 run_test 0c "check import proc"
187
188 test_0d() { # LU-3397
189         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
190                 skip "proc exports not supported before 2.10.57"
191
192         local mgs_exp="mgs.MGS.exports"
193         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
194         local exp_client_nid
195         local exp_client_version
196         local exp_val
197         local imp_val
198         local temp_imp=$DIR/$tfile.import
199         local temp_exp=$DIR/$tfile.export
200
201         # save mgc import file to $temp_imp
202         $LCTL get_param mgc.*.import | tee $temp_imp
203         # Check if client uuid is found in MGS export
204         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
205                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
206                         $client_uuid ] &&
207                         break;
208         done
209         # save mgs export file to $temp_exp
210         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
211
212         # Compare the value of field "connect_flags"
213         imp_val=$(grep "connect_flags" $temp_imp)
214         exp_val=$(grep "connect_flags" $temp_exp)
215         [ "$exp_val" == "$imp_val" ] ||
216                 error "export flags '$exp_val' != import flags '$imp_val'"
217
218         # Compare the value of client version
219         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
220         exp_val=$(version_code $exp_client_version)
221         imp_val=$CLIENT_VERSION
222         [ "$exp_val" == "$imp_val" ] ||
223                 error "export client version '$exp_val' != '$imp_val'"
224 }
225 run_test 0d "check export proc ============================="
226
227 test_1() {
228         test_mkdir $DIR/$tdir
229         test_mkdir $DIR/$tdir/d2
230         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
231         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
232         rmdir $DIR/$tdir/d2
233         rmdir $DIR/$tdir
234         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
235 }
236 run_test 1 "mkdir; remkdir; rmdir"
237
238 test_2() {
239         test_mkdir $DIR/$tdir
240         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
241         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
242         rm -r $DIR/$tdir
243         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
244 }
245 run_test 2 "mkdir; touch; rmdir; check file"
246
247 test_3() {
248         test_mkdir $DIR/$tdir
249         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
250         touch $DIR/$tdir/$tfile
251         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
252         rm -r $DIR/$tdir
253         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
254 }
255 run_test 3 "mkdir; touch; rmdir; check dir"
256
257 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
258 test_4() {
259         test_mkdir -i 1 $DIR/$tdir
260
261         touch $DIR/$tdir/$tfile ||
262                 error "Create file under remote directory failed"
263
264         rmdir $DIR/$tdir &&
265                 error "Expect error removing in-use dir $DIR/$tdir"
266
267         test -d $DIR/$tdir || error "Remote directory disappeared"
268
269         rm -rf $DIR/$tdir || error "remove remote dir error"
270 }
271 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
272
273 test_5() {
274         test_mkdir $DIR/$tdir
275         test_mkdir $DIR/$tdir/d2
276         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
277         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
278         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
279 }
280 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
281
282 test_6a() {
283         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
284         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
285         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
286                 error "$tfile does not have perm 0666 or UID $UID"
287         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
288         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
289                 error "$tfile should be 0666 and owned by UID $UID"
290 }
291 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
292
293 test_6c() {
294         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
295
296         touch $DIR/$tfile
297         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
298         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
299                 error "$tfile should be owned by UID $RUNAS_ID"
300         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
301         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
302                 error "$tfile should be owned by UID $RUNAS_ID"
303 }
304 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
305
306 test_6e() {
307         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
308
309         touch $DIR/$tfile
310         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
311         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
312                 error "$tfile should be owned by GID $UID"
313         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
314         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
315                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
316 }
317 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
318
319 test_6g() {
320         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
321
322         test_mkdir $DIR/$tdir
323         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
324         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
325         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
326         test_mkdir $DIR/$tdir/d/subdir
327         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
328                 error "$tdir/d/subdir should be GID $RUNAS_GID"
329         if [[ $MDSCOUNT -gt 1 ]]; then
330                 # check remote dir sgid inherite
331                 $LFS mkdir -i 0 $DIR/$tdir.local ||
332                         error "mkdir $tdir.local failed"
333                 chmod g+s $DIR/$tdir.local ||
334                         error "chmod $tdir.local failed"
335                 chgrp $RUNAS_GID $DIR/$tdir.local ||
336                         error "chgrp $tdir.local failed"
337                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
338                         error "mkdir $tdir.remote failed"
339                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
340                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
341                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
342                         error "$tdir.remote should be mode 02755"
343         fi
344 }
345 run_test 6g "verify new dir in sgid dir inherits group"
346
347 test_6h() { # bug 7331
348         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
349
350         touch $DIR/$tfile || error "touch failed"
351         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
352         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
353                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
354         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
355                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
356 }
357 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
358
359 test_7a() {
360         test_mkdir $DIR/$tdir
361         $MCREATE $DIR/$tdir/$tfile
362         chmod 0666 $DIR/$tdir/$tfile
363         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
364                 error "$tdir/$tfile should be mode 0666"
365 }
366 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
367
368 test_7b() {
369         if [ ! -d $DIR/$tdir ]; then
370                 test_mkdir $DIR/$tdir
371         fi
372         $MCREATE $DIR/$tdir/$tfile
373         echo -n foo > $DIR/$tdir/$tfile
374         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
375         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
376 }
377 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
378
379 test_8() {
380         test_mkdir $DIR/$tdir
381         touch $DIR/$tdir/$tfile
382         chmod 0666 $DIR/$tdir/$tfile
383         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
384                 error "$tfile mode not 0666"
385 }
386 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
387
388 test_9() {
389         test_mkdir $DIR/$tdir
390         test_mkdir $DIR/$tdir/d2
391         test_mkdir $DIR/$tdir/d2/d3
392         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
393 }
394 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
395
396 test_10() {
397         test_mkdir $DIR/$tdir
398         test_mkdir $DIR/$tdir/d2
399         touch $DIR/$tdir/d2/$tfile
400         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
401                 error "$tdir/d2/$tfile not a file"
402 }
403 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
404
405 test_11() {
406         test_mkdir $DIR/$tdir
407         test_mkdir $DIR/$tdir/d2
408         chmod 0666 $DIR/$tdir/d2
409         chmod 0705 $DIR/$tdir/d2
410         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
411                 error "$tdir/d2 mode not 0705"
412 }
413 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
414
415 test_12() {
416         test_mkdir $DIR/$tdir
417         touch $DIR/$tdir/$tfile
418         chmod 0666 $DIR/$tdir/$tfile
419         chmod 0654 $DIR/$tdir/$tfile
420         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
421                 error "$tdir/d2 mode not 0654"
422 }
423 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
424
425 test_13() {
426         test_mkdir $DIR/$tdir
427         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
428         >  $DIR/$tdir/$tfile
429         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
430                 error "$tdir/$tfile size not 0 after truncate"
431 }
432 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
433
434 test_14() {
435         test_mkdir $DIR/$tdir
436         touch $DIR/$tdir/$tfile
437         rm $DIR/$tdir/$tfile
438         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
439 }
440 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
441
442 test_15() {
443         test_mkdir $DIR/$tdir
444         touch $DIR/$tdir/$tfile
445         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
446         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
447                 error "$tdir/${tfile_2} not a file after rename"
448         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
449 }
450 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
451
452 test_16() {
453         test_mkdir $DIR/$tdir
454         touch $DIR/$tdir/$tfile
455         rm -rf $DIR/$tdir/$tfile
456         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
457 }
458 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
459
460 test_17a() {
461         test_mkdir $DIR/$tdir
462         touch $DIR/$tdir/$tfile
463         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
464         ls -l $DIR/$tdir
465         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
466                 error "$tdir/l-exist not a symlink"
467         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
468                 error "$tdir/l-exist not referencing a file"
469         rm -f $DIR/$tdir/l-exist
470         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
471 }
472 run_test 17a "symlinks: create, remove (real)"
473
474 test_17b() {
475         test_mkdir $DIR/$tdir
476         ln -s no-such-file $DIR/$tdir/l-dangle
477         ls -l $DIR/$tdir
478         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
479                 error "$tdir/l-dangle not referencing no-such-file"
480         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
481                 error "$tdir/l-dangle not referencing non-existent file"
482         rm -f $DIR/$tdir/l-dangle
483         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
484 }
485 run_test 17b "symlinks: create, remove (dangling)"
486
487 test_17c() { # bug 3440 - don't save failed open RPC for replay
488         test_mkdir $DIR/$tdir
489         ln -s foo $DIR/$tdir/$tfile
490         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
491 }
492 run_test 17c "symlinks: open dangling (should return error)"
493
494 test_17d() {
495         test_mkdir $DIR/$tdir
496         ln -s foo $DIR/$tdir/$tfile
497         touch $DIR/$tdir/$tfile || error "creating to new symlink"
498 }
499 run_test 17d "symlinks: create dangling"
500
501 test_17e() {
502         test_mkdir $DIR/$tdir
503         local foo=$DIR/$tdir/$tfile
504         ln -s $foo $foo || error "create symlink failed"
505         ls -l $foo || error "ls -l failed"
506         ls $foo && error "ls not failed" || true
507 }
508 run_test 17e "symlinks: create recursive symlink (should return error)"
509
510 test_17f() {
511         test_mkdir $DIR/$tdir
512         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
513         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
514         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
515         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
516         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
517         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
518         ls -l  $DIR/$tdir
519 }
520 run_test 17f "symlinks: long and very long symlink name"
521
522 # str_repeat(S, N) generate a string that is string S repeated N times
523 str_repeat() {
524         local s=$1
525         local n=$2
526         local ret=''
527         while [ $((n -= 1)) -ge 0 ]; do
528                 ret=$ret$s
529         done
530         echo $ret
531 }
532
533 # Long symlinks and LU-2241
534 test_17g() {
535         test_mkdir $DIR/$tdir
536         local TESTS="59 60 61 4094 4095"
537
538         # Fix for inode size boundary in 2.1.4
539         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
540                 TESTS="4094 4095"
541
542         # Patch not applied to 2.2 or 2.3 branches
543         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
544         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
545                 TESTS="4094 4095"
546
547         # skip long symlink name for rhel6.5.
548         # rhel6.5 has a limit (PATH_MAX - sizeof(struct filename))
549         grep -q '6.5' /etc/redhat-release &>/dev/null &&
550                 TESTS="59 60 61 4062 4063"
551
552         for i in $TESTS; do
553                 local SYMNAME=$(str_repeat 'x' $i)
554                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
555                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
556         done
557 }
558 run_test 17g "symlinks: really long symlink name and inode boundaries"
559
560 test_17h() { #bug 17378
561         [ $PARALLEL == "yes" ] && skip "skip parallel run"
562         remote_mds_nodsh && skip "remote MDS with nodsh"
563
564         local mdt_idx
565
566         test_mkdir $DIR/$tdir
567         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
568         $LFS setstripe -c -1 $DIR/$tdir
569         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
570         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
571         touch $DIR/$tdir/$tfile || true
572 }
573 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
574
575 test_17i() { #bug 20018
576         [ $PARALLEL == "yes" ] && skip "skip parallel run"
577         remote_mds_nodsh && skip "remote MDS with nodsh"
578
579         local foo=$DIR/$tdir/$tfile
580         local mdt_idx
581
582         test_mkdir -c1 $DIR/$tdir
583         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
584         ln -s $foo $foo || error "create symlink failed"
585 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
586         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
587         ls -l $foo && error "error not detected"
588         return 0
589 }
590 run_test 17i "don't panic on short symlink (should return error)"
591
592 test_17k() { #bug 22301
593         [ $PARALLEL == "yes" ] && skip "skip parallel run"
594         [[ -z "$(which rsync 2>/dev/null)" ]] &&
595                 skip "no rsync command"
596         rsync --help | grep -q xattr ||
597                 skip_env "$(rsync --version | head -n1) does not support xattrs"
598         test_mkdir $DIR/$tdir
599         test_mkdir $DIR/$tdir.new
600         touch $DIR/$tdir/$tfile
601         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
602         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
603                 error "rsync failed with xattrs enabled"
604 }
605 run_test 17k "symlinks: rsync with xattrs enabled"
606
607 test_17l() { # LU-279
608         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
609                 skip "no getfattr command"
610
611         test_mkdir $DIR/$tdir
612         touch $DIR/$tdir/$tfile
613         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
614         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
615                 # -h to not follow symlinks. -m '' to list all the xattrs.
616                 # grep to remove first line: '# file: $path'.
617                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
618                 do
619                         lgetxattr_size_check $path $xattr ||
620                                 error "lgetxattr_size_check $path $xattr failed"
621                 done
622         done
623 }
624 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
625
626 # LU-1540
627 test_17m() {
628         [ $PARALLEL == "yes" ] && skip "skip parallel run"
629         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
630         remote_mds_nodsh && skip "remote MDS with nodsh"
631         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
632         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
633                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
634
635         local short_sym="0123456789"
636         local wdir=$DIR/$tdir
637         local i
638
639         test_mkdir $wdir
640         long_sym=$short_sym
641         # create a long symlink file
642         for ((i = 0; i < 4; ++i)); do
643                 long_sym=${long_sym}${long_sym}
644         done
645
646         echo "create 512 short and long symlink files under $wdir"
647         for ((i = 0; i < 256; ++i)); do
648                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
649                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
650         done
651
652         echo "erase them"
653         rm -f $wdir/*
654         sync
655         wait_delete_completed
656
657         echo "recreate the 512 symlink files with a shorter string"
658         for ((i = 0; i < 512; ++i)); do
659                 # rewrite the symlink file with a shorter string
660                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
661                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
662         done
663
664         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
665         local devname=$(mdsdevname $mds_index)
666
667         echo "stop and checking mds${mds_index}:"
668         # e2fsck should not return error
669         stop mds${mds_index}
670         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
671         rc=$?
672
673         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
674                 error "start mds${mds_index} failed"
675         df $MOUNT > /dev/null 2>&1
676         [ $rc -eq 0 ] ||
677                 error "e2fsck detected error for short/long symlink: rc=$rc"
678         rm -f $wdir/*
679 }
680 run_test 17m "run e2fsck against MDT which contains short/long symlink"
681
682 check_fs_consistency_17n() {
683         local mdt_index
684         local rc=0
685
686         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
687         # so it only check MDT1/MDT2 instead of all of MDTs.
688         for mdt_index in 1 2; do
689                 local devname=$(mdsdevname $mdt_index)
690                 # e2fsck should not return error
691                 stop mds${mdt_index}
692                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
693                         rc=$((rc + $?))
694
695                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
696                         error "mount mds$mdt_index failed"
697                 df $MOUNT > /dev/null 2>&1
698         done
699         return $rc
700 }
701
702 test_17n() {
703         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
704         [ $PARALLEL == "yes" ] && skip "skip parallel run"
705         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
706         remote_mds_nodsh && skip "remote MDS with nodsh"
707         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
708         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
709                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
710
711         local i
712
713         test_mkdir $DIR/$tdir
714         for ((i=0; i<10; i++)); do
715                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
716                         error "create remote dir error $i"
717                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
718                         error "create files under remote dir failed $i"
719         done
720
721         check_fs_consistency_17n ||
722                 error "e2fsck report error after create files under remote dir"
723
724         for ((i = 0; i < 10; i++)); do
725                 rm -rf $DIR/$tdir/remote_dir_${i} ||
726                         error "destroy remote dir error $i"
727         done
728
729         check_fs_consistency_17n ||
730                 error "e2fsck report error after unlink files under remote dir"
731
732         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
733                 skip "lustre < 2.4.50 does not support migrate mv"
734
735         for ((i = 0; i < 10; i++)); do
736                 mkdir -p $DIR/$tdir/remote_dir_${i}
737                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
738                         error "create files under remote dir failed $i"
739                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
740                         error "migrate remote dir error $i"
741         done
742         check_fs_consistency_17n || error "e2fsck report error after migration"
743
744         for ((i = 0; i < 10; i++)); do
745                 rm -rf $DIR/$tdir/remote_dir_${i} ||
746                         error "destroy remote dir error $i"
747         done
748
749         check_fs_consistency_17n || error "e2fsck report error after unlink"
750 }
751 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
752
753 test_17o() {
754         remote_mds_nodsh && skip "remote MDS with nodsh"
755         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
756                 skip "Need MDS version at least 2.3.64"
757
758         local wdir=$DIR/${tdir}o
759         local mdt_index
760         local rc=0
761
762         test_mkdir $wdir
763         touch $wdir/$tfile
764         mdt_index=$($LFS getstripe -m $wdir/$tfile)
765         mdt_index=$((mdt_index + 1))
766
767         cancel_lru_locks mdc
768         #fail mds will wait the failover finish then set
769         #following fail_loc to avoid interfer the recovery process.
770         fail mds${mdt_index}
771
772         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
773         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
774         ls -l $wdir/$tfile && rc=1
775         do_facet mds${mdt_index} lctl set_param fail_loc=0
776         [[ $rc -eq 0 ]] || error "stat file should fail"
777 }
778 run_test 17o "stat file with incompat LMA feature"
779
780 test_18() {
781         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
782         ls $DIR || error "Failed to ls $DIR: $?"
783 }
784 run_test 18 "touch .../f ; ls ... =============================="
785
786 test_19a() {
787         touch $DIR/$tfile
788         ls -l $DIR
789         rm $DIR/$tfile
790         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
791 }
792 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
793
794 test_19b() {
795         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
796 }
797 run_test 19b "ls -l .../f19 (should return error) =============="
798
799 test_19c() {
800         [ $RUNAS_ID -eq $UID ] &&
801                 skip_env "RUNAS_ID = UID = $UID -- skipping"
802
803         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
804 }
805 run_test 19c "$RUNAS touch .../f19 (should return error) =="
806
807 test_19d() {
808         cat $DIR/f19 && error || true
809 }
810 run_test 19d "cat .../f19 (should return error) =============="
811
812 test_20() {
813         touch $DIR/$tfile
814         rm $DIR/$tfile
815         touch $DIR/$tfile
816         rm $DIR/$tfile
817         touch $DIR/$tfile
818         rm $DIR/$tfile
819         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
820 }
821 run_test 20 "touch .../f ; ls -l ..."
822
823 test_21() {
824         test_mkdir $DIR/$tdir
825         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
826         ln -s dangle $DIR/$tdir/link
827         echo foo >> $DIR/$tdir/link
828         cat $DIR/$tdir/dangle
829         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
830         $CHECKSTAT -f -t file $DIR/$tdir/link ||
831                 error "$tdir/link not linked to a file"
832 }
833 run_test 21 "write to dangling link"
834
835 test_22() {
836         local wdir=$DIR/$tdir
837         test_mkdir $wdir
838         chown $RUNAS_ID:$RUNAS_GID $wdir
839         (cd $wdir || error "cd $wdir failed";
840                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
841                 $RUNAS tar xf -)
842         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
843         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
844         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
845                 error "checkstat -u failed"
846 }
847 run_test 22 "unpack tar archive as non-root user"
848
849 # was test_23
850 test_23a() {
851         test_mkdir $DIR/$tdir
852         local file=$DIR/$tdir/$tfile
853
854         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
855         openfile -f O_CREAT:O_EXCL $file &&
856                 error "$file recreate succeeded" || true
857 }
858 run_test 23a "O_CREAT|O_EXCL in subdir"
859
860 test_23b() { # bug 18988
861         test_mkdir $DIR/$tdir
862         local file=$DIR/$tdir/$tfile
863
864         rm -f $file
865         echo foo > $file || error "write filed"
866         echo bar >> $file || error "append filed"
867         $CHECKSTAT -s 8 $file || error "wrong size"
868         rm $file
869 }
870 run_test 23b "O_APPEND check"
871
872 # LU-9409, size with O_APPEND and tiny writes
873 test_23c() {
874         local file=$DIR/$tfile
875
876         # single dd
877         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
878         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
879         rm -f $file
880
881         # racing tiny writes
882         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
883         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
884         wait
885         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
886         rm -f $file
887
888         #racing tiny & normal writes
889         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
890         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
891         wait
892         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
893         rm -f $file
894
895         #racing tiny & normal writes 2, ugly numbers
896         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
897         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
898         wait
899         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
900         rm -f $file
901 }
902 run_test 23c "O_APPEND size checks for tiny writes"
903
904 # LU-11069 file offset is correct after appending writes
905 test_23d() {
906         local file=$DIR/$tfile
907         local offset
908
909         echo CentaurHauls > $file
910         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
911         if ((offset != 26)); then
912                 error "wrong offset, expected 26, got '$offset'"
913         fi
914 }
915 run_test 23d "file offset is correct after appending writes"
916
917 # rename sanity
918 test_24a() {
919         echo '-- same directory rename'
920         test_mkdir $DIR/$tdir
921         touch $DIR/$tdir/$tfile.1
922         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
923         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
924 }
925 run_test 24a "rename file to non-existent target"
926
927 test_24b() {
928         test_mkdir $DIR/$tdir
929         touch $DIR/$tdir/$tfile.{1,2}
930         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
931         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
932         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
933 }
934 run_test 24b "rename file to existing target"
935
936 test_24c() {
937         test_mkdir $DIR/$tdir
938         test_mkdir $DIR/$tdir/d$testnum.1
939         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
940         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
941         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
942 }
943 run_test 24c "rename directory to non-existent target"
944
945 test_24d() {
946         test_mkdir -c1 $DIR/$tdir
947         test_mkdir -c1 $DIR/$tdir/d$testnum.1
948         test_mkdir -c1 $DIR/$tdir/d$testnum.2
949         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
950         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
951         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
952 }
953 run_test 24d "rename directory to existing target"
954
955 test_24e() {
956         echo '-- cross directory renames --'
957         test_mkdir $DIR/R5a
958         test_mkdir $DIR/R5b
959         touch $DIR/R5a/f
960         mv $DIR/R5a/f $DIR/R5b/g
961         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
962         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
963 }
964 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
965
966 test_24f() {
967         test_mkdir $DIR/R6a
968         test_mkdir $DIR/R6b
969         touch $DIR/R6a/f $DIR/R6b/g
970         mv $DIR/R6a/f $DIR/R6b/g
971         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
972         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
973 }
974 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
975
976 test_24g() {
977         test_mkdir $DIR/R7a
978         test_mkdir $DIR/R7b
979         test_mkdir $DIR/R7a/d
980         mv $DIR/R7a/d $DIR/R7b/e
981         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
982         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
983 }
984 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
985
986 test_24h() {
987         test_mkdir -c1 $DIR/R8a
988         test_mkdir -c1 $DIR/R8b
989         test_mkdir -c1 $DIR/R8a/d
990         test_mkdir -c1 $DIR/R8b/e
991         mrename $DIR/R8a/d $DIR/R8b/e
992         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
993         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
994 }
995 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
996
997 test_24i() {
998         echo "-- rename error cases"
999         test_mkdir $DIR/R9
1000         test_mkdir $DIR/R9/a
1001         touch $DIR/R9/f
1002         mrename $DIR/R9/f $DIR/R9/a
1003         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1004         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1005         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1006 }
1007 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1008
1009 test_24j() {
1010         test_mkdir $DIR/R10
1011         mrename $DIR/R10/f $DIR/R10/g
1012         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1013         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1014         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1015 }
1016 run_test 24j "source does not exist ============================"
1017
1018 test_24k() {
1019         test_mkdir $DIR/R11a
1020         test_mkdir $DIR/R11a/d
1021         touch $DIR/R11a/f
1022         mv $DIR/R11a/f $DIR/R11a/d
1023         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1024         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1025 }
1026 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1027
1028 # bug 2429 - rename foo foo foo creates invalid file
1029 test_24l() {
1030         f="$DIR/f24l"
1031         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1032 }
1033 run_test 24l "Renaming a file to itself ========================"
1034
1035 test_24m() {
1036         f="$DIR/f24m"
1037         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1038         # on ext3 this does not remove either the source or target files
1039         # though the "expected" operation would be to remove the source
1040         $CHECKSTAT -t file ${f} || error "${f} missing"
1041         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1042 }
1043 run_test 24m "Renaming a file to a hard link to itself ========="
1044
1045 test_24n() {
1046     f="$DIR/f24n"
1047     # this stats the old file after it was renamed, so it should fail
1048     touch ${f}
1049     $CHECKSTAT ${f} || error "${f} missing"
1050     mv ${f} ${f}.rename
1051     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1052     $CHECKSTAT -a ${f} || error "${f} exists"
1053 }
1054 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1055
1056 test_24o() {
1057         test_mkdir $DIR/$tdir
1058         rename_many -s random -v -n 10 $DIR/$tdir
1059 }
1060 run_test 24o "rename of files during htree split"
1061
1062 test_24p() {
1063         test_mkdir $DIR/R12a
1064         test_mkdir $DIR/R12b
1065         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1066         mrename $DIR/R12a $DIR/R12b
1067         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1068         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1069         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1070         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1071 }
1072 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1073
1074 cleanup_multiop_pause() {
1075         trap 0
1076         kill -USR1 $MULTIPID
1077 }
1078
1079 test_24q() {
1080         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1081
1082         test_mkdir $DIR/R13a
1083         test_mkdir $DIR/R13b
1084         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1085         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1086         MULTIPID=$!
1087
1088         trap cleanup_multiop_pause EXIT
1089         mrename $DIR/R13a $DIR/R13b
1090         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1091         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1092         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1093         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1094         cleanup_multiop_pause
1095         wait $MULTIPID || error "multiop close failed"
1096 }
1097 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1098
1099 test_24r() { #bug 3789
1100         test_mkdir $DIR/R14a
1101         test_mkdir $DIR/R14a/b
1102         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1103         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1104         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1105 }
1106 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1107
1108 test_24s() {
1109         test_mkdir $DIR/R15a
1110         test_mkdir $DIR/R15a/b
1111         test_mkdir $DIR/R15a/b/c
1112         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1113         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1114         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1115 }
1116 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1117 test_24t() {
1118         test_mkdir $DIR/R16a
1119         test_mkdir $DIR/R16a/b
1120         test_mkdir $DIR/R16a/b/c
1121         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1122         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1123         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1124 }
1125 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1126
1127 test_24u() { # bug12192
1128         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1129         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1130 }
1131 run_test 24u "create stripe file"
1132
1133 simple_cleanup_common() {
1134         local rc=0
1135         trap 0
1136         [ -z "$DIR" ] || [ -z "$tdir" ] && return 0
1137
1138         local start=$SECONDS
1139         rm -rf $DIR/$tdir
1140         rc=$?
1141         wait_delete_completed
1142         echo "cleanup time $((SECONDS - start))"
1143         return $rc
1144 }
1145
1146 max_pages_per_rpc() {
1147         local mdtname="$(printf "MDT%04x" ${1:-0})"
1148         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1149 }
1150
1151 test_24v() {
1152         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1153
1154         local nrfiles=${COUNT:-100000}
1155         local fname="$DIR/$tdir/$tfile"
1156
1157         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1158         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1159
1160         test_mkdir "$(dirname $fname)"
1161         # assume MDT0000 has the fewest inodes
1162         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1163         local free_inodes=$(($(mdt_free_inodes 0) * stripes))
1164         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1165
1166         trap simple_cleanup_common EXIT
1167
1168         createmany -m "$fname" $nrfiles
1169
1170         cancel_lru_locks mdc
1171         lctl set_param mdc.*.stats clear
1172
1173         # was previously test_24D: LU-6101
1174         # readdir() returns correct number of entries after cursor reload
1175         local num_ls=$(ls $DIR/$tdir | wc -l)
1176         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1177         local num_all=$(ls -a $DIR/$tdir | wc -l)
1178         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1179                 [ $num_all -ne $((nrfiles + 2)) ]; then
1180                         error "Expected $nrfiles files, got $num_ls " \
1181                                 "($num_uniq unique $num_all .&..)"
1182         fi
1183         # LU-5 large readdir
1184         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1185         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1186         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1187         # take into account of overhead in lu_dirpage header and end mark in
1188         # each page, plus one in rpc_num calculation.
1189         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1190         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1191         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1192         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1193         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1194         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1195         echo "readpages: $mds_readpage rpc_max: $rpc_max"
1196         (( $mds_readpage < $rpc_max - 2 || $mds_readpage > $rpc_max + 1)) &&
1197                 error "large readdir doesn't take effect: " \
1198                       "$mds_readpage should be about $rpc_max"
1199
1200         simple_cleanup_common
1201 }
1202 run_test 24v "list large directory (test hash collision, b=17560)"
1203
1204 test_24w() { # bug21506
1205         SZ1=234852
1206         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1207         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1208         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1209         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1210         [[ "$SZ1" -eq "$SZ2" ]] ||
1211                 error "Error reading at the end of the file $tfile"
1212 }
1213 run_test 24w "Reading a file larger than 4Gb"
1214
1215 test_24x() {
1216         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1217         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1218         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1219                 skip "Need MDS version at least 2.7.56"
1220
1221         local MDTIDX=1
1222         local remote_dir=$DIR/$tdir/remote_dir
1223
1224         test_mkdir $DIR/$tdir
1225         $LFS mkdir -i $MDTIDX $remote_dir ||
1226                 error "create remote directory failed"
1227
1228         test_mkdir $DIR/$tdir/src_dir
1229         touch $DIR/$tdir/src_file
1230         test_mkdir $remote_dir/tgt_dir
1231         touch $remote_dir/tgt_file
1232
1233         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1234                 error "rename dir cross MDT failed!"
1235
1236         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1237                 error "rename file cross MDT failed!"
1238
1239         touch $DIR/$tdir/ln_file
1240         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1241                 error "ln file cross MDT failed"
1242
1243         rm -rf $DIR/$tdir || error "Can not delete directories"
1244 }
1245 run_test 24x "cross MDT rename/link"
1246
1247 test_24y() {
1248         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1249         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1250
1251         local remote_dir=$DIR/$tdir/remote_dir
1252         local mdtidx=1
1253
1254         test_mkdir $DIR/$tdir
1255         $LFS mkdir -i $mdtidx $remote_dir ||
1256                 error "create remote directory failed"
1257
1258         test_mkdir $remote_dir/src_dir
1259         touch $remote_dir/src_file
1260         test_mkdir $remote_dir/tgt_dir
1261         touch $remote_dir/tgt_file
1262
1263         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1264                 error "rename subdir in the same remote dir failed!"
1265
1266         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1267                 error "rename files in the same remote dir failed!"
1268
1269         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1270                 error "link files in the same remote dir failed!"
1271
1272         rm -rf $DIR/$tdir || error "Can not delete directories"
1273 }
1274 run_test 24y "rename/link on the same dir should succeed"
1275
1276 test_24z() {
1277         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1278         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1279                 skip "Need MDS version at least 2.12.51"
1280
1281         local index
1282
1283         for index in 0 1; do
1284                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1285                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1286         done
1287
1288         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1289
1290         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1291         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1292
1293         local mdts=$(comma_list $(mdts_nodes))
1294
1295         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1296         stack_trap "do_nodes $mdts $LCTL \
1297                 set_param mdt.*.enable_remote_rename=1" EXIT
1298
1299         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1300
1301         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1302         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1303 }
1304 run_test 24z "cross-MDT rename is done as cp"
1305
1306 test_24A() { # LU-3182
1307         local NFILES=5000
1308
1309         rm -rf $DIR/$tdir
1310         test_mkdir $DIR/$tdir
1311         trap simple_cleanup_common EXIT
1312         createmany -m $DIR/$tdir/$tfile $NFILES
1313         local t=$(ls $DIR/$tdir | wc -l)
1314         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1315         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1316         if [ $t -ne $NFILES ] || [ $u -ne $NFILES ] ||
1317            [ $v -ne $((NFILES + 2)) ] ; then
1318                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1319         fi
1320
1321         simple_cleanup_common || error "Can not delete directories"
1322 }
1323 run_test 24A "readdir() returns correct number of entries."
1324
1325 test_24B() { # LU-4805
1326         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1327
1328         local count
1329
1330         test_mkdir $DIR/$tdir
1331         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1332                 error "create striped dir failed"
1333
1334         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1335         [ $count -eq 2 ] || error "Expected 2, got $count"
1336
1337         touch $DIR/$tdir/striped_dir/a
1338
1339         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1340         [ $count -eq 3 ] || error "Expected 3, got $count"
1341
1342         touch $DIR/$tdir/striped_dir/.f
1343
1344         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1345         [ $count -eq 4 ] || error "Expected 4, got $count"
1346
1347         rm -rf $DIR/$tdir || error "Can not delete directories"
1348 }
1349 run_test 24B "readdir for striped dir return correct number of entries"
1350
1351 test_24C() {
1352         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1353
1354         mkdir $DIR/$tdir
1355         mkdir $DIR/$tdir/d0
1356         mkdir $DIR/$tdir/d1
1357
1358         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1359                 error "create striped dir failed"
1360
1361         cd $DIR/$tdir/d0/striped_dir
1362
1363         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1364         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1365         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1366
1367         [ "$d0_ino" = "$parent_ino" ] ||
1368                 error ".. wrong, expect $d0_ino, get $parent_ino"
1369
1370         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1371                 error "mv striped dir failed"
1372
1373         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1374
1375         [ "$d1_ino" = "$parent_ino" ] ||
1376                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1377 }
1378 run_test 24C "check .. in striped dir"
1379
1380 test_24E() {
1381         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1382         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1383
1384         mkdir -p $DIR/$tdir
1385         mkdir $DIR/$tdir/src_dir
1386         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1387                 error "create remote source failed"
1388
1389         touch $DIR/$tdir/src_dir/src_child/a
1390
1391         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1392                 error "create remote target dir failed"
1393
1394         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1395                 error "create remote target child failed"
1396
1397         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1398                 error "rename dir cross MDT failed!"
1399
1400         find $DIR/$tdir
1401
1402         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1403                 error "src_child still exists after rename"
1404
1405         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1406                 error "missing file(a) after rename"
1407
1408         rm -rf $DIR/$tdir || error "Can not delete directories"
1409 }
1410 run_test 24E "cross MDT rename/link"
1411
1412 test_24F () {
1413         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1414
1415         local repeats=1000
1416         [ "$SLOW" = "no" ] && repeats=100
1417
1418         mkdir -p $DIR/$tdir
1419
1420         echo "$repeats repeats"
1421         for ((i = 0; i < repeats; i++)); do
1422                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1423                 touch $DIR/$tdir/test/a || error "touch fails"
1424                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1425                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1426         done
1427
1428         true
1429 }
1430 run_test 24F "hash order vs readdir (LU-11330)"
1431
1432 test_25a() {
1433         echo '== symlink sanity ============================================='
1434
1435         test_mkdir $DIR/d25
1436         ln -s d25 $DIR/s25
1437         touch $DIR/s25/foo ||
1438                 error "File creation in symlinked directory failed"
1439 }
1440 run_test 25a "create file in symlinked directory ==============="
1441
1442 test_25b() {
1443         [ ! -d $DIR/d25 ] && test_25a
1444         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1445 }
1446 run_test 25b "lookup file in symlinked directory ==============="
1447
1448 test_26a() {
1449         test_mkdir $DIR/d26
1450         test_mkdir $DIR/d26/d26-2
1451         ln -s d26/d26-2 $DIR/s26
1452         touch $DIR/s26/foo || error "File creation failed"
1453 }
1454 run_test 26a "multiple component symlink ======================="
1455
1456 test_26b() {
1457         test_mkdir -p $DIR/$tdir/d26-2
1458         ln -s $tdir/d26-2/foo $DIR/s26-2
1459         touch $DIR/s26-2 || error "File creation failed"
1460 }
1461 run_test 26b "multiple component symlink at end of lookup ======"
1462
1463 test_26c() {
1464         test_mkdir $DIR/d26.2
1465         touch $DIR/d26.2/foo
1466         ln -s d26.2 $DIR/s26.2-1
1467         ln -s s26.2-1 $DIR/s26.2-2
1468         ln -s s26.2-2 $DIR/s26.2-3
1469         chmod 0666 $DIR/s26.2-3/foo
1470 }
1471 run_test 26c "chain of symlinks"
1472
1473 # recursive symlinks (bug 439)
1474 test_26d() {
1475         ln -s d26-3/foo $DIR/d26-3
1476 }
1477 run_test 26d "create multiple component recursive symlink"
1478
1479 test_26e() {
1480         [ ! -h $DIR/d26-3 ] && test_26d
1481         rm $DIR/d26-3
1482 }
1483 run_test 26e "unlink multiple component recursive symlink"
1484
1485 # recursive symlinks (bug 7022)
1486 test_26f() {
1487         test_mkdir $DIR/$tdir
1488         test_mkdir $DIR/$tdir/$tfile
1489         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1490         test_mkdir -p lndir/bar1
1491         test_mkdir $DIR/$tdir/$tfile/$tfile
1492         cd $tfile                || error "cd $tfile failed"
1493         ln -s .. dotdot          || error "ln dotdot failed"
1494         ln -s dotdot/lndir lndir || error "ln lndir failed"
1495         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1496         output=`ls $tfile/$tfile/lndir/bar1`
1497         [ "$output" = bar1 ] && error "unexpected output"
1498         rm -r $tfile             || error "rm $tfile failed"
1499         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1500 }
1501 run_test 26f "rm -r of a directory which has recursive symlink"
1502
1503 test_27a() {
1504         test_mkdir $DIR/$tdir
1505         $LFS getstripe $DIR/$tdir
1506         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1507         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1508         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1509 }
1510 run_test 27a "one stripe file"
1511
1512 test_27b() {
1513         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1514
1515         test_mkdir $DIR/$tdir
1516         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1517         $LFS getstripe -c $DIR/$tdir/$tfile
1518         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1519                 error "two-stripe file doesn't have two stripes"
1520
1521         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1522 }
1523 run_test 27b "create and write to two stripe file"
1524
1525 # 27c family tests specific striping, setstripe -o
1526 test_27ca() {
1527         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1528         test_mkdir -p $DIR/$tdir
1529         local osts="1"
1530
1531         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1532         $LFS getstripe -i $DIR/$tdir/$tfile
1533         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1534                 error "stripe not on specified OST"
1535
1536         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1537 }
1538 run_test 27ca "one stripe on specified OST"
1539
1540 test_27cb() {
1541         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1542         test_mkdir -p $DIR/$tdir
1543         local osts="1,0"
1544         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1545         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1546         echo "$getstripe"
1547
1548         # Strip getstripe output to a space separated list of OSTs
1549         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1550                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1551         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1552                 error "stripes not on specified OSTs"
1553
1554         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1555 }
1556 run_test 27cb "two stripes on specified OSTs"
1557
1558 test_27cc() {
1559         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1560         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1561                 skip "server does not support overstriping"
1562
1563         test_mkdir -p $DIR/$tdir
1564         local osts="0,0"
1565         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1566         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1567         echo "$getstripe"
1568
1569         # Strip getstripe output to a space separated list of OSTs
1570         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1571                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1572         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1573                 error "stripes not on specified OSTs"
1574
1575         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1576 }
1577 run_test 27cc "two stripes on the same OST"
1578
1579 test_27cd() {
1580         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1581         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1582                 skip "server does not support overstriping"
1583         test_mkdir -p $DIR/$tdir
1584         local osts="0,1,1,0"
1585         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1586         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1587         echo "$getstripe"
1588
1589         # Strip getstripe output to a space separated list of OSTs
1590         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1591                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1592         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1593                 error "stripes not on specified OSTs"
1594
1595         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1596 }
1597 run_test 27cd "four stripes on two OSTs"
1598
1599 test_27ce() {
1600         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1601                 skip_env "too many osts, skipping"
1602         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1603                 skip "server does not support overstriping"
1604         # We do one more stripe than we have OSTs
1605         [ $OSTCOUNT -ge 159 ] || large_xattr_enabled ||
1606                 skip_env "ea_inode feature disabled"
1607
1608         test_mkdir -p $DIR/$tdir
1609         local osts=""
1610         for i in $(seq 0 $OSTCOUNT);
1611         do
1612                 osts=$osts"0"
1613                 if [ $i -ne $OSTCOUNT ]; then
1614                         osts=$osts","
1615                 fi
1616         done
1617         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1618         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1619         echo "$getstripe"
1620
1621         # Strip getstripe output to a space separated list of OSTs
1622         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1623                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1624         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1625                 error "stripes not on specified OSTs"
1626
1627         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1628 }
1629 run_test 27ce "more stripes than OSTs with -o"
1630
1631 test_27d() {
1632         test_mkdir $DIR/$tdir
1633         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1634                 error "setstripe failed"
1635         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1636         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1637 }
1638 run_test 27d "create file with default settings"
1639
1640 test_27e() {
1641         # LU-5839 adds check for existed layout before setting it
1642         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1643                 skip "Need MDS version at least 2.7.56"
1644
1645         test_mkdir $DIR/$tdir
1646         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1647         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1648         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1649 }
1650 run_test 27e "setstripe existing file (should return error)"
1651
1652 test_27f() {
1653         test_mkdir $DIR/$tdir
1654         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1655                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1656         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1657                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1658         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1659         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1660 }
1661 run_test 27f "setstripe with bad stripe size (should return error)"
1662
1663 test_27g() {
1664         test_mkdir $DIR/$tdir
1665         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1666         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1667                 error "$DIR/$tdir/$tfile has object"
1668 }
1669 run_test 27g "$LFS getstripe with no objects"
1670
1671 test_27ga() {
1672         test_mkdir $DIR/$tdir
1673         touch $DIR/$tdir/$tfile || error "touch failed"
1674         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1675         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1676         local rc=$?
1677         (( rc == 2 )) || error "getstripe did not return ENOENT"
1678 }
1679 run_test 27ga "$LFS getstripe with missing file (should return error)"
1680
1681 test_27i() {
1682         test_mkdir $DIR/$tdir
1683         touch $DIR/$tdir/$tfile || error "touch failed"
1684         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1685                 error "missing objects"
1686 }
1687 run_test 27i "$LFS getstripe with some objects"
1688
1689 test_27j() {
1690         test_mkdir $DIR/$tdir
1691         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1692                 error "setstripe failed" || true
1693 }
1694 run_test 27j "setstripe with bad stripe offset (should return error)"
1695
1696 test_27k() { # bug 2844
1697         test_mkdir $DIR/$tdir
1698         local file=$DIR/$tdir/$tfile
1699         local ll_max_blksize=$((4 * 1024 * 1024))
1700         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1701         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1702         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1703         dd if=/dev/zero of=$file bs=4k count=1
1704         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1705         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1706 }
1707 run_test 27k "limit i_blksize for broken user apps"
1708
1709 test_27l() {
1710         mcreate $DIR/$tfile || error "creating file"
1711         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1712                 error "setstripe should have failed" || true
1713 }
1714 run_test 27l "check setstripe permissions (should return error)"
1715
1716 test_27m() {
1717         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1718
1719         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1720                 skip_env "multiple clients -- skipping"
1721
1722         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1723                    head -n1)
1724         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1725                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1726         fi
1727         trap simple_cleanup_common EXIT
1728         test_mkdir $DIR/$tdir
1729         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1730         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1731                 error "dd should fill OST0"
1732         i=2
1733         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1734                 i=$((i + 1))
1735                 [ $i -gt 256 ] && break
1736         done
1737         i=$((i + 1))
1738         touch $DIR/$tdir/$tfile.$i
1739         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1740             awk '{print $1}'| grep -w "0") ] &&
1741                 error "OST0 was full but new created file still use it"
1742         i=$((i + 1))
1743         touch $DIR/$tdir/$tfile.$i
1744         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1745             awk '{print $1}'| grep -w "0") ] &&
1746                 error "OST0 was full but new created file still use it"
1747         simple_cleanup_common
1748 }
1749 run_test 27m "create file while OST0 was full"
1750
1751 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1752 # if the OST isn't full anymore.
1753 reset_enospc() {
1754         local OSTIDX=${1:-""}
1755
1756         local list=$(comma_list $(osts_nodes))
1757         [ "$OSTIDX" ] && list=$(facet_host ost$((OSTIDX + 1)))
1758
1759         do_nodes $list lctl set_param fail_loc=0
1760         sync    # initiate all OST_DESTROYs from MDS to OST
1761         sleep_maxage
1762 }
1763
1764 exhaust_precreations() {
1765         local OSTIDX=$1
1766         local FAILLOC=$2
1767         local FAILIDX=${3:-$OSTIDX}
1768         local ofacet=ost$((OSTIDX + 1))
1769
1770         test_mkdir -p -c1 $DIR/$tdir
1771         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
1772         local mfacet=mds$((mdtidx + 1))
1773         echo OSTIDX=$OSTIDX MDTIDX=$mdtidx
1774
1775         local OST=$(ostname_from_index $OSTIDX)
1776
1777         # on the mdt's osc
1778         local mdtosc_proc1=$(get_mdtosc_proc_path $mfacet $OST)
1779         local last_id=$(do_facet $mfacet lctl get_param -n \
1780                         osp.$mdtosc_proc1.prealloc_last_id)
1781         local next_id=$(do_facet $mfacet lctl get_param -n \
1782                         osp.$mdtosc_proc1.prealloc_next_id)
1783
1784         local mdtosc_proc2=$(get_mdtosc_proc_path $mfacet)
1785         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1786
1787         test_mkdir -p $DIR/$tdir/${OST}
1788         $LFS setstripe -i $OSTIDX -c 1 $DIR/$tdir/${OST}
1789 #define OBD_FAIL_OST_ENOSPC              0x215
1790         do_facet $ofacet lctl set_param fail_val=$FAILIDX fail_loc=0x215
1791         echo "Creating to objid $last_id on ost $OST..."
1792         createmany -o $DIR/$tdir/${OST}/f $next_id $((last_id - next_id + 2))
1793         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1794         do_facet $ofacet lctl set_param fail_loc=$FAILLOC
1795         sleep_maxage
1796 }
1797
1798 exhaust_all_precreations() {
1799         local i
1800         for (( i=0; i < OSTCOUNT; i++ )) ; do
1801                 exhaust_precreations $i $1 -1
1802         done
1803 }
1804
1805 test_27n() {
1806         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1807         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1808         remote_mds_nodsh && skip "remote MDS with nodsh"
1809         remote_ost_nodsh && skip "remote OST with nodsh"
1810
1811         reset_enospc
1812         rm -f $DIR/$tdir/$tfile
1813         exhaust_precreations 0 0x80000215
1814         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1815         touch $DIR/$tdir/$tfile || error "touch failed"
1816         $LFS getstripe $DIR/$tdir/$tfile
1817         reset_enospc
1818 }
1819 run_test 27n "create file with some full OSTs"
1820
1821 test_27o() {
1822         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1823         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1824         remote_mds_nodsh && skip "remote MDS with nodsh"
1825         remote_ost_nodsh && skip "remote OST with nodsh"
1826
1827         reset_enospc
1828         rm -f $DIR/$tdir/$tfile
1829         exhaust_all_precreations 0x215
1830
1831         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1832
1833         reset_enospc
1834         rm -rf $DIR/$tdir/*
1835 }
1836 run_test 27o "create file with all full OSTs (should error)"
1837
1838 test_27p() {
1839         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1840         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1841         remote_mds_nodsh && skip "remote MDS with nodsh"
1842         remote_ost_nodsh && skip "remote OST with nodsh"
1843
1844         reset_enospc
1845         rm -f $DIR/$tdir/$tfile
1846         test_mkdir $DIR/$tdir
1847
1848         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1849         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1850         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1851
1852         exhaust_precreations 0 0x80000215
1853         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1854         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1855         $LFS getstripe $DIR/$tdir/$tfile
1856
1857         reset_enospc
1858 }
1859 run_test 27p "append to a truncated file with some full OSTs"
1860
1861 test_27q() {
1862         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1863         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1864         remote_mds_nodsh && skip "remote MDS with nodsh"
1865         remote_ost_nodsh && skip "remote OST with nodsh"
1866
1867         reset_enospc
1868         rm -f $DIR/$tdir/$tfile
1869
1870         test_mkdir $DIR/$tdir
1871         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1872         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1873                 error "truncate $DIR/$tdir/$tfile failed"
1874         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1875
1876         exhaust_all_precreations 0x215
1877
1878         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1879         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1880
1881         reset_enospc
1882 }
1883 run_test 27q "append to truncated file with all OSTs full (should error)"
1884
1885 test_27r() {
1886         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1887         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1888         remote_mds_nodsh && skip "remote MDS with nodsh"
1889         remote_ost_nodsh && skip "remote OST with nodsh"
1890
1891         reset_enospc
1892         rm -f $DIR/$tdir/$tfile
1893         exhaust_precreations 0 0x80000215
1894
1895         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1896
1897         reset_enospc
1898 }
1899 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
1900
1901 test_27s() { # bug 10725
1902         test_mkdir $DIR/$tdir
1903         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
1904         local stripe_count=0
1905         [ $OSTCOUNT -eq 1 ] || stripe_count=2
1906         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
1907                 error "stripe width >= 2^32 succeeded" || true
1908
1909 }
1910 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
1911
1912 test_27t() { # bug 10864
1913         WDIR=$(pwd)
1914         WLFS=$(which lfs)
1915         cd $DIR
1916         touch $tfile
1917         $WLFS getstripe $tfile
1918         cd $WDIR
1919 }
1920 run_test 27t "check that utils parse path correctly"
1921
1922 test_27u() { # bug 4900
1923         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1924         remote_mds_nodsh && skip "remote MDS with nodsh"
1925
1926         local index
1927         local list=$(comma_list $(mdts_nodes))
1928
1929 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
1930         do_nodes $list $LCTL set_param fail_loc=0x139
1931         test_mkdir -p $DIR/$tdir
1932         trap simple_cleanup_common EXIT
1933         createmany -o $DIR/$tdir/t- 1000
1934         do_nodes $list $LCTL set_param fail_loc=0
1935
1936         TLOG=$TMP/$tfile.getstripe
1937         $LFS getstripe $DIR/$tdir > $TLOG
1938         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
1939         unlinkmany $DIR/$tdir/t- 1000
1940         trap 0
1941         [[ $OBJS -gt 0 ]] &&
1942                 error "$OBJS objects created on OST-0. See $TLOG" ||
1943                 rm -f $TLOG
1944 }
1945 run_test 27u "skip object creation on OSC w/o objects"
1946
1947 test_27v() { # bug 4900
1948         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1949         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1950         remote_mds_nodsh && skip "remote MDS with nodsh"
1951         remote_ost_nodsh && skip "remote OST with nodsh"
1952
1953         exhaust_all_precreations 0x215
1954         reset_enospc
1955
1956         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
1957
1958         touch $DIR/$tdir/$tfile
1959         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
1960         # all except ost1
1961         for (( i=1; i < OSTCOUNT; i++ )); do
1962                 do_facet ost$i lctl set_param fail_loc=0x705
1963         done
1964         local START=`date +%s`
1965         createmany -o $DIR/$tdir/$tfile 32
1966
1967         local FINISH=`date +%s`
1968         local TIMEOUT=`lctl get_param -n timeout`
1969         local PROCESS=$((FINISH - START))
1970         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
1971                error "$FINISH - $START >= $TIMEOUT / 2"
1972         sleep $((TIMEOUT / 2 - PROCESS))
1973         reset_enospc
1974 }
1975 run_test 27v "skip object creation on slow OST"
1976
1977 test_27w() { # bug 10997
1978         test_mkdir $DIR/$tdir
1979         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
1980         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
1981                 error "stripe size $size != 65536" || true
1982         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
1983                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
1984 }
1985 run_test 27w "check $LFS setstripe -S and getstrip -d options"
1986
1987 test_27wa() {
1988         [[ $OSTCOUNT -lt 2 ]] &&
1989                 skip_env "skipping multiple stripe count/offset test"
1990
1991         test_mkdir $DIR/$tdir
1992         for i in $(seq 1 $OSTCOUNT); do
1993                 offset=$((i - 1))
1994                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
1995                         error "setstripe -c $i -i $offset failed"
1996                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
1997                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
1998                 [ $count -ne $i ] && error "stripe count $count != $i" || true
1999                 [ $index -ne $offset ] &&
2000                         error "stripe offset $index != $offset" || true
2001         done
2002 }
2003 run_test 27wa "check $LFS setstripe -c -i options"
2004
2005 test_27x() {
2006         remote_ost_nodsh && skip "remote OST with nodsh"
2007         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2008         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2009
2010         OFFSET=$(($OSTCOUNT - 1))
2011         OSTIDX=0
2012         local OST=$(ostname_from_index $OSTIDX)
2013
2014         test_mkdir $DIR/$tdir
2015         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2016         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2017         sleep_maxage
2018         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2019         for i in $(seq 0 $OFFSET); do
2020                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2021                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2022                 error "OST0 was degraded but new created file still use it"
2023         done
2024         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2025 }
2026 run_test 27x "create files while OST0 is degraded"
2027
2028 test_27y() {
2029         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2030         remote_mds_nodsh && skip "remote MDS with nodsh"
2031         remote_ost_nodsh && skip "remote OST with nodsh"
2032         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2033
2034         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2035         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2036                 osp.$mdtosc.prealloc_last_id)
2037         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2038                 osp.$mdtosc.prealloc_next_id)
2039         local fcount=$((last_id - next_id))
2040         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2041         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2042
2043         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2044                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2045         local OST_DEACTIVE_IDX=-1
2046         local OSC
2047         local OSTIDX
2048         local OST
2049
2050         for OSC in $MDS_OSCS; do
2051                 OST=$(osc_to_ost $OSC)
2052                 OSTIDX=$(index_from_ostuuid $OST)
2053                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2054                         OST_DEACTIVE_IDX=$OSTIDX
2055                 fi
2056                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2057                         echo $OSC "is Deactivated:"
2058                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2059                 fi
2060         done
2061
2062         OSTIDX=$(index_from_ostuuid $OST)
2063         test_mkdir $DIR/$tdir
2064         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2065
2066         for OSC in $MDS_OSCS; do
2067                 OST=$(osc_to_ost $OSC)
2068                 OSTIDX=$(index_from_ostuuid $OST)
2069                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2070                         echo $OST "is degraded:"
2071                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2072                                                 obdfilter.$OST.degraded=1
2073                 fi
2074         done
2075
2076         sleep_maxage
2077         createmany -o $DIR/$tdir/$tfile $fcount
2078
2079         for OSC in $MDS_OSCS; do
2080                 OST=$(osc_to_ost $OSC)
2081                 OSTIDX=$(index_from_ostuuid $OST)
2082                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2083                         echo $OST "is recovered from degraded:"
2084                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2085                                                 obdfilter.$OST.degraded=0
2086                 else
2087                         do_facet $SINGLEMDS lctl --device %$OSC activate
2088                 fi
2089         done
2090
2091         # all osp devices get activated, hence -1 stripe count restored
2092         local stripe_count=0
2093
2094         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2095         # devices get activated.
2096         sleep_maxage
2097         $LFS setstripe -c -1 $DIR/$tfile
2098         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2099         rm -f $DIR/$tfile
2100         [ $stripe_count -ne $OSTCOUNT ] &&
2101                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2102         return 0
2103 }
2104 run_test 27y "create files while OST0 is degraded and the rest inactive"
2105
2106 check_seq_oid()
2107 {
2108         log "check file $1"
2109
2110         lmm_count=$($LFS getstripe -c $1)
2111         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2112         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2113
2114         local old_ifs="$IFS"
2115         IFS=$'[:]'
2116         fid=($($LFS path2fid $1))
2117         IFS="$old_ifs"
2118
2119         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2120         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2121
2122         # compare lmm_seq and lu_fid->f_seq
2123         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2124         # compare lmm_object_id and lu_fid->oid
2125         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2126
2127         # check the trusted.fid attribute of the OST objects of the file
2128         local have_obdidx=false
2129         local stripe_nr=0
2130         $LFS getstripe $1 | while read obdidx oid hex seq; do
2131                 # skip lines up to and including "obdidx"
2132                 [ -z "$obdidx" ] && break
2133                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2134                 $have_obdidx || continue
2135
2136                 local ost=$((obdidx + 1))
2137                 local dev=$(ostdevname $ost)
2138                 local oid_hex
2139
2140                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2141
2142                 seq=$(echo $seq | sed -e "s/^0x//g")
2143                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2144                         oid_hex=$(echo $oid)
2145                 else
2146                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2147                 fi
2148                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2149
2150                 local ff=""
2151                 #
2152                 # Don't unmount/remount the OSTs if we don't need to do that.
2153                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2154                 # update too, until that use mount/ll_decode_filter_fid/mount.
2155                 # Re-enable when debugfs will understand new filter_fid.
2156                 #
2157                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2158                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2159                                 $dev 2>/dev/null" | grep "parent=")
2160                 fi
2161                 if [ -z "$ff" ]; then
2162                         stop ost$ost
2163                         mount_fstype ost$ost
2164                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2165                                 $(facet_mntpt ost$ost)/$obj_file)
2166                         unmount_fstype ost$ost
2167                         start ost$ost $dev $OST_MOUNT_OPTS
2168                         clients_up
2169                 fi
2170
2171                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2172
2173                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2174
2175                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2176                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2177                 #
2178                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2179                 #       stripe_size=1048576 component_id=1 component_start=0 \
2180                 #       component_end=33554432
2181                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2182                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2183                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2184                 local ff_pstripe
2185                 if grep -q 'stripe=' <<<$ff; then
2186                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2187                 else
2188                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2189                         # into f_ver in this case.  See comment on ff_parent.
2190                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2191                 fi
2192
2193                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2194                 [ $ff_pseq = $lmm_seq ] ||
2195                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2196                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2197                 [ $ff_poid = $lmm_oid ] ||
2198                         error "FF parent OID $ff_poid != $lmm_oid"
2199                 (($ff_pstripe == $stripe_nr)) ||
2200                         error "FF stripe $ff_pstripe != $stripe_nr"
2201
2202                 stripe_nr=$((stripe_nr + 1))
2203                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2204                         continue
2205                 if grep -q 'stripe_count=' <<<$ff; then
2206                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2207                                             -e 's/ .*//' <<<$ff)
2208                         [ $lmm_count = $ff_scnt ] ||
2209                                 error "FF stripe count $lmm_count != $ff_scnt"
2210                 fi
2211         done
2212 }
2213
2214 test_27z() {
2215         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2216         remote_ost_nodsh && skip "remote OST with nodsh"
2217
2218         test_mkdir $DIR/$tdir
2219         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2220                 { error "setstripe -c -1 failed"; return 1; }
2221         # We need to send a write to every object to get parent FID info set.
2222         # This _should_ also work for setattr, but does not currently.
2223         # touch $DIR/$tdir/$tfile-1 ||
2224         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2225                 { error "dd $tfile-1 failed"; return 2; }
2226         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2227                 { error "setstripe -c -1 failed"; return 3; }
2228         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2229                 { error "dd $tfile-2 failed"; return 4; }
2230
2231         # make sure write RPCs have been sent to OSTs
2232         sync; sleep 5; sync
2233
2234         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2235         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2236 }
2237 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2238
2239 test_27A() { # b=19102
2240         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2241
2242         save_layout_restore_at_exit $MOUNT
2243         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2244         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2245                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2246         local default_size=$($LFS getstripe -S $MOUNT)
2247         local default_offset=$($LFS getstripe -i $MOUNT)
2248         local dsize=$(do_facet $SINGLEMDS \
2249                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2250         [ $default_size -eq $dsize ] ||
2251                 error "stripe size $default_size != $dsize"
2252         [ $default_offset -eq -1 ] ||
2253                 error "stripe offset $default_offset != -1"
2254 }
2255 run_test 27A "check filesystem-wide default LOV EA values"
2256
2257 test_27B() { # LU-2523
2258         test_mkdir $DIR/$tdir
2259         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2260         touch $DIR/$tdir/f0
2261         # open f1 with O_LOV_DELAY_CREATE
2262         # rename f0 onto f1
2263         # call setstripe ioctl on open file descriptor for f1
2264         # close
2265         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2266                 $DIR/$tdir/f0
2267
2268         rm -f $DIR/$tdir/f1
2269         # open f1 with O_LOV_DELAY_CREATE
2270         # unlink f1
2271         # call setstripe ioctl on open file descriptor for f1
2272         # close
2273         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2274
2275         # Allow multiop to fail in imitation of NFS's busted semantics.
2276         true
2277 }
2278 run_test 27B "call setstripe on open unlinked file/rename victim"
2279
2280 # 27C family tests full striping and overstriping
2281 test_27Ca() { #LU-2871
2282         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2283
2284         declare -a ost_idx
2285         local index
2286         local found
2287         local i
2288         local j
2289
2290         test_mkdir $DIR/$tdir
2291         cd $DIR/$tdir
2292         for i in $(seq 0 $((OSTCOUNT - 1))); do
2293                 # set stripe across all OSTs starting from OST$i
2294                 $LFS setstripe -i $i -c -1 $tfile$i
2295                 # get striping information
2296                 ost_idx=($($LFS getstripe $tfile$i |
2297                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2298                 echo ${ost_idx[@]}
2299
2300                 # check the layout
2301                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2302                         error "${#ost_idx[@]} != $OSTCOUNT"
2303
2304                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2305                         found=0
2306                         for j in $(echo ${ost_idx[@]}); do
2307                                 if [ $index -eq $j ]; then
2308                                         found=1
2309                                         break
2310                                 fi
2311                         done
2312                         [ $found = 1 ] ||
2313                                 error "Can not find $index in ${ost_idx[@]}"
2314                 done
2315         done
2316 }
2317 run_test 27Ca "check full striping across all OSTs"
2318
2319 test_27Cb() {
2320         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2321                 skip "server does not support overstriping"
2322         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2323                 skip_env "too many osts, skipping"
2324
2325         test_mkdir -p $DIR/$tdir
2326         local setcount=$(($OSTCOUNT * 2))
2327         [ $setcount -ge 160 ] || large_xattr_enabled ||
2328                 skip_env "ea_inode feature disabled"
2329
2330         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2331                 error "setstripe failed"
2332
2333         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2334         [ $count -eq $setcount ] ||
2335                 error "stripe count $count, should be $setcount"
2336
2337         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2338                 error "overstriped should be set in pattern"
2339
2340         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2341                 error "dd failed"
2342 }
2343 run_test 27Cb "more stripes than OSTs with -C"
2344
2345 test_27Cc() {
2346         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2347                 skip "server does not support overstriping"
2348         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2349
2350         test_mkdir -p $DIR/$tdir
2351         local setcount=$(($OSTCOUNT - 1))
2352
2353         [ $setcount -ge 160 ] || large_xattr_enabled ||
2354                 skip_env "ea_inode feature disabled"
2355
2356         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2357                 error "setstripe failed"
2358
2359         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2360         [ $count -eq $setcount ] ||
2361                 error "stripe count $count, should be $setcount"
2362
2363         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2364                 error "overstriped should not be set in pattern"
2365
2366         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2367                 error "dd failed"
2368 }
2369 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2370
2371 test_27Cd() {
2372         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2373                 skip "server does not support overstriping"
2374         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2375         large_xattr_enabled || skip_env "ea_inode feature disabled"
2376
2377         test_mkdir -p $DIR/$tdir
2378         local setcount=$LOV_MAX_STRIPE_COUNT
2379
2380         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2381                 error "setstripe failed"
2382
2383         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2384         [ $count -eq $setcount ] ||
2385                 error "stripe count $count, should be $setcount"
2386
2387         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2388                 error "overstriped should be set in pattern"
2389
2390         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2391                 error "dd failed"
2392
2393         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2394 }
2395 run_test 27Cd "test maximum stripe count"
2396
2397 test_27Ce() {
2398         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2399                 skip "server does not support overstriping"
2400         test_mkdir -p $DIR/$tdir
2401
2402         pool_add $TESTNAME || error "Pool creation failed"
2403         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2404
2405         local setcount=8
2406
2407         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2408                 error "setstripe failed"
2409
2410         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2411         [ $count -eq $setcount ] ||
2412                 error "stripe count $count, should be $setcount"
2413
2414         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2415                 error "overstriped should be set in pattern"
2416
2417         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2418                 error "dd failed"
2419
2420         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2421 }
2422 run_test 27Ce "test pool with overstriping"
2423
2424 test_27Cf() {
2425         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2426                 skip "server does not support overstriping"
2427         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2428                 skip_env "too many osts, skipping"
2429
2430         test_mkdir -p $DIR/$tdir
2431
2432         local setcount=$(($OSTCOUNT * 2))
2433         [ $setcount -ge 160 ] || large_xattr_enabled ||
2434                 skip_env "ea_inode feature disabled"
2435
2436         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2437                 error "setstripe failed"
2438
2439         echo 1 > $DIR/$tdir/$tfile
2440
2441         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2442         [ $count -eq $setcount ] ||
2443                 error "stripe count $count, should be $setcount"
2444
2445         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2446                 error "overstriped should be set in pattern"
2447
2448         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2449                 error "dd failed"
2450
2451         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2452 }
2453 run_test 27Cf "test default inheritance with overstriping"
2454
2455 test_27D() {
2456         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2457         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2458         remote_mds_nodsh && skip "remote MDS with nodsh"
2459
2460         local POOL=${POOL:-testpool}
2461         local first_ost=0
2462         local last_ost=$(($OSTCOUNT - 1))
2463         local ost_step=1
2464         local ost_list=$(seq $first_ost $ost_step $last_ost)
2465         local ost_range="$first_ost $last_ost $ost_step"
2466
2467         test_mkdir $DIR/$tdir
2468         pool_add $POOL || error "pool_add failed"
2469         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2470
2471         local skip27D
2472         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2473                 skip27D+="-s 29"
2474         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2475                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2476                         skip27D+=" -s 30,31"
2477         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2478           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2479                 skip27D+=" -s 32,33"
2480         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2481                 skip27D+=" -s 34"
2482         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2483                 error "llapi_layout_test failed"
2484
2485         destroy_test_pools || error "destroy test pools failed"
2486 }
2487 run_test 27D "validate llapi_layout API"
2488
2489 # Verify that default_easize is increased from its initial value after
2490 # accessing a widely striped file.
2491 test_27E() {
2492         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2493         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2494                 skip "client does not have LU-3338 fix"
2495
2496         # 72 bytes is the minimum space required to store striping
2497         # information for a file striped across one OST:
2498         # (sizeof(struct lov_user_md_v3) +
2499         #  sizeof(struct lov_user_ost_data_v1))
2500         local min_easize=72
2501         $LCTL set_param -n llite.*.default_easize $min_easize ||
2502                 error "lctl set_param failed"
2503         local easize=$($LCTL get_param -n llite.*.default_easize)
2504
2505         [ $easize -eq $min_easize ] ||
2506                 error "failed to set default_easize"
2507
2508         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2509                 error "setstripe failed"
2510         # In order to ensure stat() call actually talks to MDS we need to
2511         # do something drastic to this file to shake off all lock, e.g.
2512         # rename it (kills lookup lock forcing cache cleaning)
2513         mv $DIR/$tfile $DIR/${tfile}-1
2514         ls -l $DIR/${tfile}-1
2515         rm $DIR/${tfile}-1
2516
2517         easize=$($LCTL get_param -n llite.*.default_easize)
2518
2519         [ $easize -gt $min_easize ] ||
2520                 error "default_easize not updated"
2521 }
2522 run_test 27E "check that default extended attribute size properly increases"
2523
2524 test_27F() { # LU-5346/LU-7975
2525         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2526         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2527         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2528                 skip "Need MDS version at least 2.8.51"
2529         remote_ost_nodsh && skip "remote OST with nodsh"
2530
2531         test_mkdir $DIR/$tdir
2532         rm -f $DIR/$tdir/f0
2533         $LFS setstripe -c 2 $DIR/$tdir
2534
2535         # stop all OSTs to reproduce situation for LU-7975 ticket
2536         for num in $(seq $OSTCOUNT); do
2537                 stop ost$num
2538         done
2539
2540         # open/create f0 with O_LOV_DELAY_CREATE
2541         # truncate f0 to a non-0 size
2542         # close
2543         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2544
2545         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2546         # open/write it again to force delayed layout creation
2547         cat /etc/hosts > $DIR/$tdir/f0 &
2548         catpid=$!
2549
2550         # restart OSTs
2551         for num in $(seq $OSTCOUNT); do
2552                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2553                         error "ost$num failed to start"
2554         done
2555
2556         wait $catpid || error "cat failed"
2557
2558         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2559         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2560                 error "wrong stripecount"
2561
2562 }
2563 run_test 27F "Client resend delayed layout creation with non-zero size"
2564
2565 test_27G() { #LU-10629
2566         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2567                 skip "Need MDS version at least 2.11.51"
2568         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2569         remote_mds_nodsh && skip "remote MDS with nodsh"
2570         local POOL=${POOL:-testpool}
2571         local ostrange="0 0 1"
2572
2573         test_mkdir $DIR/$tdir
2574         pool_add $POOL || error "pool_add failed"
2575         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2576         $LFS setstripe -p $POOL $DIR/$tdir
2577
2578         local pool=$($LFS getstripe -p $DIR/$tdir)
2579
2580         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2581
2582         $LFS setstripe -d $DIR/$tdir
2583
2584         pool=$($LFS getstripe -p $DIR/$tdir)
2585
2586         rmdir $DIR/$tdir
2587
2588         [ -z "$pool" ] || error "'$pool' is not empty"
2589 }
2590 run_test 27G "Clear OST pool from stripe"
2591
2592 test_27H() {
2593         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2594                 skip "Need MDS version newer than 2.11.54"
2595         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2596         test_mkdir $DIR/$tdir
2597         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2598         touch $DIR/$tdir/$tfile
2599         $LFS getstripe -c $DIR/$tdir/$tfile
2600         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2601                 error "two-stripe file doesn't have two stripes"
2602
2603         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2604         $LFS getstripe -y $DIR/$tdir/$tfile
2605         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2606              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2607                 error "expected l_ost_idx: [02]$ not matched"
2608
2609         # make sure ost list has been cleared
2610         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2611         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2612                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2613         touch $DIR/$tdir/f3
2614         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2615 }
2616 run_test 27H "Set specific OSTs stripe"
2617
2618 test_27I() {
2619         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2620         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2621         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2622                 skip "Need MDS version newer than 2.12.52"
2623         local pool=$TESTNAME
2624         local ostrange="1 1 1"
2625
2626         save_layout_restore_at_exit $MOUNT
2627         $LFS setstripe -c 2 -i 0 $MOUNT
2628         pool_add $pool || error "pool_add failed"
2629         pool_add_targets $pool $ostrange || "pool_add_targets failed"
2630         test_mkdir $DIR/$tdir
2631         $LFS setstripe -p $pool $DIR/$tdir
2632         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2633         $LFS getstripe $DIR/$tdir/$tfile
2634 }
2635 run_test 27I "check that root dir striping does not break parent dir one"
2636
2637 test_27J() {
2638         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
2639                 skip "Need MDS version newer than 2.12.51"
2640
2641         test_mkdir $DIR/$tdir
2642         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2643         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2644
2645         # create foreign file (raw way)
2646         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2647                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2648
2649         # verify foreign file (raw way)
2650         parse_foreign_file -f $DIR/$tdir/$tfile |
2651                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2652                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2653         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2654                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2655         parse_foreign_file -f $DIR/$tdir/$tfile |
2656                 grep "lov_foreign_size: 73" ||
2657                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2658         parse_foreign_file -f $DIR/$tdir/$tfile |
2659                 grep "lov_foreign_type: 1" ||
2660                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2661         parse_foreign_file -f $DIR/$tdir/$tfile |
2662                 grep "lov_foreign_flags: 0x0000DA08" ||
2663                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2664         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2665                 grep "lov_foreign_value: 0x" |
2666                 sed -e 's/lov_foreign_value: 0x//')
2667         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2668         [[ $lov = ${lov2// /} ]] ||
2669                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2670
2671         # create foreign file (lfs + API)
2672         $LFS setstripe --foreign=daos --flags 0xda08 \
2673                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2674                 error "$DIR/$tdir/${tfile}2: create failed"
2675
2676         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2677                 grep "lfm_magic:.*0x0BD70BD0" ||
2678                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2679         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2680         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2681                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2682         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*daos" ||
2683                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2684         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2685                 grep "lfm_flags:.*0x0000DA08" ||
2686                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2687         $LFS getstripe $DIR/$tdir/${tfile}2 |
2688                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2689                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2690
2691         # modify striping should fail
2692         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2693                 error "$DIR/$tdir/$tfile: setstripe should fail"
2694         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2695                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2696
2697         # R/W should fail
2698         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2699         cat $DIR/$tdir/${tfile}2 &&
2700                 error "$DIR/$tdir/${tfile}2: read should fail"
2701         cat /etc/passwd > $DIR/$tdir/$tfile &&
2702                 error "$DIR/$tdir/$tfile: write should fail"
2703         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2704                 error "$DIR/$tdir/${tfile}2: write should fail"
2705
2706         # chmod should work
2707         chmod 222 $DIR/$tdir/$tfile ||
2708                 error "$DIR/$tdir/$tfile: chmod failed"
2709         chmod 222 $DIR/$tdir/${tfile}2 ||
2710                 error "$DIR/$tdir/${tfile}2: chmod failed"
2711
2712         # chown should work
2713         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2714                 error "$DIR/$tdir/$tfile: chown failed"
2715         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2716                 error "$DIR/$tdir/${tfile}2: chown failed"
2717
2718         # rename should work
2719         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2720                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2721         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2722                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2723
2724         #remove foreign file
2725         rm $DIR/$tdir/${tfile}.new ||
2726                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2727         rm $DIR/$tdir/${tfile}2.new ||
2728                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2729 }
2730 run_test 27J "basic ops on file with foreign LOV"
2731
2732 test_27K() {
2733         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
2734                 skip "Need MDS version newer than 2.12.49"
2735
2736         test_mkdir $DIR/$tdir
2737         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2738         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2739
2740         # create foreign dir (raw way)
2741         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2742                 error "create_foreign_dir FAILED"
2743
2744         # verify foreign dir (raw way)
2745         parse_foreign_dir -d $DIR/$tdir/$tdir |
2746                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2747                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2748         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2749                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2750         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2751                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2752         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_flags: 0$" ||
2753                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2754         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2755                 grep "lmv_foreign_value: 0x" |
2756                 sed 's/lmv_foreign_value: 0x//')
2757         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2758                 sed 's/ //g')
2759         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2760
2761         # create foreign dir (lfs + API)
2762         $LFS mkdir --foreign=daos --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2763                 $DIR/$tdir/${tdir}2 ||
2764                 error "$DIR/$tdir/${tdir}2: create failed"
2765
2766         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2767                 grep "lfm_magic:.*0x0CD50CD0" ||
2768                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2769         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2770         # - sizeof(lfm_type) - sizeof(lfm_flags)
2771         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2772                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2773         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*daos" ||
2774                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2775         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2776                 grep "lfm_flags:.*0x0000DA05" ||
2777                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2778         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2779                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2780                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2781
2782         # file create in dir should fail
2783         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
2784         touch $DIR/$tdir/${tdir}2/$tfile &&
2785                 "$DIR/${tdir}2: file create should fail"
2786
2787         # chmod should work
2788         chmod 777 $DIR/$tdir/$tdir ||
2789                 error "$DIR/$tdir: chmod failed"
2790         chmod 777 $DIR/$tdir/${tdir}2 ||
2791                 error "$DIR/${tdir}2: chmod failed"
2792
2793         # chown should work
2794         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2795                 error "$DIR/$tdir: chown failed"
2796         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2797                 error "$DIR/${tdir}2: chown failed"
2798
2799         # rename should work
2800         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2801                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2802         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2803                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2804
2805         #remove foreign dir
2806         rmdir $DIR/$tdir/${tdir}.new ||
2807                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2808         rmdir $DIR/$tdir/${tdir}2.new ||
2809                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2810 }
2811 run_test 27K "basic ops on dir with foreign LMV"
2812
2813 test_27L() {
2814         remote_mds_nodsh && skip "remote MDS with nodsh"
2815
2816         local POOL=${POOL:-$TESTNAME}
2817
2818         pool_add $POOL || error "pool_add failed"
2819
2820         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2821                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2822                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2823 }
2824 run_test 27L "lfs pool_list gives correct pool name"
2825
2826 test_27M() {
2827         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2828                 skip "Need MDS version >= than 2.12.57"
2829         remote_mds_nodsh && skip "remote MDS with nodsh"
2830         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2831
2832         test_mkdir $DIR/$tdir
2833
2834         # Set default striping on directory
2835         $LFS setstripe -C 4 $DIR/$tdir
2836
2837         echo 1 > $DIR/$tdir/${tfile}.1
2838         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2839         local setcount=4
2840         [ $count -eq $setcount ] ||
2841                 error "(1) stripe count $count, should be $setcount"
2842
2843         # Capture existing append_stripe_count setting for restore
2844         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2845         local mdts=$(comma_list $(mdts_nodes))
2846         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$orig_count" EXIT
2847
2848         local appendcount=$orig_count
2849         echo 1 >> $DIR/$tdir/${tfile}.2_append
2850         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
2851         [ $count -eq $appendcount ] ||
2852                 error "(2)stripe count $count, should be $appendcount for append"
2853
2854         # Disable O_APPEND striping, verify it works
2855         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
2856
2857         # Should now get the default striping, which is 4
2858         setcount=4
2859         echo 1 >> $DIR/$tdir/${tfile}.3_append
2860         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
2861         [ $count -eq $setcount ] ||
2862                 error "(3) stripe count $count, should be $setcount"
2863
2864         # Try changing the stripe count for append files
2865         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
2866
2867         # Append striping is now 2 (directory default is still 4)
2868         appendcount=2
2869         echo 1 >> $DIR/$tdir/${tfile}.4_append
2870         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
2871         [ $count -eq $appendcount ] ||
2872                 error "(4) stripe count $count, should be $appendcount for append"
2873
2874         # Test append stripe count of -1
2875         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
2876         appendcount=$OSTCOUNT
2877         echo 1 >> $DIR/$tdir/${tfile}.5
2878         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
2879         [ $count -eq $appendcount ] ||
2880                 error "(5) stripe count $count, should be $appendcount for append"
2881
2882         # Set append striping back to default of 1
2883         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
2884
2885         # Try a new default striping, PFL + DOM
2886         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
2887
2888         # Create normal DOM file, DOM returns stripe count == 0
2889         setcount=0
2890         touch $DIR/$tdir/${tfile}.6
2891         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
2892         [ $count -eq $setcount ] ||
2893                 error "(6) stripe count $count, should be $setcount"
2894
2895         # Show
2896         appendcount=1
2897         echo 1 >> $DIR/$tdir/${tfile}.7_append
2898         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
2899         [ $count -eq $appendcount ] ||
2900                 error "(7) stripe count $count, should be $appendcount for append"
2901
2902         # Clean up DOM layout
2903         $LFS setstripe -d $DIR/$tdir
2904
2905         # Now test that append striping works when layout is from root
2906         $LFS setstripe -c 2 $MOUNT
2907         # Make a special directory for this
2908         mkdir $DIR/${tdir}/${tdir}.2
2909         stack_trap "$LFS setstripe -d $MOUNT" EXIT
2910
2911         # Verify for normal file
2912         setcount=2
2913         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
2914         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
2915         [ $count -eq $setcount ] ||
2916                 error "(8) stripe count $count, should be $setcount"
2917
2918         appendcount=1
2919         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
2920         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
2921         [ $count -eq $appendcount ] ||
2922                 error "(9) stripe count $count, should be $appendcount for append"
2923
2924         # Now test O_APPEND striping with pools
2925         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
2926         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'" EXIT
2927
2928         # Create the pool
2929         pool_add $TESTNAME || error "pool creation failed"
2930         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
2931
2932         echo 1 >> $DIR/$tdir/${tfile}.10_append
2933
2934         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
2935         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
2936
2937         # Check that count is still correct
2938         appendcount=1
2939         echo 1 >> $DIR/$tdir/${tfile}.11_append
2940         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
2941         [ $count -eq $appendcount ] ||
2942                 error "(11) stripe count $count, should be $appendcount for append"
2943
2944         # Disable O_APPEND stripe count, verify pool works separately
2945         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
2946
2947         echo 1 >> $DIR/$tdir/${tfile}.12_append
2948
2949         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
2950         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
2951
2952         # Remove pool setting, verify it's not applied
2953         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
2954
2955         echo 1 >> $DIR/$tdir/${tfile}.13_append
2956
2957         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
2958         [ "$pool" = "" ] || error "(13) pool found: $pool"
2959 }
2960 run_test 27M "test O_APPEND striping"
2961
2962 test_27N() {
2963         combined_mgs_mds && skip "needs separate MGS/MDT"
2964
2965         pool_add $TESTNAME || error "pool_add failed"
2966         do_facet mgs "$LCTL pool_list $FSNAME" |
2967                 grep -Fx "${FSNAME}.${TESTNAME}" ||
2968                 error "lctl pool_list on MGS failed"
2969 }
2970 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
2971
2972 # createtest also checks that device nodes are created and
2973 # then visible correctly (#2091)
2974 test_28() { # bug 2091
2975         test_mkdir $DIR/d28
2976         $CREATETEST $DIR/d28/ct || error "createtest failed"
2977 }
2978 run_test 28 "create/mknod/mkdir with bad file types ============"
2979
2980 test_29() {
2981         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2982
2983         sync; sleep 1; sync # flush out any dirty pages from previous tests
2984         cancel_lru_locks
2985         test_mkdir $DIR/d29
2986         touch $DIR/d29/foo
2987         log 'first d29'
2988         ls -l $DIR/d29
2989
2990         declare -i LOCKCOUNTORIG=0
2991         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
2992                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
2993         done
2994         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
2995
2996         declare -i LOCKUNUSEDCOUNTORIG=0
2997         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
2998                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
2999         done
3000
3001         log 'second d29'
3002         ls -l $DIR/d29
3003         log 'done'
3004
3005         declare -i LOCKCOUNTCURRENT=0
3006         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3007                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3008         done
3009
3010         declare -i LOCKUNUSEDCOUNTCURRENT=0
3011         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3012                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3013         done
3014
3015         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3016                 $LCTL set_param -n ldlm.dump_namespaces ""
3017                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3018                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3019                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3020                 return 2
3021         fi
3022         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3023                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3024                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3025                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3026                 return 3
3027         fi
3028 }
3029 run_test 29 "IT_GETATTR regression  ============================"
3030
3031 test_30a() { # was test_30
3032         cp $(which ls) $DIR || cp /bin/ls $DIR
3033         $DIR/ls / || error "Can't execute binary from lustre"
3034         rm $DIR/ls
3035 }
3036 run_test 30a "execute binary from Lustre (execve) =============="
3037
3038 test_30b() {
3039         cp `which ls` $DIR || cp /bin/ls $DIR
3040         chmod go+rx $DIR/ls
3041         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3042         rm $DIR/ls
3043 }
3044 run_test 30b "execute binary from Lustre as non-root ==========="
3045
3046 test_30c() { # b=22376
3047         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3048
3049         cp `which ls` $DIR || cp /bin/ls $DIR
3050         chmod a-rw $DIR/ls
3051         cancel_lru_locks mdc
3052         cancel_lru_locks osc
3053         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3054         rm -f $DIR/ls
3055 }
3056 run_test 30c "execute binary from Lustre without read perms ===="
3057
3058 test_31a() {
3059         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3060         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3061 }
3062 run_test 31a "open-unlink file =================================="
3063
3064 test_31b() {
3065         touch $DIR/f31 || error "touch $DIR/f31 failed"
3066         ln $DIR/f31 $DIR/f31b || error "ln failed"
3067         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3068         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3069 }
3070 run_test 31b "unlink file with multiple links while open ======="
3071
3072 test_31c() {
3073         touch $DIR/f31 || error "touch $DIR/f31 failed"
3074         ln $DIR/f31 $DIR/f31c || error "ln failed"
3075         multiop_bg_pause $DIR/f31 O_uc ||
3076                 error "multiop_bg_pause for $DIR/f31 failed"
3077         MULTIPID=$!
3078         $MULTIOP $DIR/f31c Ouc
3079         kill -USR1 $MULTIPID
3080         wait $MULTIPID
3081 }
3082 run_test 31c "open-unlink file with multiple links ============="
3083
3084 test_31d() {
3085         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3086         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3087 }
3088 run_test 31d "remove of open directory ========================="
3089
3090 test_31e() { # bug 2904
3091         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3092 }
3093 run_test 31e "remove of open non-empty directory ==============="
3094
3095 test_31f() { # bug 4554
3096         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3097
3098         set -vx
3099         test_mkdir $DIR/d31f
3100         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3101         cp /etc/hosts $DIR/d31f
3102         ls -l $DIR/d31f
3103         $LFS getstripe $DIR/d31f/hosts
3104         multiop_bg_pause $DIR/d31f D_c || return 1
3105         MULTIPID=$!
3106
3107         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3108         test_mkdir $DIR/d31f
3109         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3110         cp /etc/hosts $DIR/d31f
3111         ls -l $DIR/d31f
3112         $LFS getstripe $DIR/d31f/hosts
3113         multiop_bg_pause $DIR/d31f D_c || return 1
3114         MULTIPID2=$!
3115
3116         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3117         wait $MULTIPID || error "first opendir $MULTIPID failed"
3118
3119         sleep 6
3120
3121         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3122         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3123         set +vx
3124 }
3125 run_test 31f "remove of open directory with open-unlink file ==="
3126
3127 test_31g() {
3128         echo "-- cross directory link --"
3129         test_mkdir -c1 $DIR/${tdir}ga
3130         test_mkdir -c1 $DIR/${tdir}gb
3131         touch $DIR/${tdir}ga/f
3132         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3133         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3134         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3135         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3136         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3137 }
3138 run_test 31g "cross directory link==============="
3139
3140 test_31h() {
3141         echo "-- cross directory link --"
3142         test_mkdir -c1 $DIR/${tdir}
3143         test_mkdir -c1 $DIR/${tdir}/dir
3144         touch $DIR/${tdir}/f
3145         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3146         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3147         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3148         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3149         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3150 }
3151 run_test 31h "cross directory link under child==============="
3152
3153 test_31i() {
3154         echo "-- cross directory link --"
3155         test_mkdir -c1 $DIR/$tdir
3156         test_mkdir -c1 $DIR/$tdir/dir
3157         touch $DIR/$tdir/dir/f
3158         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3159         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3160         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3161         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3162         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3163 }
3164 run_test 31i "cross directory link under parent==============="
3165
3166 test_31j() {
3167         test_mkdir -c1 -p $DIR/$tdir
3168         test_mkdir -c1 -p $DIR/$tdir/dir1
3169         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3170         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3171         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3172         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3173         return 0
3174 }
3175 run_test 31j "link for directory==============="
3176
3177 test_31k() {
3178         test_mkdir -c1 -p $DIR/$tdir
3179         touch $DIR/$tdir/s
3180         touch $DIR/$tdir/exist
3181         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3182         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3183         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3184         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3185         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3186         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3187         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3188         return 0
3189 }
3190 run_test 31k "link to file: the same, non-existing, dir==============="
3191
3192 test_31m() {
3193         mkdir $DIR/d31m
3194         touch $DIR/d31m/s
3195         mkdir $DIR/d31m2
3196         touch $DIR/d31m2/exist
3197         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3198         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3199         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3200         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3201         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3202         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3203         return 0
3204 }
3205 run_test 31m "link to file: the same, non-existing, dir==============="
3206
3207 test_31n() {
3208         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3209         nlink=$(stat --format=%h $DIR/$tfile)
3210         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3211         local fd=$(free_fd)
3212         local cmd="exec $fd<$DIR/$tfile"
3213         eval $cmd
3214         cmd="exec $fd<&-"
3215         trap "eval $cmd" EXIT
3216         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3217         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3218         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3219         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3220         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3221         eval $cmd
3222 }
3223 run_test 31n "check link count of unlinked file"
3224
3225 link_one() {
3226         local tempfile=$(mktemp $1_XXXXXX)
3227         mlink $tempfile $1 2> /dev/null &&
3228                 echo "$BASHPID: link $tempfile to $1 succeeded"
3229         munlink $tempfile
3230 }
3231
3232 test_31o() { # LU-2901
3233         test_mkdir $DIR/$tdir
3234         for LOOP in $(seq 100); do
3235                 rm -f $DIR/$tdir/$tfile*
3236                 for THREAD in $(seq 8); do
3237                         link_one $DIR/$tdir/$tfile.$LOOP &
3238                 done
3239                 wait
3240                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3241                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3242                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3243                         break || true
3244         done
3245 }
3246 run_test 31o "duplicate hard links with same filename"
3247
3248 test_31p() {
3249         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3250
3251         test_mkdir $DIR/$tdir
3252         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3253         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3254
3255         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3256                 error "open unlink test1 failed"
3257         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3258                 error "open unlink test2 failed"
3259
3260         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3261                 error "test1 still exists"
3262         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3263                 error "test2 still exists"
3264 }
3265 run_test 31p "remove of open striped directory"
3266
3267 cleanup_test32_mount() {
3268         local rc=0
3269         trap 0
3270         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3271         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3272         losetup -d $loopdev || true
3273         rm -rf $DIR/$tdir
3274         return $rc
3275 }
3276
3277 test_32a() {
3278         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3279
3280         echo "== more mountpoints and symlinks ================="
3281         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3282         trap cleanup_test32_mount EXIT
3283         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3284         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3285                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3286         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3287                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3288         cleanup_test32_mount
3289 }
3290 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3291
3292 test_32b() {
3293         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3294
3295         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3296         trap cleanup_test32_mount EXIT
3297         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3298         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3299                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3300         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3301                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3302         cleanup_test32_mount
3303 }
3304 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3305
3306 test_32c() {
3307         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3308
3309         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3310         trap cleanup_test32_mount EXIT
3311         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3312         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3313                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3314         test_mkdir -p $DIR/$tdir/d2/test_dir
3315         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3316                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3317         cleanup_test32_mount
3318 }
3319 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3320
3321 test_32d() {
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         test_mkdir -p $DIR/$tdir/d2/test_dir
3330         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3331                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3332         cleanup_test32_mount
3333 }
3334 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3335
3336 test_32e() {
3337         rm -fr $DIR/$tdir
3338         test_mkdir -p $DIR/$tdir/tmp
3339         local tmp_dir=$DIR/$tdir/tmp
3340         ln -s $DIR/$tdir $tmp_dir/symlink11
3341         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3342         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3343         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3344 }
3345 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3346
3347 test_32f() {
3348         rm -fr $DIR/$tdir
3349         test_mkdir -p $DIR/$tdir/tmp
3350         local tmp_dir=$DIR/$tdir/tmp
3351         ln -s $DIR/$tdir $tmp_dir/symlink11
3352         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3353         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3354         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3355 }
3356 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3357
3358 test_32g() {
3359         local tmp_dir=$DIR/$tdir/tmp
3360         test_mkdir -p $tmp_dir
3361         test_mkdir $DIR/${tdir}2
3362         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3363         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3364         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3365         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3366         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3367         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3368 }
3369 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3370
3371 test_32h() {
3372         rm -fr $DIR/$tdir $DIR/${tdir}2
3373         tmp_dir=$DIR/$tdir/tmp
3374         test_mkdir -p $tmp_dir
3375         test_mkdir $DIR/${tdir}2
3376         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3377         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3378         ls $tmp_dir/symlink12 || error "listing symlink12"
3379         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3380 }
3381 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3382
3383 test_32i() {
3384         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3385
3386         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3387         trap cleanup_test32_mount EXIT
3388         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3389         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3390                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3391         touch $DIR/$tdir/test_file
3392         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3393                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3394         cleanup_test32_mount
3395 }
3396 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3397
3398 test_32j() {
3399         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3400
3401         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3402         trap cleanup_test32_mount EXIT
3403         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3404         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3405                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3406         touch $DIR/$tdir/test_file
3407         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3408                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3409         cleanup_test32_mount
3410 }
3411 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3412
3413 test_32k() {
3414         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3415
3416         rm -fr $DIR/$tdir
3417         trap cleanup_test32_mount EXIT
3418         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3419         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3420                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3421         test_mkdir -p $DIR/$tdir/d2
3422         touch $DIR/$tdir/d2/test_file || error "touch failed"
3423         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3424                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3425         cleanup_test32_mount
3426 }
3427 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3428
3429 test_32l() {
3430         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3431
3432         rm -fr $DIR/$tdir
3433         trap cleanup_test32_mount EXIT
3434         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3435         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3436                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3437         test_mkdir -p $DIR/$tdir/d2
3438         touch $DIR/$tdir/d2/test_file || error "touch failed"
3439         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3440                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3441         cleanup_test32_mount
3442 }
3443 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3444
3445 test_32m() {
3446         rm -fr $DIR/d32m
3447         test_mkdir -p $DIR/d32m/tmp
3448         TMP_DIR=$DIR/d32m/tmp
3449         ln -s $DIR $TMP_DIR/symlink11
3450         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3451         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3452                 error "symlink11 not a link"
3453         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3454                 error "symlink01 not a link"
3455 }
3456 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3457
3458 test_32n() {
3459         rm -fr $DIR/d32n
3460         test_mkdir -p $DIR/d32n/tmp
3461         TMP_DIR=$DIR/d32n/tmp
3462         ln -s $DIR $TMP_DIR/symlink11
3463         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3464         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3465         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3466 }
3467 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3468
3469 test_32o() {
3470         touch $DIR/$tfile
3471         test_mkdir -p $DIR/d32o/tmp
3472         TMP_DIR=$DIR/d32o/tmp
3473         ln -s $DIR/$tfile $TMP_DIR/symlink12
3474         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3475         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3476                 error "symlink12 not a link"
3477         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3478         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3479                 error "$DIR/d32o/tmp/symlink12 not file type"
3480         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3481                 error "$DIR/d32o/symlink02 not file type"
3482 }
3483 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3484
3485 test_32p() {
3486         log 32p_1
3487         rm -fr $DIR/d32p
3488         log 32p_2
3489         rm -f $DIR/$tfile
3490         log 32p_3
3491         touch $DIR/$tfile
3492         log 32p_4
3493         test_mkdir -p $DIR/d32p/tmp
3494         log 32p_5
3495         TMP_DIR=$DIR/d32p/tmp
3496         log 32p_6
3497         ln -s $DIR/$tfile $TMP_DIR/symlink12
3498         log 32p_7
3499         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3500         log 32p_8
3501         cat $DIR/d32p/tmp/symlink12 ||
3502                 error "Can't open $DIR/d32p/tmp/symlink12"
3503         log 32p_9
3504         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3505         log 32p_10
3506 }
3507 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3508
3509 test_32q() {
3510         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3511
3512         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3513         trap cleanup_test32_mount EXIT
3514         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3515         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3516         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3517                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3518         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3519         cleanup_test32_mount
3520 }
3521 run_test 32q "stat follows mountpoints in Lustre (should return error)"
3522
3523 test_32r() {
3524         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3525
3526         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3527         trap cleanup_test32_mount EXIT
3528         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3529         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3530         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3531                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3532         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
3533         cleanup_test32_mount
3534 }
3535 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
3536
3537 test_33aa() {
3538         rm -f $DIR/$tfile
3539         touch $DIR/$tfile
3540         chmod 444 $DIR/$tfile
3541         chown $RUNAS_ID $DIR/$tfile
3542         log 33_1
3543         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3544         log 33_2
3545 }
3546 run_test 33aa "write file with mode 444 (should return error)"
3547
3548 test_33a() {
3549         rm -fr $DIR/$tdir
3550         test_mkdir $DIR/$tdir
3551         chown $RUNAS_ID $DIR/$tdir
3552         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
3553                 error "$RUNAS create $tdir/$tfile failed"
3554         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
3555                 error "open RDWR" || true
3556 }
3557 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
3558
3559 test_33b() {
3560         rm -fr $DIR/$tdir
3561         test_mkdir $DIR/$tdir
3562         chown $RUNAS_ID $DIR/$tdir
3563         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
3564 }
3565 run_test 33b "test open file with malformed flags (No panic)"
3566
3567 test_33c() {
3568         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3569         remote_ost_nodsh && skip "remote OST with nodsh"
3570
3571         local ostnum
3572         local ostname
3573         local write_bytes
3574         local all_zeros
3575
3576         all_zeros=:
3577         rm -fr $DIR/$tdir
3578         test_mkdir $DIR/$tdir
3579         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
3580
3581         sync
3582         for ostnum in $(seq $OSTCOUNT); do
3583                 # test-framework's OST numbering is one-based, while Lustre's
3584                 # is zero-based
3585                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3586                 # Parsing llobdstat's output sucks; we could grep the /proc
3587                 # path, but that's likely to not be as portable as using the
3588                 # llobdstat utility.  So we parse lctl output instead.
3589                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3590                         obdfilter/$ostname/stats |
3591                         awk '/^write_bytes/ {print $7}' )
3592                 echo "baseline_write_bytes@$OSTnum/$ostname=$write_bytes"
3593                 if (( ${write_bytes:-0} > 0 ))
3594                 then
3595                         all_zeros=false
3596                         break;
3597                 fi
3598         done
3599
3600         $all_zeros || return 0
3601
3602         # Write four bytes
3603         echo foo > $DIR/$tdir/bar
3604         # Really write them
3605         sync
3606
3607         # Total up write_bytes after writing.  We'd better find non-zeros.
3608         for ostnum in $(seq $OSTCOUNT); do
3609                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3610                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3611                         obdfilter/$ostname/stats |
3612                         awk '/^write_bytes/ {print $7}' )
3613                 echo "write_bytes@$OSTnum/$ostname=$write_bytes"
3614                 if (( ${write_bytes:-0} > 0 ))
3615                 then
3616                         all_zeros=false
3617                         break;
3618                 fi
3619         done
3620
3621         if $all_zeros
3622         then
3623                 for ostnum in $(seq $OSTCOUNT); do
3624                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3625                         echo "Check that write_bytes is present in obdfilter/*/stats:"
3626                         do_facet ost$ostnum lctl get_param -n \
3627                                 obdfilter/$ostname/stats
3628                 done
3629                 error "OST not keeping write_bytes stats (b22312)"
3630         fi
3631 }
3632 run_test 33c "test llobdstat and write_bytes"
3633
3634 test_33d() {
3635         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
3636         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3637
3638         local MDTIDX=1
3639         local remote_dir=$DIR/$tdir/remote_dir
3640
3641         test_mkdir $DIR/$tdir
3642         $LFS mkdir -i $MDTIDX $remote_dir ||
3643                 error "create remote directory failed"
3644
3645         touch $remote_dir/$tfile
3646         chmod 444 $remote_dir/$tfile
3647         chown $RUNAS_ID $remote_dir/$tfile
3648
3649         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3650
3651         chown $RUNAS_ID $remote_dir
3652         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
3653                                         error "create" || true
3654         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
3655                                     error "open RDWR" || true
3656         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
3657 }
3658 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
3659
3660 test_33e() {
3661         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3662
3663         mkdir $DIR/$tdir
3664
3665         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3666         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3667         mkdir $DIR/$tdir/local_dir
3668
3669         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3670         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3671         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3672
3673         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3674                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
3675
3676         rmdir $DIR/$tdir/* || error "rmdir failed"
3677
3678         umask 777
3679         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3680         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3681         mkdir $DIR/$tdir/local_dir
3682
3683         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3684         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3685         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3686
3687         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3688                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
3689
3690         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
3691
3692         umask 000
3693         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3694         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3695         mkdir $DIR/$tdir/local_dir
3696
3697         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3698         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3699         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3700
3701         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3702                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
3703 }
3704 run_test 33e "mkdir and striped directory should have same mode"
3705
3706 cleanup_33f() {
3707         trap 0
3708         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
3709 }
3710
3711 test_33f() {
3712         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3713         remote_mds_nodsh && skip "remote MDS with nodsh"
3714
3715         mkdir $DIR/$tdir
3716         chmod go+rwx $DIR/$tdir
3717         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
3718         trap cleanup_33f EXIT
3719
3720         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
3721                 error "cannot create striped directory"
3722
3723         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
3724                 error "cannot create files in striped directory"
3725
3726         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
3727                 error "cannot remove files in striped directory"
3728
3729         $RUNAS rmdir $DIR/$tdir/striped_dir ||
3730                 error "cannot remove striped directory"
3731
3732         cleanup_33f
3733 }
3734 run_test 33f "nonroot user can create, access, and remove a striped directory"
3735
3736 test_33g() {
3737         mkdir -p $DIR/$tdir/dir2
3738
3739         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
3740         echo $err
3741         [[ $err =~ "exists" ]] || error "Not exists error"
3742 }
3743 run_test 33g "nonroot user create already existing root created file"
3744
3745 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
3746 test_34a() {
3747         rm -f $DIR/f34
3748         $MCREATE $DIR/f34 || error "mcreate failed"
3749         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3750                 error "getstripe failed"
3751         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
3752         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3753                 error "getstripe failed"
3754         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3755                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3756 }
3757 run_test 34a "truncate file that has not been opened ==========="
3758
3759 test_34b() {
3760         [ ! -f $DIR/f34 ] && test_34a
3761         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3762                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3763         $OPENFILE -f O_RDONLY $DIR/f34
3764         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3765                 error "getstripe failed"
3766         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3767                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3768 }
3769 run_test 34b "O_RDONLY opening file doesn't create objects ====="
3770
3771 test_34c() {
3772         [ ! -f $DIR/f34 ] && test_34a
3773         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3774                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3775         $OPENFILE -f O_RDWR $DIR/f34
3776         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
3777                 error "$LFS getstripe failed"
3778         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3779                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3780 }
3781 run_test 34c "O_RDWR opening file-with-size works =============="
3782
3783 test_34d() {
3784         [ ! -f $DIR/f34 ] && test_34a
3785         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
3786                 error "dd failed"
3787         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3788                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3789         rm $DIR/f34
3790 }
3791 run_test 34d "write to sparse file ============================="
3792
3793 test_34e() {
3794         rm -f $DIR/f34e
3795         $MCREATE $DIR/f34e || error "mcreate failed"
3796         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
3797         $CHECKSTAT -s 1000 $DIR/f34e ||
3798                 error "Size of $DIR/f34e not equal to 1000 bytes"
3799         $OPENFILE -f O_RDWR $DIR/f34e
3800         $CHECKSTAT -s 1000 $DIR/f34e ||
3801                 error "Size of $DIR/f34e not equal to 1000 bytes"
3802 }
3803 run_test 34e "create objects, some with size and some without =="
3804
3805 test_34f() { # bug 6242, 6243
3806         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3807
3808         SIZE34F=48000
3809         rm -f $DIR/f34f
3810         $MCREATE $DIR/f34f || error "mcreate failed"
3811         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
3812         dd if=$DIR/f34f of=$TMP/f34f
3813         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
3814         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
3815         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
3816         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
3817         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
3818 }
3819 run_test 34f "read from a file with no objects until EOF ======="
3820
3821 test_34g() {
3822         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3823
3824         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
3825                 error "dd failed"
3826         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
3827         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3828                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
3829         cancel_lru_locks osc
3830         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3831                 error "wrong size after lock cancel"
3832
3833         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
3834         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3835                 error "expanding truncate failed"
3836         cancel_lru_locks osc
3837         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3838                 error "wrong expanded size after lock cancel"
3839 }
3840 run_test 34g "truncate long file ==============================="
3841
3842 test_34h() {
3843         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3844
3845         local gid=10
3846         local sz=1000
3847
3848         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
3849         sync # Flush the cache so that multiop below does not block on cache
3850              # flush when getting the group lock
3851         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
3852         MULTIPID=$!
3853
3854         # Since just timed wait is not good enough, let's do a sync write
3855         # that way we are sure enough time for a roundtrip + processing
3856         # passed + 2 seconds of extra margin.
3857         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
3858         rm $DIR/${tfile}-1
3859         sleep 2
3860
3861         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
3862                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
3863                 kill -9 $MULTIPID
3864         fi
3865         wait $MULTIPID
3866         local nsz=`stat -c %s $DIR/$tfile`
3867         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
3868 }
3869 run_test 34h "ftruncate file under grouplock should not block"
3870
3871 test_35a() {
3872         cp /bin/sh $DIR/f35a
3873         chmod 444 $DIR/f35a
3874         chown $RUNAS_ID $DIR/f35a
3875         $RUNAS $DIR/f35a && error || true
3876         rm $DIR/f35a
3877 }
3878 run_test 35a "exec file with mode 444 (should return and not leak)"
3879
3880 test_36a() {
3881         rm -f $DIR/f36
3882         utime $DIR/f36 || error "utime failed for MDS"
3883 }
3884 run_test 36a "MDS utime check (mknod, utime)"
3885
3886 test_36b() {
3887         echo "" > $DIR/f36
3888         utime $DIR/f36 || error "utime failed for OST"
3889 }
3890 run_test 36b "OST utime check (open, utime)"
3891
3892 test_36c() {
3893         rm -f $DIR/d36/f36
3894         test_mkdir $DIR/d36
3895         chown $RUNAS_ID $DIR/d36
3896         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
3897 }
3898 run_test 36c "non-root MDS utime check (mknod, utime)"
3899
3900 test_36d() {
3901         [ ! -d $DIR/d36 ] && test_36c
3902         echo "" > $DIR/d36/f36
3903         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
3904 }
3905 run_test 36d "non-root OST utime check (open, utime)"
3906
3907 test_36e() {
3908         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
3909
3910         test_mkdir $DIR/$tdir
3911         touch $DIR/$tdir/$tfile
3912         $RUNAS utime $DIR/$tdir/$tfile &&
3913                 error "utime worked, expected failure" || true
3914 }
3915 run_test 36e "utime on non-owned file (should return error)"
3916
3917 subr_36fh() {
3918         local fl="$1"
3919         local LANG_SAVE=$LANG
3920         local LC_LANG_SAVE=$LC_LANG
3921         export LANG=C LC_LANG=C # for date language
3922
3923         DATESTR="Dec 20  2000"
3924         test_mkdir $DIR/$tdir
3925         lctl set_param fail_loc=$fl
3926         date; date +%s
3927         cp /etc/hosts $DIR/$tdir/$tfile
3928         sync & # write RPC generated with "current" inode timestamp, but delayed
3929         sleep 1
3930         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
3931         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
3932         cancel_lru_locks $OSC
3933         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
3934         date; date +%s
3935         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
3936                 echo "BEFORE: $LS_BEFORE" && \
3937                 echo "AFTER : $LS_AFTER" && \
3938                 echo "WANT  : $DATESTR" && \
3939                 error "$DIR/$tdir/$tfile timestamps changed" || true
3940
3941         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
3942 }
3943
3944 test_36f() {
3945         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3946
3947         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
3948         subr_36fh "0x80000214"
3949 }
3950 run_test 36f "utime on file racing with OST BRW write =========="
3951
3952 test_36g() {
3953         remote_ost_nodsh && skip "remote OST with nodsh"
3954         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3955         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
3956                 skip "Need MDS version at least 2.12.51"
3957
3958         local fmd_max_age
3959         local fmd
3960         local facet="ost1"
3961         local tgt="obdfilter"
3962
3963         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
3964
3965         test_mkdir $DIR/$tdir
3966         fmd_max_age=$(do_facet $facet \
3967                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
3968                 head -n 1")
3969
3970         echo "FMD max age: ${fmd_max_age}s"
3971         touch $DIR/$tdir/$tfile
3972         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
3973                 gawk '{cnt=cnt+$1}  END{print cnt}')
3974         echo "FMD before: $fmd"
3975         [[ $fmd == 0 ]] &&
3976                 error "FMD wasn't create by touch"
3977         sleep $((fmd_max_age + 12))
3978         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
3979                 gawk '{cnt=cnt+$1}  END{print cnt}')
3980         echo "FMD after: $fmd"
3981         [[ $fmd == 0 ]] ||
3982                 error "FMD wasn't expired by ping"
3983 }
3984 run_test 36g "FMD cache expiry ====================="
3985
3986 test_36h() {
3987         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3988
3989         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
3990         subr_36fh "0x80000227"
3991 }
3992 run_test 36h "utime on file racing with OST BRW write =========="
3993
3994 test_36i() {
3995         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3996
3997         test_mkdir $DIR/$tdir
3998         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
3999
4000         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4001         local new_mtime=$((mtime + 200))
4002
4003         #change Modify time of striped dir
4004         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4005                         error "change mtime failed"
4006
4007         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4008
4009         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4010 }
4011 run_test 36i "change mtime on striped directory"
4012
4013 # test_37 - duplicate with tests 32q 32r
4014
4015 test_38() {
4016         local file=$DIR/$tfile
4017         touch $file
4018         openfile -f O_DIRECTORY $file
4019         local RC=$?
4020         local ENOTDIR=20
4021         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4022         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4023 }
4024 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4025
4026 test_39a() { # was test_39
4027         touch $DIR/$tfile
4028         touch $DIR/${tfile}2
4029 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4030 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4031 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4032         sleep 2
4033         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4034         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4035                 echo "mtime"
4036                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4037                 echo "atime"
4038                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4039                 echo "ctime"
4040                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4041                 error "O_TRUNC didn't change timestamps"
4042         fi
4043 }
4044 run_test 39a "mtime changed on create"
4045
4046 test_39b() {
4047         test_mkdir -c1 $DIR/$tdir
4048         cp -p /etc/passwd $DIR/$tdir/fopen
4049         cp -p /etc/passwd $DIR/$tdir/flink
4050         cp -p /etc/passwd $DIR/$tdir/funlink
4051         cp -p /etc/passwd $DIR/$tdir/frename
4052         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4053
4054         sleep 1
4055         echo "aaaaaa" >> $DIR/$tdir/fopen
4056         echo "aaaaaa" >> $DIR/$tdir/flink
4057         echo "aaaaaa" >> $DIR/$tdir/funlink
4058         echo "aaaaaa" >> $DIR/$tdir/frename
4059
4060         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4061         local link_new=`stat -c %Y $DIR/$tdir/flink`
4062         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4063         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4064
4065         cat $DIR/$tdir/fopen > /dev/null
4066         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4067         rm -f $DIR/$tdir/funlink2
4068         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4069
4070         for (( i=0; i < 2; i++ )) ; do
4071                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4072                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4073                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4074                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4075
4076                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4077                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4078                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4079                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4080
4081                 cancel_lru_locks $OSC
4082                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4083         done
4084 }
4085 run_test 39b "mtime change on open, link, unlink, rename  ======"
4086
4087 # this should be set to past
4088 TEST_39_MTIME=`date -d "1 year ago" +%s`
4089
4090 # bug 11063
4091 test_39c() {
4092         touch $DIR1/$tfile
4093         sleep 2
4094         local mtime0=`stat -c %Y $DIR1/$tfile`
4095
4096         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4097         local mtime1=`stat -c %Y $DIR1/$tfile`
4098         [ "$mtime1" = $TEST_39_MTIME ] || \
4099                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4100
4101         local d1=`date +%s`
4102         echo hello >> $DIR1/$tfile
4103         local d2=`date +%s`
4104         local mtime2=`stat -c %Y $DIR1/$tfile`
4105         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4106                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4107
4108         mv $DIR1/$tfile $DIR1/$tfile-1
4109
4110         for (( i=0; i < 2; i++ )) ; do
4111                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4112                 [ "$mtime2" = "$mtime3" ] || \
4113                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4114
4115                 cancel_lru_locks $OSC
4116                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4117         done
4118 }
4119 run_test 39c "mtime change on rename ==========================="
4120
4121 # bug 21114
4122 test_39d() {
4123         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4124
4125         touch $DIR1/$tfile
4126         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4127
4128         for (( i=0; i < 2; i++ )) ; do
4129                 local mtime=`stat -c %Y $DIR1/$tfile`
4130                 [ $mtime = $TEST_39_MTIME ] || \
4131                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4132
4133                 cancel_lru_locks $OSC
4134                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4135         done
4136 }
4137 run_test 39d "create, utime, stat =============================="
4138
4139 # bug 21114
4140 test_39e() {
4141         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4142
4143         touch $DIR1/$tfile
4144         local mtime1=`stat -c %Y $DIR1/$tfile`
4145
4146         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4147
4148         for (( i=0; i < 2; i++ )) ; do
4149                 local mtime2=`stat -c %Y $DIR1/$tfile`
4150                 [ $mtime2 = $TEST_39_MTIME ] || \
4151                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4152
4153                 cancel_lru_locks $OSC
4154                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4155         done
4156 }
4157 run_test 39e "create, stat, utime, stat ========================"
4158
4159 # bug 21114
4160 test_39f() {
4161         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4162
4163         touch $DIR1/$tfile
4164         mtime1=`stat -c %Y $DIR1/$tfile`
4165
4166         sleep 2
4167         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4168
4169         for (( i=0; i < 2; i++ )) ; do
4170                 local mtime2=`stat -c %Y $DIR1/$tfile`
4171                 [ $mtime2 = $TEST_39_MTIME ] || \
4172                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4173
4174                 cancel_lru_locks $OSC
4175                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4176         done
4177 }
4178 run_test 39f "create, stat, sleep, utime, stat ================="
4179
4180 # bug 11063
4181 test_39g() {
4182         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4183
4184         echo hello >> $DIR1/$tfile
4185         local mtime1=`stat -c %Y $DIR1/$tfile`
4186
4187         sleep 2
4188         chmod o+r $DIR1/$tfile
4189
4190         for (( i=0; i < 2; i++ )) ; do
4191                 local mtime2=`stat -c %Y $DIR1/$tfile`
4192                 [ "$mtime1" = "$mtime2" ] || \
4193                         error "lost mtime: $mtime2, should be $mtime1"
4194
4195                 cancel_lru_locks $OSC
4196                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4197         done
4198 }
4199 run_test 39g "write, chmod, stat ==============================="
4200
4201 # bug 11063
4202 test_39h() {
4203         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4204
4205         touch $DIR1/$tfile
4206         sleep 1
4207
4208         local d1=`date`
4209         echo hello >> $DIR1/$tfile
4210         local mtime1=`stat -c %Y $DIR1/$tfile`
4211
4212         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4213         local d2=`date`
4214         if [ "$d1" != "$d2" ]; then
4215                 echo "write and touch not within one second"
4216         else
4217                 for (( i=0; i < 2; i++ )) ; do
4218                         local mtime2=`stat -c %Y $DIR1/$tfile`
4219                         [ "$mtime2" = $TEST_39_MTIME ] || \
4220                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4221
4222                         cancel_lru_locks $OSC
4223                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4224                 done
4225         fi
4226 }
4227 run_test 39h "write, utime within one second, stat ============="
4228
4229 test_39i() {
4230         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4231
4232         touch $DIR1/$tfile
4233         sleep 1
4234
4235         echo hello >> $DIR1/$tfile
4236         local mtime1=`stat -c %Y $DIR1/$tfile`
4237
4238         mv $DIR1/$tfile $DIR1/$tfile-1
4239
4240         for (( i=0; i < 2; i++ )) ; do
4241                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4242
4243                 [ "$mtime1" = "$mtime2" ] || \
4244                         error "lost mtime: $mtime2, should be $mtime1"
4245
4246                 cancel_lru_locks $OSC
4247                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4248         done
4249 }
4250 run_test 39i "write, rename, stat =============================="
4251
4252 test_39j() {
4253         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4254
4255         start_full_debug_logging
4256         touch $DIR1/$tfile
4257         sleep 1
4258
4259         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4260         lctl set_param fail_loc=0x80000412
4261         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4262                 error "multiop failed"
4263         local multipid=$!
4264         local mtime1=`stat -c %Y $DIR1/$tfile`
4265
4266         mv $DIR1/$tfile $DIR1/$tfile-1
4267
4268         kill -USR1 $multipid
4269         wait $multipid || error "multiop close failed"
4270
4271         for (( i=0; i < 2; i++ )) ; do
4272                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4273                 [ "$mtime1" = "$mtime2" ] ||
4274                         error "mtime is lost on close: $mtime2, " \
4275                               "should be $mtime1"
4276
4277                 cancel_lru_locks
4278                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4279         done
4280         lctl set_param fail_loc=0
4281         stop_full_debug_logging
4282 }
4283 run_test 39j "write, rename, close, stat ======================="
4284
4285 test_39k() {
4286         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4287
4288         touch $DIR1/$tfile
4289         sleep 1
4290
4291         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4292         local multipid=$!
4293         local mtime1=`stat -c %Y $DIR1/$tfile`
4294
4295         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4296
4297         kill -USR1 $multipid
4298         wait $multipid || error "multiop close failed"
4299
4300         for (( i=0; i < 2; i++ )) ; do
4301                 local mtime2=`stat -c %Y $DIR1/$tfile`
4302
4303                 [ "$mtime2" = $TEST_39_MTIME ] || \
4304                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4305
4306                 cancel_lru_locks
4307                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4308         done
4309 }
4310 run_test 39k "write, utime, close, stat ========================"
4311
4312 # this should be set to future
4313 TEST_39_ATIME=`date -d "1 year" +%s`
4314
4315 test_39l() {
4316         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4317         remote_mds_nodsh && skip "remote MDS with nodsh"
4318
4319         local atime_diff=$(do_facet $SINGLEMDS \
4320                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4321         rm -rf $DIR/$tdir
4322         mkdir -p $DIR/$tdir
4323
4324         # test setting directory atime to future
4325         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4326         local atime=$(stat -c %X $DIR/$tdir)
4327         [ "$atime" = $TEST_39_ATIME ] ||
4328                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4329
4330         # test setting directory atime from future to now
4331         local now=$(date +%s)
4332         touch -a -d @$now $DIR/$tdir
4333
4334         atime=$(stat -c %X $DIR/$tdir)
4335         [ "$atime" -eq "$now"  ] ||
4336                 error "atime is not updated from future: $atime, $now"
4337
4338         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4339         sleep 3
4340
4341         # test setting directory atime when now > dir atime + atime_diff
4342         local d1=$(date +%s)
4343         ls $DIR/$tdir
4344         local d2=$(date +%s)
4345         cancel_lru_locks mdc
4346         atime=$(stat -c %X $DIR/$tdir)
4347         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4348                 error "atime is not updated  : $atime, should be $d2"
4349
4350         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4351         sleep 3
4352
4353         # test not setting directory atime when now < dir atime + atime_diff
4354         ls $DIR/$tdir
4355         cancel_lru_locks mdc
4356         atime=$(stat -c %X $DIR/$tdir)
4357         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4358                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4359
4360         do_facet $SINGLEMDS \
4361                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4362 }
4363 run_test 39l "directory atime update ==========================="
4364
4365 test_39m() {
4366         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4367
4368         touch $DIR1/$tfile
4369         sleep 2
4370         local far_past_mtime=$(date -d "May 29 1953" +%s)
4371         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4372
4373         touch -m -d @$far_past_mtime $DIR1/$tfile
4374         touch -a -d @$far_past_atime $DIR1/$tfile
4375
4376         for (( i=0; i < 2; i++ )) ; do
4377                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4378                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4379                         error "atime or mtime set incorrectly"
4380
4381                 cancel_lru_locks $OSC
4382                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4383         done
4384 }
4385 run_test 39m "test atime and mtime before 1970"
4386
4387 test_39n() { # LU-3832
4388         remote_mds_nodsh && skip "remote MDS with nodsh"
4389
4390         local atime_diff=$(do_facet $SINGLEMDS \
4391                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4392         local atime0
4393         local atime1
4394         local atime2
4395
4396         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4397
4398         rm -rf $DIR/$tfile
4399         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4400         atime0=$(stat -c %X $DIR/$tfile)
4401
4402         sleep 5
4403         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4404         atime1=$(stat -c %X $DIR/$tfile)
4405
4406         sleep 5
4407         cancel_lru_locks mdc
4408         cancel_lru_locks osc
4409         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4410         atime2=$(stat -c %X $DIR/$tfile)
4411
4412         do_facet $SINGLEMDS \
4413                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4414
4415         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4416         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4417 }
4418 run_test 39n "check that O_NOATIME is honored"
4419
4420 test_39o() {
4421         TESTDIR=$DIR/$tdir/$tfile
4422         [ -e $TESTDIR ] && rm -rf $TESTDIR
4423         mkdir -p $TESTDIR
4424         cd $TESTDIR
4425         links1=2
4426         ls
4427         mkdir a b
4428         ls
4429         links2=$(stat -c %h .)
4430         [ $(($links1 + 2)) != $links2 ] &&
4431                 error "wrong links count $(($links1 + 2)) != $links2"
4432         rmdir b
4433         links3=$(stat -c %h .)
4434         [ $(($links1 + 1)) != $links3 ] &&
4435                 error "wrong links count $links1 != $links3"
4436         return 0
4437 }
4438 run_test 39o "directory cached attributes updated after create"
4439
4440 test_39p() {
4441         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4442
4443         local MDTIDX=1
4444         TESTDIR=$DIR/$tdir/$tdir
4445         [ -e $TESTDIR ] && rm -rf $TESTDIR
4446         test_mkdir -p $TESTDIR
4447         cd $TESTDIR
4448         links1=2
4449         ls
4450         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4451         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4452         ls
4453         links2=$(stat -c %h .)
4454         [ $(($links1 + 2)) != $links2 ] &&
4455                 error "wrong links count $(($links1 + 2)) != $links2"
4456         rmdir remote_dir2
4457         links3=$(stat -c %h .)
4458         [ $(($links1 + 1)) != $links3 ] &&
4459                 error "wrong links count $links1 != $links3"
4460         return 0
4461 }
4462 run_test 39p "remote directory cached attributes updated after create ========"
4463
4464
4465 test_39q() { # LU-8041
4466         local testdir=$DIR/$tdir
4467         mkdir -p $testdir
4468         multiop_bg_pause $testdir D_c || error "multiop failed"
4469         local multipid=$!
4470         cancel_lru_locks mdc
4471         kill -USR1 $multipid
4472         local atime=$(stat -c %X $testdir)
4473         [ "$atime" -ne 0 ] || error "atime is zero"
4474 }
4475 run_test 39q "close won't zero out atime"
4476
4477 test_40() {
4478         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
4479         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
4480                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
4481         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
4482                 error "$tfile is not 4096 bytes in size"
4483 }
4484 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
4485
4486 test_41() {
4487         # bug 1553
4488         small_write $DIR/f41 18
4489 }
4490 run_test 41 "test small file write + fstat ====================="
4491
4492 count_ost_writes() {
4493         lctl get_param -n ${OSC}.*.stats |
4494                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
4495                         END { printf("%0.0f", writes) }'
4496 }
4497
4498 # decent default
4499 WRITEBACK_SAVE=500
4500 DIRTY_RATIO_SAVE=40
4501 MAX_DIRTY_RATIO=50
4502 BG_DIRTY_RATIO_SAVE=10
4503 MAX_BG_DIRTY_RATIO=25
4504
4505 start_writeback() {
4506         trap 0
4507         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
4508         # dirty_ratio, dirty_background_ratio
4509         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4510                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
4511                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
4512                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
4513         else
4514                 # if file not here, we are a 2.4 kernel
4515                 kill -CONT `pidof kupdated`
4516         fi
4517 }
4518
4519 stop_writeback() {
4520         # setup the trap first, so someone cannot exit the test at the
4521         # exact wrong time and mess up a machine
4522         trap start_writeback EXIT
4523         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
4524         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4525                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
4526                 sysctl -w vm.dirty_writeback_centisecs=0
4527                 sysctl -w vm.dirty_writeback_centisecs=0
4528                 # save and increase /proc/sys/vm/dirty_ratio
4529                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
4530                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
4531                 # save and increase /proc/sys/vm/dirty_background_ratio
4532                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
4533                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
4534         else
4535                 # if file not here, we are a 2.4 kernel
4536                 kill -STOP `pidof kupdated`
4537         fi
4538 }
4539
4540 # ensure that all stripes have some grant before we test client-side cache
4541 setup_test42() {
4542         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
4543                 dd if=/dev/zero of=$i bs=4k count=1
4544                 rm $i
4545         done
4546 }
4547
4548 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
4549 # file truncation, and file removal.
4550 test_42a() {
4551         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4552
4553         setup_test42
4554         cancel_lru_locks $OSC
4555         stop_writeback
4556         sync; sleep 1; sync # just to be safe
4557         BEFOREWRITES=`count_ost_writes`
4558         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
4559         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
4560         AFTERWRITES=`count_ost_writes`
4561         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
4562                 error "$BEFOREWRITES < $AFTERWRITES"
4563         start_writeback
4564 }
4565 run_test 42a "ensure that we don't flush on close"
4566
4567 test_42b() {
4568         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4569
4570         setup_test42
4571         cancel_lru_locks $OSC
4572         stop_writeback
4573         sync
4574         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
4575         BEFOREWRITES=$(count_ost_writes)
4576         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
4577         AFTERWRITES=$(count_ost_writes)
4578         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4579                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
4580         fi
4581         BEFOREWRITES=$(count_ost_writes)
4582         sync || error "sync: $?"
4583         AFTERWRITES=$(count_ost_writes)
4584         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4585                 error "$BEFOREWRITES < $AFTERWRITES on sync"
4586         fi
4587         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
4588         start_writeback
4589         return 0
4590 }
4591 run_test 42b "test destroy of file with cached dirty data ======"
4592
4593 # if these tests just want to test the effect of truncation,
4594 # they have to be very careful.  consider:
4595 # - the first open gets a {0,EOF}PR lock
4596 # - the first write conflicts and gets a {0, count-1}PW
4597 # - the rest of the writes are under {count,EOF}PW
4598 # - the open for truncate tries to match a {0,EOF}PR
4599 #   for the filesize and cancels the PWs.
4600 # any number of fixes (don't get {0,EOF} on open, match
4601 # composite locks, do smarter file size management) fix
4602 # this, but for now we want these tests to verify that
4603 # the cancellation with truncate intent works, so we
4604 # start the file with a full-file pw lock to match against
4605 # until the truncate.
4606 trunc_test() {
4607         test=$1
4608         file=$DIR/$test
4609         offset=$2
4610         cancel_lru_locks $OSC
4611         stop_writeback
4612         # prime the file with 0,EOF PW to match
4613         touch $file
4614         $TRUNCATE $file 0
4615         sync; sync
4616         # now the real test..
4617         dd if=/dev/zero of=$file bs=1024 count=100
4618         BEFOREWRITES=`count_ost_writes`
4619         $TRUNCATE $file $offset
4620         cancel_lru_locks $OSC
4621         AFTERWRITES=`count_ost_writes`
4622         start_writeback
4623 }
4624
4625 test_42c() {
4626         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4627
4628         trunc_test 42c 1024
4629         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
4630                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
4631         rm $file
4632 }
4633 run_test 42c "test partial truncate of file with cached dirty data"
4634
4635 test_42d() {
4636         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4637
4638         trunc_test 42d 0
4639         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
4640                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
4641         rm $file
4642 }
4643 run_test 42d "test complete truncate of file with cached dirty data"
4644
4645 test_42e() { # bug22074
4646         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4647
4648         local TDIR=$DIR/${tdir}e
4649         local pages=16 # hardcoded 16 pages, don't change it.
4650         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
4651         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
4652         local max_dirty_mb
4653         local warmup_files
4654
4655         test_mkdir $DIR/${tdir}e
4656         $LFS setstripe -c 1 $TDIR
4657         createmany -o $TDIR/f $files
4658
4659         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
4660
4661         # we assume that with $OSTCOUNT files, at least one of them will
4662         # be allocated on OST0.
4663         warmup_files=$((OSTCOUNT * max_dirty_mb))
4664         createmany -o $TDIR/w $warmup_files
4665
4666         # write a large amount of data into one file and sync, to get good
4667         # avail_grant number from OST.
4668         for ((i=0; i<$warmup_files; i++)); do
4669                 idx=$($LFS getstripe -i $TDIR/w$i)
4670                 [ $idx -ne 0 ] && continue
4671                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
4672                 break
4673         done
4674         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
4675         sync
4676         $LCTL get_param $proc_osc0/cur_dirty_bytes
4677         $LCTL get_param $proc_osc0/cur_grant_bytes
4678
4679         # create as much dirty pages as we can while not to trigger the actual
4680         # RPCs directly. but depends on the env, VFS may trigger flush during this
4681         # period, hopefully we are good.
4682         for ((i=0; i<$warmup_files; i++)); do
4683                 idx=$($LFS getstripe -i $TDIR/w$i)
4684                 [ $idx -ne 0 ] && continue
4685                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
4686         done
4687         $LCTL get_param $proc_osc0/cur_dirty_bytes
4688         $LCTL get_param $proc_osc0/cur_grant_bytes
4689
4690         # perform the real test
4691         $LCTL set_param $proc_osc0/rpc_stats 0
4692         for ((;i<$files; i++)); do
4693                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
4694                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
4695         done
4696         sync
4697         $LCTL get_param $proc_osc0/rpc_stats
4698
4699         local percent=0
4700         local have_ppr=false
4701         $LCTL get_param $proc_osc0/rpc_stats |
4702                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
4703                         # skip lines until we are at the RPC histogram data
4704                         [ "$PPR" == "pages" ] && have_ppr=true && continue
4705                         $have_ppr || continue
4706
4707                         # we only want the percent stat for < 16 pages
4708                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
4709
4710                         percent=$((percent + WPCT))
4711                         if [[ $percent -gt 15 ]]; then
4712                                 error "less than 16-pages write RPCs" \
4713                                       "$percent% > 15%"
4714                                 break
4715                         fi
4716                 done
4717         rm -rf $TDIR
4718 }
4719 run_test 42e "verify sub-RPC writes are not done synchronously"
4720
4721 test_43A() { # was test_43
4722         test_mkdir $DIR/$tdir
4723         cp -p /bin/ls $DIR/$tdir/$tfile
4724         $MULTIOP $DIR/$tdir/$tfile Ow_c &
4725         pid=$!
4726         # give multiop a chance to open
4727         sleep 1
4728
4729         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
4730         kill -USR1 $pid
4731 }
4732 run_test 43A "execution of file opened for write should return -ETXTBSY"
4733
4734 test_43a() {
4735         test_mkdir $DIR/$tdir
4736         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4737         $DIR/$tdir/sleep 60 &
4738         SLEEP_PID=$!
4739         # Make sure exec of $tdir/sleep wins race with truncate
4740         sleep 1
4741         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
4742         kill $SLEEP_PID
4743 }
4744 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
4745
4746 test_43b() {
4747         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4748
4749         test_mkdir $DIR/$tdir
4750         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4751         $DIR/$tdir/sleep 60 &
4752         SLEEP_PID=$!
4753         # Make sure exec of $tdir/sleep wins race with truncate
4754         sleep 1
4755         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
4756         kill $SLEEP_PID
4757 }
4758 run_test 43b "truncate of file being executed should return -ETXTBSY"
4759
4760 test_43c() {
4761         local testdir="$DIR/$tdir"
4762         test_mkdir $testdir
4763         cp $SHELL $testdir/
4764         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
4765                 ( cd $testdir && md5sum -c )
4766 }
4767 run_test 43c "md5sum of copy into lustre"
4768
4769 test_44A() { # was test_44
4770         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4771
4772         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
4773         dd if=$DIR/f1 bs=4k count=1 > /dev/null
4774 }
4775 run_test 44A "zero length read from a sparse stripe"
4776
4777 test_44a() {
4778         local nstripe=$($LCTL lov_getconfig $DIR | grep default_stripe_count: |
4779                 awk '{ print $2 }')
4780         [ -z "$nstripe" ] && skip "can't get stripe info"
4781         [[ $nstripe -gt $OSTCOUNT ]] &&
4782                 skip "Wrong default_stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
4783
4784         local stride=$($LCTL lov_getconfig $DIR | grep default_stripe_size: |
4785                 awk '{ print $2 }')
4786         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
4787                 nstripe=$($LCTL lov_getconfig $DIR | grep obd_count: |
4788                         awk '{ print $2 }')
4789         fi
4790
4791         OFFSETS="0 $((stride/2)) $((stride-1))"
4792         for offset in $OFFSETS; do
4793                 for i in $(seq 0 $((nstripe-1))); do
4794                         local GLOBALOFFSETS=""
4795                         # size in Bytes
4796                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
4797                         local myfn=$DIR/d44a-$size
4798                         echo "--------writing $myfn at $size"
4799                         ll_sparseness_write $myfn $size ||
4800                                 error "ll_sparseness_write"
4801                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
4802                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4803                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4804
4805                         for j in $(seq 0 $((nstripe-1))); do
4806                                 # size in Bytes
4807                                 size=$((((j + $nstripe )*$stride + $offset)))
4808                                 ll_sparseness_write $myfn $size ||
4809                                         error "ll_sparseness_write"
4810                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
4811                         done
4812                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4813                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4814                         rm -f $myfn
4815                 done
4816         done
4817 }
4818 run_test 44a "test sparse pwrite ==============================="
4819
4820 dirty_osc_total() {
4821         tot=0
4822         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
4823                 tot=$(($tot + $d))
4824         done
4825         echo $tot
4826 }
4827 do_dirty_record() {
4828         before=`dirty_osc_total`
4829         echo executing "\"$*\""
4830         eval $*
4831         after=`dirty_osc_total`
4832         echo before $before, after $after
4833 }
4834 test_45() {
4835         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4836
4837         f="$DIR/f45"
4838         # Obtain grants from OST if it supports it
4839         echo blah > ${f}_grant
4840         stop_writeback
4841         sync
4842         do_dirty_record "echo blah > $f"
4843         [[ $before -eq $after ]] && error "write wasn't cached"
4844         do_dirty_record "> $f"
4845         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
4846         do_dirty_record "echo blah > $f"
4847         [[ $before -eq $after ]] && error "write wasn't cached"
4848         do_dirty_record "sync"
4849         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
4850         do_dirty_record "echo blah > $f"
4851         [[ $before -eq $after ]] && error "write wasn't cached"
4852         do_dirty_record "cancel_lru_locks osc"
4853         [[ $before -gt $after ]] ||
4854                 error "lock cancellation didn't lower dirty count"
4855         start_writeback
4856 }
4857 run_test 45 "osc io page accounting ============================"
4858
4859 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
4860 # test tickles a bug where re-dirtying a page was failing to be mapped to the
4861 # objects offset and an assert hit when an rpc was built with 1023's mapped
4862 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
4863 test_46() {
4864         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4865
4866         f="$DIR/f46"
4867         stop_writeback
4868         sync
4869         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
4870         sync
4871         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
4872         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
4873         sync
4874         start_writeback
4875 }
4876 run_test 46 "dirtying a previously written page ================"
4877
4878 # test_47 is removed "Device nodes check" is moved to test_28
4879
4880 test_48a() { # bug 2399
4881         [ "$mds1_FSTYPE" = "zfs" ] &&
4882         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
4883                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
4884
4885         test_mkdir $DIR/$tdir
4886         cd $DIR/$tdir
4887         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
4888         test_mkdir $DIR/$tdir
4889         touch foo || error "'touch foo' failed after recreating cwd"
4890         test_mkdir bar
4891         touch .foo || error "'touch .foo' failed after recreating cwd"
4892         test_mkdir .bar
4893         ls . > /dev/null || error "'ls .' failed after recreating cwd"
4894         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
4895         cd . || error "'cd .' failed after recreating cwd"
4896         mkdir . && error "'mkdir .' worked after recreating cwd"
4897         rmdir . && error "'rmdir .' worked after recreating cwd"
4898         ln -s . baz || error "'ln -s .' failed after recreating cwd"
4899         cd .. || error "'cd ..' failed after recreating cwd"
4900 }
4901 run_test 48a "Access renamed working dir (should return errors)="
4902
4903 test_48b() { # bug 2399
4904         rm -rf $DIR/$tdir
4905         test_mkdir $DIR/$tdir
4906         cd $DIR/$tdir
4907         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
4908         touch foo && error "'touch foo' worked after removing cwd"
4909         mkdir foo && error "'mkdir foo' worked after removing cwd"
4910         touch .foo && error "'touch .foo' worked after removing cwd"
4911         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
4912         ls . > /dev/null && error "'ls .' worked after removing cwd"
4913         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
4914         mkdir . && error "'mkdir .' worked after removing cwd"
4915         rmdir . && error "'rmdir .' worked after removing cwd"
4916         ln -s . foo && error "'ln -s .' worked after removing cwd"
4917         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
4918 }
4919 run_test 48b "Access removed working dir (should return errors)="
4920
4921 test_48c() { # bug 2350
4922         #lctl set_param debug=-1
4923         #set -vx
4924         rm -rf $DIR/$tdir
4925         test_mkdir -p $DIR/$tdir/dir
4926         cd $DIR/$tdir/dir
4927         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4928         $TRACE touch foo && error "touch foo worked after removing cwd"
4929         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
4930         touch .foo && error "touch .foo worked after removing cwd"
4931         mkdir .foo && error "mkdir .foo worked after removing cwd"
4932         $TRACE ls . && error "'ls .' worked after removing cwd"
4933         $TRACE ls .. || error "'ls ..' failed after removing cwd"
4934         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
4935         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
4936         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
4937         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
4938 }
4939 run_test 48c "Access removed working subdir (should return errors)"
4940
4941 test_48d() { # bug 2350
4942         #lctl set_param debug=-1
4943         #set -vx
4944         rm -rf $DIR/$tdir
4945         test_mkdir -p $DIR/$tdir/dir
4946         cd $DIR/$tdir/dir
4947         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4948         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
4949         $TRACE touch foo && error "'touch foo' worked after removing parent"
4950         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
4951         touch .foo && error "'touch .foo' worked after removing parent"
4952         mkdir .foo && error "mkdir .foo worked after removing parent"
4953         $TRACE ls . && error "'ls .' worked after removing parent"
4954         $TRACE ls .. && error "'ls ..' worked after removing parent"
4955         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
4956         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
4957         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
4958         true
4959 }
4960 run_test 48d "Access removed parent subdir (should return errors)"
4961
4962 test_48e() { # bug 4134
4963         #lctl set_param debug=-1
4964         #set -vx
4965         rm -rf $DIR/$tdir
4966         test_mkdir -p $DIR/$tdir/dir
4967         cd $DIR/$tdir/dir
4968         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4969         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
4970         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
4971         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
4972         # On a buggy kernel addition of "touch foo" after cd .. will
4973         # produce kernel oops in lookup_hash_it
4974         touch ../foo && error "'cd ..' worked after recreate parent"
4975         cd $DIR
4976         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
4977 }
4978 run_test 48e "Access to recreated parent subdir (should return errors)"
4979
4980 test_49() { # LU-1030
4981         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4982         remote_ost_nodsh && skip "remote OST with nodsh"
4983
4984         # get ost1 size - lustre-OST0000
4985         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
4986                 awk '{ print $4 }')
4987         # write 800M at maximum
4988         [[ $ost1_size -lt 2 ]] && ost1_size=2
4989         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
4990
4991         $LFS setstripe -c 1 -i 0 $DIR/$tfile
4992         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
4993         local dd_pid=$!
4994
4995         # change max_pages_per_rpc while writing the file
4996         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
4997         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
4998         # loop until dd process exits
4999         while ps ax -opid | grep -wq $dd_pid; do
5000                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5001                 sleep $((RANDOM % 5 + 1))
5002         done
5003         # restore original max_pages_per_rpc
5004         $LCTL set_param $osc1_mppc=$orig_mppc
5005         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5006 }
5007 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5008
5009 test_50() {
5010         # bug 1485
5011         test_mkdir $DIR/$tdir
5012         cd $DIR/$tdir
5013         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5014 }
5015 run_test 50 "special situations: /proc symlinks  ==============="
5016
5017 test_51a() {    # was test_51
5018         # bug 1516 - create an empty entry right after ".." then split dir
5019         test_mkdir -c1 $DIR/$tdir
5020         touch $DIR/$tdir/foo
5021         $MCREATE $DIR/$tdir/bar
5022         rm $DIR/$tdir/foo
5023         createmany -m $DIR/$tdir/longfile 201
5024         FNUM=202
5025         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5026                 $MCREATE $DIR/$tdir/longfile$FNUM
5027                 FNUM=$(($FNUM + 1))
5028                 echo -n "+"
5029         done
5030         echo
5031         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5032 }
5033 run_test 51a "special situations: split htree with empty entry =="
5034
5035 cleanup_print_lfs_df () {
5036         trap 0
5037         $LFS df
5038         $LFS df -i
5039 }
5040
5041 test_51b() {
5042         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5043
5044         local dir=$DIR/$tdir
5045         local nrdirs=$((65536 + 100))
5046
5047         # cleanup the directory
5048         rm -fr $dir
5049
5050         test_mkdir -c1 $dir
5051
5052         $LFS df
5053         $LFS df -i
5054         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5055         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5056         [[ $numfree -lt $nrdirs ]] &&
5057                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5058
5059         # need to check free space for the directories as well
5060         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5061         numfree=$(( blkfree / $(fs_inode_ksize) ))
5062         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5063
5064         trap cleanup_print_lfs_df EXIT
5065
5066         # create files
5067         createmany -d $dir/d $nrdirs || {
5068                 unlinkmany $dir/d $nrdirs
5069                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5070         }
5071
5072         # really created :
5073         nrdirs=$(ls -U $dir | wc -l)
5074
5075         # unlink all but 100 subdirectories, then check it still works
5076         local left=100
5077         local delete=$((nrdirs - left))
5078
5079         $LFS df
5080         $LFS df -i
5081
5082         # for ldiskfs the nlink count should be 1, but this is OSD specific
5083         # and so this is listed for informational purposes only
5084         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5085         unlinkmany -d $dir/d $delete ||
5086                 error "unlink of first $delete subdirs failed"
5087
5088         echo "nlink between: $(stat -c %h $dir)"
5089         local found=$(ls -U $dir | wc -l)
5090         [ $found -ne $left ] &&
5091                 error "can't find subdirs: found only $found, expected $left"
5092
5093         unlinkmany -d $dir/d $delete $left ||
5094                 error "unlink of second $left subdirs failed"
5095         # regardless of whether the backing filesystem tracks nlink accurately
5096         # or not, the nlink count shouldn't be more than "." and ".." here
5097         local after=$(stat -c %h $dir)
5098         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5099                 echo "nlink after: $after"
5100
5101         cleanup_print_lfs_df
5102 }
5103 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5104
5105 test_51d() {
5106         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5107         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5108
5109         test_mkdir $DIR/$tdir
5110         createmany -o $DIR/$tdir/t- 1000
5111         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5112         for N in $(seq 0 $((OSTCOUNT - 1))); do
5113                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
5114                         END { printf("%0.0f", objs) }' $TMP/$tfile)
5115                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5116                         '($1 == '$N') { objs += 1 } \
5117                         END { printf("%0.0f", objs) }')
5118                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
5119         done
5120         unlinkmany $DIR/$tdir/t- 1000
5121
5122         NLAST=0
5123         for N in $(seq 1 $((OSTCOUNT - 1))); do
5124                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
5125                         error "OST $N has less objects vs OST $NLAST" \
5126                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5127                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
5128                         error "OST $N has less objects vs OST $NLAST" \
5129                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5130
5131                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
5132                         error "OST $N has less #0 objects vs OST $NLAST" \
5133                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5134                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
5135                         error "OST $N has less #0 objects vs OST $NLAST" \
5136                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5137                 NLAST=$N
5138         done
5139         rm -f $TMP/$tfile
5140 }
5141 run_test 51d "check object distribution"
5142
5143 test_51e() {
5144         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5145                 skip_env "ldiskfs only test"
5146         fi
5147
5148         test_mkdir -c1 $DIR/$tdir
5149         test_mkdir -c1 $DIR/$tdir/d0
5150
5151         touch $DIR/$tdir/d0/foo
5152         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5153                 error "file exceed 65000 nlink limit!"
5154         unlinkmany $DIR/$tdir/d0/f- 65001
5155         return 0
5156 }
5157 run_test 51e "check file nlink limit"
5158
5159 test_51f() {
5160         test_mkdir $DIR/$tdir
5161
5162         local max=100000
5163         local ulimit_old=$(ulimit -n)
5164         local spare=20 # number of spare fd's for scripts/libraries, etc.
5165         local mdt=$($LFS getstripe -m $DIR/$tdir)
5166         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5167
5168         echo "MDT$mdt numfree=$numfree, max=$max"
5169         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5170         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5171                 while ! ulimit -n $((numfree + spare)); do
5172                         numfree=$((numfree * 3 / 4))
5173                 done
5174                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5175         else
5176                 echo "left ulimit at $ulimit_old"
5177         fi
5178
5179         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5180                 unlinkmany $DIR/$tdir/f $numfree
5181                 error "create+open $numfree files in $DIR/$tdir failed"
5182         }
5183         ulimit -n $ulimit_old
5184
5185         # if createmany exits at 120s there will be fewer than $numfree files
5186         unlinkmany $DIR/$tdir/f $numfree || true
5187 }
5188 run_test 51f "check many open files limit"
5189
5190 test_52a() {
5191         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5192         test_mkdir $DIR/$tdir
5193         touch $DIR/$tdir/foo
5194         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5195         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5196         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5197         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5198         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5199                                         error "link worked"
5200         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5201         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5202         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5203                                                      error "lsattr"
5204         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5205         cp -r $DIR/$tdir $TMP/
5206         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5207 }
5208 run_test 52a "append-only flag test (should return errors)"
5209
5210 test_52b() {
5211         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5212         test_mkdir $DIR/$tdir
5213         touch $DIR/$tdir/foo
5214         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5215         cat test > $DIR/$tdir/foo && error "cat test worked"
5216         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5217         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5218         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5219                                         error "link worked"
5220         echo foo >> $DIR/$tdir/foo && error "echo worked"
5221         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5222         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5223         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5224         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5225                                                         error "lsattr"
5226         chattr -i $DIR/$tdir/foo || error "chattr failed"
5227
5228         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5229 }
5230 run_test 52b "immutable flag test (should return errors) ======="
5231
5232 test_53() {
5233         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5234         remote_mds_nodsh && skip "remote MDS with nodsh"
5235         remote_ost_nodsh && skip "remote OST with nodsh"
5236
5237         local param
5238         local param_seq
5239         local ostname
5240         local mds_last
5241         local mds_last_seq
5242         local ost_last
5243         local ost_last_seq
5244         local ost_last_id
5245         local ostnum
5246         local node
5247         local found=false
5248         local support_last_seq=true
5249
5250         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5251                 support_last_seq=false
5252
5253         # only test MDT0000
5254         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5255         local value
5256         for value in $(do_facet $SINGLEMDS \
5257                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5258                 param=$(echo ${value[0]} | cut -d "=" -f1)
5259                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5260
5261                 if $support_last_seq; then
5262                         param_seq=$(echo $param |
5263                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5264                         mds_last_seq=$(do_facet $SINGLEMDS \
5265                                        $LCTL get_param -n $param_seq)
5266                 fi
5267                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5268
5269                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5270                 node=$(facet_active_host ost$((ostnum+1)))
5271                 param="obdfilter.$ostname.last_id"
5272                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5273                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5274                         ost_last_id=$ost_last
5275
5276                         if $support_last_seq; then
5277                                 ost_last_id=$(echo $ost_last |
5278                                               awk -F':' '{print $2}' |
5279                                               sed -e "s/^0x//g")
5280                                 ost_last_seq=$(echo $ost_last |
5281                                                awk -F':' '{print $1}')
5282                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5283                         fi
5284
5285                         if [[ $ost_last_id != $mds_last ]]; then
5286                                 error "$ost_last_id != $mds_last"
5287                         else
5288                                 found=true
5289                                 break
5290                         fi
5291                 done
5292         done
5293         $found || error "can not match last_seq/last_id for $mdtosc"
5294         return 0
5295 }
5296 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5297
5298 test_54a() {
5299         perl -MSocket -e ';' || skip "no Socket perl module installed"
5300
5301         $SOCKETSERVER $DIR/socket ||
5302                 error "$SOCKETSERVER $DIR/socket failed: $?"
5303         $SOCKETCLIENT $DIR/socket ||
5304                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5305         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5306 }
5307 run_test 54a "unix domain socket test =========================="
5308
5309 test_54b() {
5310         f="$DIR/f54b"
5311         mknod $f c 1 3
5312         chmod 0666 $f
5313         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5314 }
5315 run_test 54b "char device works in lustre ======================"
5316
5317 find_loop_dev() {
5318         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5319         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5320         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5321
5322         for i in $(seq 3 7); do
5323                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5324                 LOOPDEV=$LOOPBASE$i
5325                 LOOPNUM=$i
5326                 break
5327         done
5328 }
5329
5330 cleanup_54c() {
5331         local rc=0
5332         loopdev="$DIR/loop54c"
5333
5334         trap 0
5335         $UMOUNT $DIR/$tdir || rc=$?
5336         losetup -d $loopdev || true
5337         losetup -d $LOOPDEV || true
5338         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5339         return $rc
5340 }
5341
5342 test_54c() {
5343         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5344
5345         loopdev="$DIR/loop54c"
5346
5347         find_loop_dev
5348         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5349         trap cleanup_54c EXIT
5350         mknod $loopdev b 7 $LOOPNUM
5351         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5352         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5353         losetup $loopdev $DIR/$tfile ||
5354                 error "can't set up $loopdev for $DIR/$tfile"
5355         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5356         test_mkdir $DIR/$tdir
5357         mount -t ext2 $loopdev $DIR/$tdir ||
5358                 error "error mounting $loopdev on $DIR/$tdir"
5359         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5360                 error "dd write"
5361         df $DIR/$tdir
5362         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5363                 error "dd read"
5364         cleanup_54c
5365 }
5366 run_test 54c "block device works in lustre ====================="
5367
5368 test_54d() {
5369         f="$DIR/f54d"
5370         string="aaaaaa"
5371         mknod $f p
5372         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5373 }
5374 run_test 54d "fifo device works in lustre ======================"
5375
5376 test_54e() {
5377         f="$DIR/f54e"
5378         string="aaaaaa"
5379         cp -aL /dev/console $f
5380         echo $string > $f || error "echo $string to $f failed"
5381 }
5382 run_test 54e "console/tty device works in lustre ======================"
5383
5384 test_56a() {
5385         local numfiles=3
5386         local dir=$DIR/$tdir
5387
5388         rm -rf $dir
5389         test_mkdir -p $dir/dir
5390         for i in $(seq $numfiles); do
5391                 touch $dir/file$i
5392                 touch $dir/dir/file$i
5393         done
5394
5395         local numcomp=$($LFS getstripe --component-count $dir)
5396
5397         [[ $numcomp == 0 ]] && numcomp=1
5398
5399         # test lfs getstripe with --recursive
5400         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5401
5402         [[ $filenum -eq $((numfiles * 2)) ]] ||
5403                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5404         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5405         [[ $filenum -eq $numfiles ]] ||
5406                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5407         echo "$LFS getstripe showed obdidx or l_ost_idx"
5408
5409         # test lfs getstripe with file instead of dir
5410         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5411         [[ $filenum -eq 1 ]] ||
5412                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5413         echo "$LFS getstripe file1 passed"
5414
5415         #test lfs getstripe with --verbose
5416         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5417         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5418                 error "$LFS getstripe --verbose $dir: "\
5419                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5420         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5421                 error "$LFS getstripe $dir: showed lmm_magic"
5422
5423         #test lfs getstripe with -v prints lmm_fid
5424         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5425         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5426                 error "$LFS getstripe -v $dir: "\
5427                       "got $filenum want $((numfiles * numcomp)) lmm_fid"
5428         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5429                 error "$LFS getstripe $dir: showed lmm_fid by default"
5430         echo "$LFS getstripe --verbose passed"
5431
5432         #check for FID information
5433         local fid1=$($LFS getstripe --fid $dir/file1)
5434         local fid2=$($LFS getstripe --verbose $dir/file1 |
5435                      awk '/lmm_fid: / { print $2; exit; }')
5436         local fid3=$($LFS path2fid $dir/file1)
5437
5438         [ "$fid1" != "$fid2" ] &&
5439                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5440         [ "$fid1" != "$fid3" ] &&
5441                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5442         echo "$LFS getstripe --fid passed"
5443
5444         #test lfs getstripe with --obd
5445         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
5446                 error "$LFS getstripe --obd wrong_uuid: should return error"
5447
5448         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5449
5450         local ostidx=1
5451         local obduuid=$(ostuuid_from_index $ostidx)
5452         local found=$($LFS getstripe -r --obd $obduuid $dir |
5453                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
5454
5455         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
5456         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
5457                 ((filenum--))
5458         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
5459                 ((filenum--))
5460
5461         [[ $found -eq $filenum ]] ||
5462                 error "$LFS getstripe --obd: found $found expect $filenum"
5463         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
5464                 sed '/^[         ]*'${ostidx}'[  ]/d' |
5465                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
5466                 error "$LFS getstripe --obd: should not show file on other obd"
5467         echo "$LFS getstripe --obd passed"
5468 }
5469 run_test 56a "check $LFS getstripe"
5470
5471 test_56b() {
5472         local dir=$DIR/$tdir
5473         local numdirs=3
5474
5475         test_mkdir $dir
5476         for i in $(seq $numdirs); do
5477                 test_mkdir $dir/dir$i
5478         done
5479
5480         # test lfs getdirstripe default mode is non-recursion, which is
5481         # different from lfs getstripe
5482         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
5483
5484         [[ $dircnt -eq 1 ]] ||
5485                 error "$LFS getdirstripe: found $dircnt, not 1"
5486         dircnt=$($LFS getdirstripe --recursive $dir |
5487                 grep -c lmv_stripe_count)
5488         [[ $dircnt -eq $((numdirs + 1)) ]] ||
5489                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
5490 }
5491 run_test 56b "check $LFS getdirstripe"
5492
5493 test_56c() {
5494         remote_ost_nodsh && skip "remote OST with nodsh"
5495
5496         local ost_idx=0
5497         local ost_name=$(ostname_from_index $ost_idx)
5498         local old_status=$(ost_dev_status $ost_idx)
5499
5500         [[ -z "$old_status" ]] ||
5501                 skip_env "OST $ost_name is in $old_status status"
5502
5503         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
5504         [[ $OST1_VERSION -ge $(version_code 2.12.55) ]] && do_facet ost1 \
5505                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
5506         sleep_maxage
5507
5508         local new_status=$(ost_dev_status $ost_idx)
5509
5510         [[ "$new_status" =~ "D" ]] ||
5511                 error "$ost_name status is '$new_status', missing 'D'"
5512         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
5513                 [[ "$new_status" =~ "N" ]] ||
5514                         error "$ost_name status is '$new_status', missing 'N'"
5515         fi
5516
5517         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
5518         [[ $OST1_VERSION -ge $(version_code 2.12.55) ]] && do_facet ost1 \
5519                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
5520         sleep_maxage
5521
5522         new_status=$(ost_dev_status $ost_idx)
5523         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
5524                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
5525 }
5526 run_test 56c "check 'lfs df' showing device status"
5527
5528 NUMFILES=3
5529 NUMDIRS=3
5530 setup_56() {
5531         local local_tdir="$1"
5532         local local_numfiles="$2"
5533         local local_numdirs="$3"
5534         local dir_params="$4"
5535         local dir_stripe_params="$5"
5536
5537         if [ ! -d "$local_tdir" ] ; then
5538                 test_mkdir -p $dir_stripe_params $local_tdir
5539                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
5540                 for i in $(seq $local_numfiles) ; do
5541                         touch $local_tdir/file$i
5542                 done
5543                 for i in $(seq $local_numdirs) ; do
5544                         test_mkdir $dir_stripe_params $local_tdir/dir$i
5545                         for j in $(seq $local_numfiles) ; do
5546                                 touch $local_tdir/dir$i/file$j
5547                         done
5548                 done
5549         fi
5550 }
5551
5552 setup_56_special() {
5553         local local_tdir=$1
5554         local local_numfiles=$2
5555         local local_numdirs=$3
5556
5557         setup_56 $local_tdir $local_numfiles $local_numdirs
5558
5559         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
5560                 for i in $(seq $local_numfiles) ; do
5561                         mknod $local_tdir/loop${i}b b 7 $i
5562                         mknod $local_tdir/null${i}c c 1 3
5563                         ln -s $local_tdir/file1 $local_tdir/link${i}
5564                 done
5565                 for i in $(seq $local_numdirs) ; do
5566                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
5567                         mknod $local_tdir/dir$i/null${i}c c 1 3
5568                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
5569                 done
5570         fi
5571 }
5572
5573 test_56g() {
5574         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5575         local expected=$(($NUMDIRS + 2))
5576
5577         setup_56 $dir $NUMFILES $NUMDIRS
5578
5579         # test lfs find with -name
5580         for i in $(seq $NUMFILES) ; do
5581                 local nums=$($LFS find -name "*$i" $dir | wc -l)
5582
5583                 [ $nums -eq $expected ] ||
5584                         error "lfs find -name '*$i' $dir wrong: "\
5585                               "found $nums, expected $expected"
5586         done
5587 }
5588 run_test 56g "check lfs find -name"
5589
5590 test_56h() {
5591         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5592         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
5593
5594         setup_56 $dir $NUMFILES $NUMDIRS
5595
5596         # test lfs find with ! -name
5597         for i in $(seq $NUMFILES) ; do
5598                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
5599
5600                 [ $nums -eq $expected ] ||
5601                         error "lfs find ! -name '*$i' $dir wrong: "\
5602                               "found $nums, expected $expected"
5603         done
5604 }
5605 run_test 56h "check lfs find ! -name"
5606
5607 test_56i() {
5608         local dir=$DIR/$tdir
5609
5610         test_mkdir $dir
5611
5612         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
5613         local out=$($cmd)
5614
5615         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
5616 }
5617 run_test 56i "check 'lfs find -ost UUID' skips directories"
5618
5619 test_56j() {
5620         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5621
5622         setup_56_special $dir $NUMFILES $NUMDIRS
5623
5624         local expected=$((NUMDIRS + 1))
5625         local cmd="$LFS find -type d $dir"
5626         local nums=$($cmd | wc -l)
5627
5628         [ $nums -eq $expected ] ||
5629                 error "'$cmd' wrong: found $nums, expected $expected"
5630 }
5631 run_test 56j "check lfs find -type d"
5632
5633 test_56k() {
5634         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5635
5636         setup_56_special $dir $NUMFILES $NUMDIRS
5637
5638         local expected=$(((NUMDIRS + 1) * NUMFILES))
5639         local cmd="$LFS find -type f $dir"
5640         local nums=$($cmd | wc -l)
5641
5642         [ $nums -eq $expected ] ||
5643                 error "'$cmd' wrong: found $nums, expected $expected"
5644 }
5645 run_test 56k "check lfs find -type f"
5646
5647 test_56l() {
5648         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5649
5650         setup_56_special $dir $NUMFILES $NUMDIRS
5651
5652         local expected=$((NUMDIRS + NUMFILES))
5653         local cmd="$LFS find -type b $dir"
5654         local nums=$($cmd | wc -l)
5655
5656         [ $nums -eq $expected ] ||
5657                 error "'$cmd' wrong: found $nums, expected $expected"
5658 }
5659 run_test 56l "check lfs find -type b"
5660
5661 test_56m() {
5662         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5663
5664         setup_56_special $dir $NUMFILES $NUMDIRS
5665
5666         local expected=$((NUMDIRS + NUMFILES))
5667         local cmd="$LFS find -type c $dir"
5668         local nums=$($cmd | wc -l)
5669         [ $nums -eq $expected ] ||
5670                 error "'$cmd' wrong: found $nums, expected $expected"
5671 }
5672 run_test 56m "check lfs find -type c"
5673
5674 test_56n() {
5675         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5676         setup_56_special $dir $NUMFILES $NUMDIRS
5677
5678         local expected=$((NUMDIRS + NUMFILES))
5679         local cmd="$LFS find -type l $dir"
5680         local nums=$($cmd | wc -l)
5681
5682         [ $nums -eq $expected ] ||
5683                 error "'$cmd' wrong: found $nums, expected $expected"
5684 }
5685 run_test 56n "check lfs find -type l"
5686
5687 test_56o() {
5688         local dir=$DIR/$tdir
5689
5690         setup_56 $dir $NUMFILES $NUMDIRS
5691         utime $dir/file1 > /dev/null || error "utime (1)"
5692         utime $dir/file2 > /dev/null || error "utime (2)"
5693         utime $dir/dir1 > /dev/null || error "utime (3)"
5694         utime $dir/dir2 > /dev/null || error "utime (4)"
5695         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
5696         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
5697
5698         local expected=4
5699         local nums=$($LFS find -mtime +0 $dir | wc -l)
5700
5701         [ $nums -eq $expected ] ||
5702                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
5703
5704         expected=12
5705         cmd="$LFS find -mtime 0 $dir"
5706         nums=$($cmd | wc -l)
5707         [ $nums -eq $expected ] ||
5708                 error "'$cmd' wrong: found $nums, expected $expected"
5709 }
5710 run_test 56o "check lfs find -mtime for old files"
5711
5712 test_56ob() {
5713         local dir=$DIR/$tdir
5714         local expected=1
5715         local count=0
5716
5717         # just to make sure there is something that won't be found
5718         test_mkdir $dir
5719         touch $dir/$tfile.now
5720
5721         for age in year week day hour min; do
5722                 count=$((count + 1))
5723
5724                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
5725                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
5726                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
5727
5728                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
5729                 local nums=$($cmd | wc -l)
5730                 [ $nums -eq $expected ] ||
5731                         error "'$cmd' wrong: found $nums, expected $expected"
5732
5733                 cmd="$LFS find $dir -atime $count${age:0:1}"
5734                 nums=$($cmd | wc -l)
5735                 [ $nums -eq $expected ] ||
5736                         error "'$cmd' wrong: found $nums, expected $expected"
5737         done
5738
5739         sleep 2
5740         cmd="$LFS find $dir -ctime +1s -type f"
5741         nums=$($cmd | wc -l)
5742         (( $nums == $count * 2 + 1)) ||
5743                 error "'$cmd' wrong: found $nums, expected $((expected*2+1))"
5744 }
5745 run_test 56ob "check lfs find -atime -mtime -ctime with units"
5746
5747 test_56p() {
5748         [ $RUNAS_ID -eq $UID ] &&
5749                 skip_env "RUNAS_ID = UID = $UID -- skipping"
5750
5751         local dir=$DIR/$tdir
5752
5753         setup_56 $dir $NUMFILES $NUMDIRS
5754         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
5755
5756         local expected=$NUMFILES
5757         local cmd="$LFS find -uid $RUNAS_ID $dir"
5758         local nums=$($cmd | wc -l)
5759
5760         [ $nums -eq $expected ] ||
5761                 error "'$cmd' wrong: found $nums, expected $expected"
5762
5763         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
5764         cmd="$LFS find ! -uid $RUNAS_ID $dir"
5765         nums=$($cmd | wc -l)
5766         [ $nums -eq $expected ] ||
5767                 error "'$cmd' wrong: found $nums, expected $expected"
5768 }
5769 run_test 56p "check lfs find -uid and ! -uid"
5770
5771 test_56q() {
5772         [ $RUNAS_ID -eq $UID ] &&
5773                 skip_env "RUNAS_ID = UID = $UID -- skipping"
5774
5775         local dir=$DIR/$tdir
5776
5777         setup_56 $dir $NUMFILES $NUMDIRS
5778         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
5779
5780         local expected=$NUMFILES
5781         local cmd="$LFS find -gid $RUNAS_GID $dir"
5782         local nums=$($cmd | wc -l)
5783
5784         [ $nums -eq $expected ] ||
5785                 error "'$cmd' wrong: found $nums, expected $expected"
5786
5787         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
5788         cmd="$LFS find ! -gid $RUNAS_GID $dir"
5789         nums=$($cmd | wc -l)
5790         [ $nums -eq $expected ] ||
5791                 error "'$cmd' wrong: found $nums, expected $expected"
5792 }
5793 run_test 56q "check lfs find -gid and ! -gid"
5794
5795 test_56r() {
5796         local dir=$DIR/$tdir
5797
5798         setup_56 $dir $NUMFILES $NUMDIRS
5799
5800         local expected=12
5801         local cmd="$LFS find -size 0 -type f -lazy $dir"
5802         local nums=$($cmd | wc -l)
5803
5804         [ $nums -eq $expected ] ||
5805                 error "'$cmd' wrong: found $nums, expected $expected"
5806         cmd="$LFS find -size 0 -type f $dir"
5807         nums=$($cmd | wc -l)
5808         [ $nums -eq $expected ] ||
5809                 error "'$cmd' wrong: found $nums, expected $expected"
5810
5811         expected=0
5812         cmd="$LFS find ! -size 0 -type f -lazy $dir"
5813         nums=$($cmd | wc -l)
5814         [ $nums -eq $expected ] ||
5815                 error "'$cmd' wrong: found $nums, expected $expected"
5816         cmd="$LFS find ! -size 0 -type f $dir"
5817         nums=$($cmd | wc -l)
5818         [ $nums -eq $expected ] ||
5819                 error "'$cmd' wrong: found $nums, expected $expected"
5820
5821         echo "test" > $dir/$tfile
5822         echo "test2" > $dir/$tfile.2 && sync
5823         expected=1
5824         cmd="$LFS find -size 5 -type f -lazy $dir"
5825         nums=$($cmd | wc -l)
5826         [ $nums -eq $expected ] ||
5827                 error "'$cmd' wrong: found $nums, expected $expected"
5828         cmd="$LFS find -size 5 -type f $dir"
5829         nums=$($cmd | wc -l)
5830         [ $nums -eq $expected ] ||
5831                 error "'$cmd' wrong: found $nums, expected $expected"
5832
5833         expected=1
5834         cmd="$LFS find -size +5 -type f -lazy $dir"
5835         nums=$($cmd | wc -l)
5836         [ $nums -eq $expected ] ||
5837                 error "'$cmd' wrong: found $nums, expected $expected"
5838         cmd="$LFS find -size +5 -type f $dir"
5839         nums=$($cmd | wc -l)
5840         [ $nums -eq $expected ] ||
5841                 error "'$cmd' wrong: found $nums, expected $expected"
5842
5843         expected=2
5844         cmd="$LFS find -size +0 -type f -lazy $dir"
5845         nums=$($cmd | wc -l)
5846         [ $nums -eq $expected ] ||
5847                 error "'$cmd' wrong: found $nums, expected $expected"
5848         cmd="$LFS find -size +0 -type f $dir"
5849         nums=$($cmd | wc -l)
5850         [ $nums -eq $expected ] ||
5851                 error "'$cmd' wrong: found $nums, expected $expected"
5852
5853         expected=2
5854         cmd="$LFS find ! -size -5 -type f -lazy $dir"
5855         nums=$($cmd | wc -l)
5856         [ $nums -eq $expected ] ||
5857                 error "'$cmd' wrong: found $nums, expected $expected"
5858         cmd="$LFS find ! -size -5 -type f $dir"
5859         nums=$($cmd | wc -l)
5860         [ $nums -eq $expected ] ||
5861                 error "'$cmd' wrong: found $nums, expected $expected"
5862
5863         expected=12
5864         cmd="$LFS find -size -5 -type f -lazy $dir"
5865         nums=$($cmd | wc -l)
5866         [ $nums -eq $expected ] ||
5867                 error "'$cmd' wrong: found $nums, expected $expected"
5868         cmd="$LFS find -size -5 -type f $dir"
5869         nums=$($cmd | wc -l)
5870         [ $nums -eq $expected ] ||
5871                 error "'$cmd' wrong: found $nums, expected $expected"
5872 }
5873 run_test 56r "check lfs find -size works"
5874
5875 test_56ra() {
5876         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
5877                 skip "MDS < 2.12.58 doesn't return LSOM data"
5878         local dir=$DIR/$tdir
5879
5880         [[ $OSC == "mdc" ]] && skip "DoM files" && return
5881
5882         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
5883
5884         cancel_lru_locks $OSC
5885
5886         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5887         local expected=12
5888         local cmd="$LFS find -size 0 -type f -lazy $dir"
5889         local nums=$($cmd | wc -l)
5890
5891         [ $nums -eq $expected ] ||
5892                 error "'$cmd' wrong: found $nums, expected $expected"
5893
5894         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5895         [ $rpcs_before -eq $rpcs_after ] ||
5896                 error "'$cmd' should not send glimpse RPCs to OST"
5897         cmd="$LFS find -size 0 -type f $dir"
5898         nums=$($cmd | wc -l)
5899         [ $nums -eq $expected ] ||
5900                 error "'$cmd' wrong: found $nums, expected $expected"
5901         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5902         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
5903         $LCTL get_param osc.*.stats
5904         [ $rpcs_after -eq $((rpcs_before + 12)) ] ||
5905                 error "'$cmd' should send 12 glimpse RPCs to OST"
5906
5907         cancel_lru_locks $OSC
5908         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5909         expected=0
5910         cmd="$LFS find ! -size 0 -type f -lazy $dir"
5911         nums=$($cmd | wc -l)
5912         [ $nums -eq $expected ] ||
5913                 error "'$cmd' wrong: found $nums, expected $expected"
5914         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5915         $LCTL get_param mdc.*.stats
5916         [ $rpcs_before -eq $rpcs_after ] ||
5917                 error "'$cmd' should not send glimpse RPCs to OST"
5918         cmd="$LFS find ! -size 0 -type f $dir"
5919         nums=$($cmd | wc -l)
5920         [ $nums -eq $expected ] ||
5921                 error "'$cmd' wrong: found $nums, expected $expected"
5922         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5923         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
5924         [ $rpcs_after -eq $((rpcs_before + 12)) ] ||
5925                 error "'$cmd' should send 12 glimpse RPCs to OST"
5926
5927         echo "test" > $dir/$tfile
5928         echo "test2" > $dir/$tfile.2 && sync
5929         cancel_lru_locks $OSC
5930         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5931         expected=1
5932         cmd="$LFS find -size 5 -type f -lazy $dir"
5933         nums=$($cmd | wc -l)
5934         [ $nums -eq $expected ] ||
5935                 error "'$cmd' wrong: found $nums, expected $expected"
5936         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5937         [ $rpcs_before -eq $rpcs_after ] ||
5938                 error "'$cmd' should not send glimpse RPCs to OST"
5939         cmd="$LFS find -size 5 -type f $dir"
5940         nums=$($cmd | wc -l)
5941         [ $nums -eq $expected ] ||
5942                 error "'$cmd' wrong: found $nums, expected $expected"
5943         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5944         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
5945         [ $rpcs_after -eq $((rpcs_before + 14)) ] ||
5946                 error "'$cmd' should send 14 glimpse RPCs to OST"
5947
5948         cancel_lru_locks $OSC
5949         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5950         expected=1
5951         cmd="$LFS find -size +5 -type f -lazy $dir"
5952         nums=$($cmd | wc -l)
5953         [ $nums -eq $expected ] ||
5954                 error "'$cmd' wrong: found $nums, expected $expected"
5955         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5956         [ $rpcs_before -eq $rpcs_after ] ||
5957                 error "'$cmd' should not send glimpse RPCs to OST"
5958         cmd="$LFS find -size +5 -type f $dir"
5959         nums=$($cmd | wc -l)
5960         [ $nums -eq $expected ] ||
5961                 error "'$cmd' wrong: found $nums, expected $expected"
5962         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5963         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
5964         [ $rpcs_after -eq $((rpcs_before + 14)) ] ||
5965                 error "'$cmd' should send 14 glimpse RPCs to OST"
5966
5967         cancel_lru_locks $OSC
5968         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5969         expected=2
5970         cmd="$LFS find -size +0 -type f -lazy $dir"
5971         nums=$($cmd | wc -l)
5972         [ $nums -eq $expected ] ||
5973                 error "'$cmd' wrong: found $nums, expected $expected"
5974         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5975         [ $rpcs_before -eq $rpcs_after ] ||
5976                 error "'$cmd' should not send glimpse RPCs to OST"
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         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5982         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
5983         [ $rpcs_after -eq $((rpcs_before + 14)) ] ||
5984                 error "'$cmd' should send 14 glimpse RPCs to OST"
5985
5986         cancel_lru_locks $OSC
5987         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5988         expected=2
5989         cmd="$LFS find ! -size -5 -type f -lazy $dir"
5990         nums=$($cmd | wc -l)
5991         [ $nums -eq $expected ] ||
5992                 error "'$cmd' wrong: found $nums, expected $expected"
5993         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5994         [ $rpcs_before -eq $rpcs_after ] ||
5995                 error "'$cmd' should not send glimpse RPCs to OST"
5996         cmd="$LFS find ! -size -5 -type f $dir"
5997         nums=$($cmd | wc -l)
5998         [ $nums -eq $expected ] ||
5999                 error "'$cmd' wrong: found $nums, expected $expected"
6000         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6001         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6002         [ $rpcs_after -eq $((rpcs_before + 14)) ] ||
6003                 error "'$cmd' should send 14 glimpse RPCs to OST"
6004
6005         cancel_lru_locks $OSC
6006         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6007         expected=12
6008         cmd="$LFS find -size -5 -type f -lazy $dir"
6009         nums=$($cmd | wc -l)
6010         [ $nums -eq $expected ] ||
6011                 error "'$cmd' wrong: found $nums, expected $expected"
6012         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6013         [ $rpcs_before -eq $rpcs_after ] ||
6014                 error "'$cmd' should not send glimpse RPCs to OST"
6015         cmd="$LFS find -size -5 -type f $dir"
6016         nums=$($cmd | wc -l)
6017         [ $nums -eq $expected ] ||
6018                 error "'$cmd' wrong: found $nums, expected $expected"
6019         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6020         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6021         [ $rpcs_after -eq $((rpcs_before + 14)) ] ||
6022                 error "'$cmd' should send 14 glimpse RPCs to OST"
6023 }
6024 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6025
6026 test_56s() { # LU-611 #LU-9369
6027         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6028
6029         local dir=$DIR/$tdir
6030         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6031
6032         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6033         for i in $(seq $NUMDIRS); do
6034                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6035         done
6036
6037         local expected=$NUMDIRS
6038         local cmd="$LFS find -c $OSTCOUNT $dir"
6039         local nums=$($cmd | wc -l)
6040
6041         [ $nums -eq $expected ] || {
6042                 $LFS getstripe -R $dir
6043                 error "'$cmd' wrong: found $nums, expected $expected"
6044         }
6045
6046         expected=$((NUMDIRS + onestripe))
6047         cmd="$LFS find -stripe-count +0 -type f $dir"
6048         nums=$($cmd | wc -l)
6049         [ $nums -eq $expected ] || {
6050                 $LFS getstripe -R $dir
6051                 error "'$cmd' wrong: found $nums, expected $expected"
6052         }
6053
6054         expected=$onestripe
6055         cmd="$LFS find -stripe-count 1 -type f $dir"
6056         nums=$($cmd | wc -l)
6057         [ $nums -eq $expected ] || {
6058                 $LFS getstripe -R $dir
6059                 error "'$cmd' wrong: found $nums, expected $expected"
6060         }
6061
6062         cmd="$LFS find -stripe-count -2 -type f $dir"
6063         nums=$($cmd | wc -l)
6064         [ $nums -eq $expected ] || {
6065                 $LFS getstripe -R $dir
6066                 error "'$cmd' wrong: found $nums, expected $expected"
6067         }
6068
6069         expected=0
6070         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6071         nums=$($cmd | wc -l)
6072         [ $nums -eq $expected ] || {
6073                 $LFS getstripe -R $dir
6074                 error "'$cmd' wrong: found $nums, expected $expected"
6075         }
6076 }
6077 run_test 56s "check lfs find -stripe-count works"
6078
6079 test_56t() { # LU-611 #LU-9369
6080         local dir=$DIR/$tdir
6081
6082         setup_56 $dir 0 $NUMDIRS
6083         for i in $(seq $NUMDIRS); do
6084                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6085         done
6086
6087         local expected=$NUMDIRS
6088         local cmd="$LFS find -S 8M $dir"
6089         local nums=$($cmd | wc -l)
6090
6091         [ $nums -eq $expected ] || {
6092                 $LFS getstripe -R $dir
6093                 error "'$cmd' wrong: found $nums, expected $expected"
6094         }
6095         rm -rf $dir
6096
6097         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6098
6099         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6100
6101         expected=$(((NUMDIRS + 1) * NUMFILES))
6102         cmd="$LFS find -stripe-size 512k -type f $dir"
6103         nums=$($cmd | wc -l)
6104         [ $nums -eq $expected ] ||
6105                 error "'$cmd' wrong: found $nums, expected $expected"
6106
6107         cmd="$LFS find -stripe-size +320k -type f $dir"
6108         nums=$($cmd | wc -l)
6109         [ $nums -eq $expected ] ||
6110                 error "'$cmd' wrong: found $nums, expected $expected"
6111
6112         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6113         cmd="$LFS find -stripe-size +200k -type f $dir"
6114         nums=$($cmd | wc -l)
6115         [ $nums -eq $expected ] ||
6116                 error "'$cmd' wrong: found $nums, expected $expected"
6117
6118         cmd="$LFS find -stripe-size -640k -type f $dir"
6119         nums=$($cmd | wc -l)
6120         [ $nums -eq $expected ] ||
6121                 error "'$cmd' wrong: found $nums, expected $expected"
6122
6123         expected=4
6124         cmd="$LFS find -stripe-size 256k -type f $dir"
6125         nums=$($cmd | wc -l)
6126         [ $nums -eq $expected ] ||
6127                 error "'$cmd' wrong: found $nums, expected $expected"
6128
6129         cmd="$LFS find -stripe-size -320k -type f $dir"
6130         nums=$($cmd | wc -l)
6131         [ $nums -eq $expected ] ||
6132                 error "'$cmd' wrong: found $nums, expected $expected"
6133
6134         expected=0
6135         cmd="$LFS find -stripe-size 1024k -type f $dir"
6136         nums=$($cmd | wc -l)
6137         [ $nums -eq $expected ] ||
6138                 error "'$cmd' wrong: found $nums, expected $expected"
6139 }
6140 run_test 56t "check lfs find -stripe-size works"
6141
6142 test_56u() { # LU-611
6143         local dir=$DIR/$tdir
6144
6145         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6146
6147         if [[ $OSTCOUNT -gt 1 ]]; then
6148                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6149                 onestripe=4
6150         else
6151                 onestripe=0
6152         fi
6153
6154         local expected=$(((NUMDIRS + 1) * NUMFILES))
6155         local cmd="$LFS find -stripe-index 0 -type f $dir"
6156         local nums=$($cmd | wc -l)
6157
6158         [ $nums -eq $expected ] ||
6159                 error "'$cmd' wrong: found $nums, expected $expected"
6160
6161         expected=$onestripe
6162         cmd="$LFS find -stripe-index 1 -type f $dir"
6163         nums=$($cmd | wc -l)
6164         [ $nums -eq $expected ] ||
6165                 error "'$cmd' wrong: found $nums, expected $expected"
6166
6167         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6168         nums=$($cmd | wc -l)
6169         [ $nums -eq $expected ] ||
6170                 error "'$cmd' wrong: found $nums, expected $expected"
6171
6172         expected=0
6173         # This should produce an error and not return any files
6174         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
6175         nums=$($cmd 2>/dev/null | wc -l)
6176         [ $nums -eq $expected ] ||
6177                 error "'$cmd' wrong: found $nums, expected $expected"
6178
6179         if [[ $OSTCOUNT -gt 1 ]]; then
6180                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
6181                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
6182                 nums=$($cmd | wc -l)
6183                 [ $nums -eq $expected ] ||
6184                         error "'$cmd' wrong: found $nums, expected $expected"
6185         fi
6186 }
6187 run_test 56u "check lfs find -stripe-index works"
6188
6189 test_56v() {
6190         local mdt_idx=0
6191         local dir=$DIR/$tdir
6192
6193         setup_56 $dir $NUMFILES $NUMDIRS
6194
6195         UUID=$(mdtuuid_from_index $mdt_idx $dir)
6196         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
6197
6198         for file in $($LFS find -m $UUID $dir); do
6199                 file_midx=$($LFS getstripe -m $file)
6200                 [ $file_midx -eq $mdt_idx ] ||
6201                         error "lfs find -m $UUID != getstripe -m $file_midx"
6202         done
6203 }
6204 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
6205
6206 test_56w() {
6207         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6208         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6209
6210         local dir=$DIR/$tdir
6211
6212         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
6213
6214         local stripe_size=$($LFS getstripe -S -d $dir) ||
6215                 error "$LFS getstripe -S -d $dir failed"
6216         stripe_size=${stripe_size%% *}
6217
6218         local file_size=$((stripe_size * OSTCOUNT))
6219         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
6220         local required_space=$((file_num * file_size))
6221         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
6222                            head -n1)
6223         [[ $free_space -le $((required_space / 1024)) ]] &&
6224                 skip_env "need $required_space, have $free_space kbytes"
6225
6226         local dd_bs=65536
6227         local dd_count=$((file_size / dd_bs))
6228
6229         # write data into the files
6230         local i
6231         local j
6232         local file
6233
6234         for i in $(seq $NUMFILES); do
6235                 file=$dir/file$i
6236                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6237                         error "write data into $file failed"
6238         done
6239         for i in $(seq $NUMDIRS); do
6240                 for j in $(seq $NUMFILES); do
6241                         file=$dir/dir$i/file$j
6242                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6243                                 error "write data into $file failed"
6244                 done
6245         done
6246
6247         # $LFS_MIGRATE will fail if hard link migration is unsupported
6248         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
6249                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
6250                         error "creating links to $dir/dir1/file1 failed"
6251         fi
6252
6253         local expected=-1
6254
6255         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
6256
6257         # lfs_migrate file
6258         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
6259
6260         echo "$cmd"
6261         eval $cmd || error "$cmd failed"
6262
6263         check_stripe_count $dir/file1 $expected
6264
6265         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
6266         then
6267                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
6268                 # OST 1 if it is on OST 0. This file is small enough to
6269                 # be on only one stripe.
6270                 file=$dir/migr_1_ost
6271                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
6272                         error "write data into $file failed"
6273                 local obdidx=$($LFS getstripe -i $file)
6274                 local oldmd5=$(md5sum $file)
6275                 local newobdidx=0
6276
6277                 [[ $obdidx -eq 0 ]] && newobdidx=1
6278                 cmd="$LFS migrate -i $newobdidx $file"
6279                 echo $cmd
6280                 eval $cmd || error "$cmd failed"
6281
6282                 local realobdix=$($LFS getstripe -i $file)
6283                 local newmd5=$(md5sum $file)
6284
6285                 [[ $newobdidx -ne $realobdix ]] &&
6286                         error "new OST is different (was=$obdidx, "\
6287                               "wanted=$newobdidx, got=$realobdix)"
6288                 [[ "$oldmd5" != "$newmd5" ]] &&
6289                         error "md5sum differ: $oldmd5, $newmd5"
6290         fi
6291
6292         # lfs_migrate dir
6293         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
6294         echo "$cmd"
6295         eval $cmd || error "$cmd failed"
6296
6297         for j in $(seq $NUMFILES); do
6298                 check_stripe_count $dir/dir1/file$j $expected
6299         done
6300
6301         # lfs_migrate works with lfs find
6302         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
6303              $LFS_MIGRATE -y -c $expected"
6304         echo "$cmd"
6305         eval $cmd || error "$cmd failed"
6306
6307         for i in $(seq 2 $NUMFILES); do
6308                 check_stripe_count $dir/file$i $expected
6309         done
6310         for i in $(seq 2 $NUMDIRS); do
6311                 for j in $(seq $NUMFILES); do
6312                 check_stripe_count $dir/dir$i/file$j $expected
6313                 done
6314         done
6315 }
6316 run_test 56w "check lfs_migrate -c stripe_count works"
6317
6318 test_56wb() {
6319         local file1=$DIR/$tdir/file1
6320         local create_pool=false
6321         local initial_pool=$($LFS getstripe -p $DIR)
6322         local pool_list=()
6323         local pool=""
6324
6325         echo -n "Creating test dir..."
6326         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6327         echo "done."
6328
6329         echo -n "Creating test file..."
6330         touch $file1 || error "cannot create file"
6331         echo "done."
6332
6333         echo -n "Detecting existing pools..."
6334         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
6335
6336         if [ ${#pool_list[@]} -gt 0 ]; then
6337                 echo "${pool_list[@]}"
6338                 for thispool in "${pool_list[@]}"; do
6339                         if [[ -z "$initial_pool" ||
6340                               "$initial_pool" != "$thispool" ]]; then
6341                                 pool="$thispool"
6342                                 echo "Using existing pool '$pool'"
6343                                 break
6344                         fi
6345                 done
6346         else
6347                 echo "none detected."
6348         fi
6349         if [ -z "$pool" ]; then
6350                 pool=${POOL:-testpool}
6351                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
6352                 echo -n "Creating pool '$pool'..."
6353                 create_pool=true
6354                 pool_add $pool &> /dev/null ||
6355                         error "pool_add failed"
6356                 echo "done."
6357
6358                 echo -n "Adding target to pool..."
6359                 pool_add_targets $pool 0 0 1 &> /dev/null ||
6360                         error "pool_add_targets failed"
6361                 echo "done."
6362         fi
6363
6364         echo -n "Setting pool using -p option..."
6365         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
6366                 error "migrate failed rc = $?"
6367         echo "done."
6368
6369         echo -n "Verifying test file is in pool after migrating..."
6370         [ "$($LFS getstripe -p $file1)" = $pool ] ||
6371                 error "file was not migrated to pool $pool"
6372         echo "done."
6373
6374         echo -n "Removing test file from pool '$pool'..."
6375         $LFS migrate $file1 &> /dev/null ||
6376                 error "cannot remove from pool"
6377         [ "$($LFS getstripe -p $file1)" ] &&
6378                 error "pool still set"
6379         echo "done."
6380
6381         echo -n "Setting pool using --pool option..."
6382         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
6383                 error "migrate failed rc = $?"
6384         echo "done."
6385
6386         # Clean up
6387         rm -f $file1
6388         if $create_pool; then
6389                 destroy_test_pools 2> /dev/null ||
6390                         error "destroy test pools failed"
6391         fi
6392 }
6393 run_test 56wb "check lfs_migrate pool support"
6394
6395 test_56wc() {
6396         local file1="$DIR/$tdir/file1"
6397
6398         echo -n "Creating test dir..."
6399         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6400         local def_stripe_size=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
6401         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
6402                 error "cannot set stripe"
6403         echo "done"
6404
6405         echo -n "Setting initial stripe for test file..."
6406         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
6407                 error "cannot set stripe"
6408         [ $($LFS getstripe -S "$file1") -eq 524288 ] ||
6409                 error "stripe size not set"
6410         echo "done."
6411
6412         # File currently set to -S 512K -c 1
6413
6414         # Ensure -c and -S options are rejected when -R is set
6415         echo -n "Verifying incompatible options are detected..."
6416         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
6417                 error "incompatible -c and -R options not detected"
6418         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
6419                 error "incompatible -S and -R options not detected"
6420         echo "done."
6421
6422         # Ensure unrecognized options are passed through to 'lfs migrate'
6423         echo -n "Verifying -S option is passed through to lfs migrate..."
6424         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
6425                 error "migration failed"
6426         [ $($LFS getstripe -S "$file1") -eq 1048576 ] ||
6427                 error "file was not restriped"
6428         echo "done."
6429
6430         # File currently set to -S 1M -c 1
6431
6432         # Ensure long options are supported
6433         echo -n "Verifying long options supported..."
6434         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
6435                 error "long option without argument not supported"
6436         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
6437                 error "long option with argument not supported"
6438         [ $($LFS getstripe -S "$file1") -eq 524288 ] ||
6439                 error "file not restriped with --stripe-size option"
6440         echo "done."
6441
6442         # File currently set to -S 512K -c 1
6443
6444         if [ "$OSTCOUNT" -gt 1 ]; then
6445                 echo -n "Verifying explicit stripe count can be set..."
6446                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
6447                         error "migrate failed"
6448                 [ $($LFS getstripe -c "$file1") -eq 2 ] ||
6449                         error "file not restriped to explicit count"
6450                 echo "done."
6451         fi
6452
6453         # File currently set to -S 512K -c 1 or -S 512K -c 2
6454
6455         # Ensure parent striping is used if -R is set, and no stripe
6456         # count or size is specified
6457         echo -n "Setting stripe for parent directory..."
6458         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
6459                 error "cannot set stripe"
6460         echo "done."
6461
6462         echo -n "Verifying restripe option uses parent stripe settings..."
6463         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
6464                 error "migrate failed"
6465         [ $($LFS getstripe -S "$file1") -eq $def_stripe_size ] ||
6466                 error "file not restriped to parent settings"
6467         [ $($LFS getstripe -c "$file1") -eq 1 ] ||
6468                 error "file not restriped to parent settings"
6469         echo "done."
6470
6471         # File currently set to -S 1M -c 1
6472
6473         # Ensure striping is preserved if -R is not set, and no stripe
6474         # count or size is specified
6475         echo -n "Verifying striping size preserved when not specified..."
6476         local orig_stripe_size=$($LFS getstripe -S "$file1" 2>/dev/null)
6477         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6478                 error "cannot set stripe on parent directory"
6479         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6480                 error "migrate failed"
6481         [ $($LFS getstripe -S "$file1") -eq $orig_stripe_size ] ||
6482                 error "file was restriped"
6483         echo "done."
6484
6485         # Ensure file name properly detected when final option has no argument
6486         echo -n "Verifying file name properly detected..."
6487         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6488                 error "file name interpreted as option argument"
6489         echo "done."
6490
6491         # Clean up
6492         rm -f "$file1"
6493 }
6494 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
6495
6496 test_56wd() {
6497         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6498
6499         local file1=$DIR/$tdir/file1
6500
6501         echo -n "Creating test dir..."
6502         test_mkdir $DIR/$tdir || error "cannot create dir"
6503         echo "done."
6504
6505         echo -n "Creating test file..."
6506         touch $file1
6507         echo "done."
6508
6509         # Ensure 'lfs migrate' will fail by using a non-existent option,
6510         # and make sure rsync is not called to recover
6511         echo -n "Make sure --no-rsync option works..."
6512         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
6513                 grep -q 'refusing to fall back to rsync' ||
6514                 error "rsync was called with --no-rsync set"
6515         echo "done."
6516
6517         # Ensure rsync is called without trying 'lfs migrate' first
6518         echo -n "Make sure --rsync option works..."
6519         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
6520                 grep -q 'falling back to rsync' &&
6521                 error "lfs migrate was called with --rsync set"
6522         echo "done."
6523
6524         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
6525         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
6526                 grep -q 'at the same time' ||
6527                 error "--rsync and --no-rsync accepted concurrently"
6528         echo "done."
6529
6530         # Clean up
6531         rm -f $file1
6532 }
6533 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
6534
6535 test_56x() {
6536         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6537         check_swap_layouts_support
6538
6539         local dir=$DIR/$tdir
6540         local ref1=/etc/passwd
6541         local file1=$dir/file1
6542
6543         test_mkdir $dir || error "creating dir $dir"
6544         $LFS setstripe -c 2 $file1
6545         cp $ref1 $file1
6546         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
6547         stripe=$($LFS getstripe -c $file1)
6548         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6549         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6550
6551         # clean up
6552         rm -f $file1
6553 }
6554 run_test 56x "lfs migration support"
6555
6556 test_56xa() {
6557         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6558         check_swap_layouts_support
6559
6560         local dir=$DIR/$tdir/$testnum
6561
6562         test_mkdir -p $dir
6563
6564         local ref1=/etc/passwd
6565         local file1=$dir/file1
6566
6567         $LFS setstripe -c 2 $file1
6568         cp $ref1 $file1
6569         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
6570
6571         local stripe=$($LFS getstripe -c $file1)
6572
6573         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6574         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6575
6576         # clean up
6577         rm -f $file1
6578 }
6579 run_test 56xa "lfs migration --block support"
6580
6581 check_migrate_links() {
6582         local dir="$1"
6583         local file1="$dir/file1"
6584         local begin="$2"
6585         local count="$3"
6586         local runas="$4"
6587         local total_count=$(($begin + $count - 1))
6588         local symlink_count=10
6589         local uniq_count=10
6590
6591         if [ ! -f "$file1" ]; then
6592                 echo -n "creating initial file..."
6593                 $LFS setstripe -c 1 -S "512k" "$file1" ||
6594                         error "cannot setstripe initial file"
6595                 echo "done"
6596
6597                 echo -n "creating symlinks..."
6598                 for s in $(seq 1 $symlink_count); do
6599                         ln -s "$file1" "$dir/slink$s" ||
6600                                 error "cannot create symlinks"
6601                 done
6602                 echo "done"
6603
6604                 echo -n "creating nonlinked files..."
6605                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
6606                         error "cannot create nonlinked files"
6607                 echo "done"
6608         fi
6609
6610         # create hard links
6611         if [ ! -f "$dir/file$total_count" ]; then
6612                 echo -n "creating hard links $begin:$total_count..."
6613                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
6614                         /dev/null || error "cannot create hard links"
6615                 echo "done"
6616         fi
6617
6618         echo -n "checking number of hard links listed in xattrs..."
6619         local fid=$($LFS getstripe -F "$file1")
6620         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
6621
6622         echo "${#paths[*]}"
6623         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
6624                         skip "hard link list has unexpected size, skipping test"
6625         fi
6626         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
6627                         error "link names should exceed xattrs size"
6628         fi
6629
6630         echo -n "migrating files..."
6631         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
6632         local rc=$?
6633         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
6634         echo "done"
6635
6636         # make sure all links have been properly migrated
6637         echo -n "verifying files..."
6638         fid=$($LFS getstripe -F "$file1") ||
6639                 error "cannot get fid for file $file1"
6640         for i in $(seq 2 $total_count); do
6641                 local fid2=$($LFS getstripe -F $dir/file$i)
6642
6643                 [ "$fid2" == "$fid" ] ||
6644                         error "migrated hard link has mismatched FID"
6645         done
6646
6647         # make sure hard links were properly detected, and migration was
6648         # performed only once for the entire link set; nonlinked files should
6649         # also be migrated
6650         local actual=$(grep -c 'done' <<< "$migrate_out")
6651         local expected=$(($uniq_count + 1))
6652
6653         [ "$actual" -eq  "$expected" ] ||
6654                 error "hard links individually migrated ($actual != $expected)"
6655
6656         # make sure the correct number of hard links are present
6657         local hardlinks=$(stat -c '%h' "$file1")
6658
6659         [ $hardlinks -eq $total_count ] ||
6660                 error "num hard links $hardlinks != $total_count"
6661         echo "done"
6662
6663         return 0
6664 }
6665
6666 test_56xb() {
6667         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
6668                 skip "Need MDS version at least 2.10.55"
6669
6670         local dir="$DIR/$tdir"
6671
6672         test_mkdir "$dir" || error "cannot create dir $dir"
6673
6674         echo "testing lfs migrate mode when all links fit within xattrs"
6675         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
6676
6677         echo "testing rsync mode when all links fit within xattrs"
6678         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
6679
6680         echo "testing lfs migrate mode when all links do not fit within xattrs"
6681         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
6682
6683         echo "testing rsync mode when all links do not fit within xattrs"
6684         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
6685
6686         chown -R $RUNAS_ID $dir
6687         echo "testing non-root lfs migrate mode when not all links are in xattr"
6688         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
6689
6690         # clean up
6691         rm -rf $dir
6692 }
6693 run_test 56xb "lfs migration hard link support"
6694
6695 test_56xc() {
6696         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6697
6698         local dir="$DIR/$tdir"
6699
6700         test_mkdir "$dir" || error "cannot create dir $dir"
6701
6702         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
6703         echo -n "Setting initial stripe for 20MB test file..."
6704         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
6705                 error "cannot setstripe 20MB file"
6706         echo "done"
6707         echo -n "Sizing 20MB test file..."
6708         truncate "$dir/20mb" 20971520 || error "cannot create 20MB test file"
6709         echo "done"
6710         echo -n "Verifying small file autostripe count is 1..."
6711         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
6712                 error "cannot migrate 20MB file"
6713         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
6714                 error "cannot get stripe for $dir/20mb"
6715         [ $stripe_count -eq 1 ] ||
6716                 error "unexpected stripe count $stripe_count for 20MB file"
6717         rm -f "$dir/20mb"
6718         echo "done"
6719
6720         # Test 2: File is small enough to fit within the available space on
6721         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
6722         # have at least an additional 1KB for each desired stripe for test 3
6723         echo -n "Setting stripe for 1GB test file..."
6724         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
6725         echo "done"
6726         echo -n "Sizing 1GB test file..."
6727         # File size is 1GB + 3KB
6728         truncate "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
6729         echo "done"
6730
6731         # need at least 512MB per OST for 1GB file to fit in 2 stripes
6732         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
6733         if (( avail > 524288 * OSTCOUNT )); then
6734                 echo -n "Migrating 1GB file..."
6735                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
6736                         error "cannot migrate 1GB file"
6737                 echo "done"
6738                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
6739                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
6740                         error "cannot getstripe for 1GB file"
6741                 [ $stripe_count -eq 2 ] ||
6742                         error "unexpected stripe count $stripe_count != 2"
6743                 echo "done"
6744         fi
6745
6746         # Test 3: File is too large to fit within the available space on
6747         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
6748         if [ $OSTCOUNT -ge 3 ]; then
6749                 # The required available space is calculated as
6750                 # file size (1GB + 3KB) / OST count (3).
6751                 local kb_per_ost=349526
6752
6753                 echo -n "Migrating 1GB file with limit..."
6754                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
6755                         error "cannot migrate 1GB file with limit"
6756                 echo "done"
6757
6758                 stripe_count=$($LFS getstripe -c "$dir/1gb")
6759                 echo -n "Verifying 1GB autostripe count with limited space..."
6760                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
6761                         error "unexpected stripe count $stripe_count (min 3)"
6762                 echo "done"
6763         fi
6764
6765         # clean up
6766         rm -rf $dir
6767 }
6768 run_test 56xc "lfs migration autostripe"
6769
6770 test_56y() {
6771         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
6772                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
6773
6774         local res=""
6775         local dir=$DIR/$tdir
6776         local f1=$dir/file1
6777         local f2=$dir/file2
6778
6779         test_mkdir -p $dir || error "creating dir $dir"
6780         touch $f1 || error "creating std file $f1"
6781         $MULTIOP $f2 H2c || error "creating released file $f2"
6782
6783         # a directory can be raid0, so ask only for files
6784         res=$($LFS find $dir -L raid0 -type f | wc -l)
6785         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
6786
6787         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
6788         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
6789
6790         # only files can be released, so no need to force file search
6791         res=$($LFS find $dir -L released)
6792         [[ $res == $f2 ]] || error "search released: found $res != $f2"
6793
6794         res=$($LFS find $dir -type f \! -L released)
6795         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
6796 }
6797 run_test 56y "lfs find -L raid0|released"
6798
6799 test_56z() { # LU-4824
6800         # This checks to make sure 'lfs find' continues after errors
6801         # There are two classes of errors that should be caught:
6802         # - If multiple paths are provided, all should be searched even if one
6803         #   errors out
6804         # - If errors are encountered during the search, it should not terminate
6805         #   early
6806         local dir=$DIR/$tdir
6807         local i
6808
6809         test_mkdir $dir
6810         for i in d{0..9}; do
6811                 test_mkdir $dir/$i
6812                 touch $dir/$i/$tfile
6813         done
6814         $LFS find $DIR/non_existent_dir $dir &&
6815                 error "$LFS find did not return an error"
6816         # Make a directory unsearchable. This should NOT be the last entry in
6817         # directory order.  Arbitrarily pick the 6th entry
6818         chmod 700 $($LFS find $dir -type d | sed '6!d')
6819
6820         $RUNAS $LFS find $DIR/non_existent $dir
6821         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
6822
6823         # The user should be able to see 10 directories and 9 files
6824         (( count == 19 )) ||
6825                 error "$LFS find found $count != 19 entries after error"
6826 }
6827 run_test 56z "lfs find should continue after an error"
6828
6829 test_56aa() { # LU-5937
6830         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
6831
6832         local dir=$DIR/$tdir
6833
6834         mkdir $dir
6835         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
6836
6837         createmany -o $dir/striped_dir/${tfile}- 1024
6838         local dirs=$($LFS find --size +8k $dir/)
6839
6840         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
6841 }
6842 run_test 56aa "lfs find --size under striped dir"
6843
6844 test_56ab() { # LU-10705
6845         test_mkdir $DIR/$tdir
6846         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
6847         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
6848         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
6849         # Flush writes to ensure valid blocks.  Need to be more thorough for
6850         # ZFS, since blocks are not allocated/returned to client immediately.
6851         sync_all_data
6852         wait_zfs_commit ost1 2
6853         cancel_lru_locks osc
6854         ls -ls $DIR/$tdir
6855
6856         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
6857
6858         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
6859
6860         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
6861         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
6862
6863         rm -f $DIR/$tdir/$tfile.[123]
6864 }
6865 run_test 56ab "lfs find --blocks"
6866
6867 test_56ba() {
6868         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
6869                 skip "Need MDS version at least 2.10.50"
6870
6871         # Create composite files with one component
6872         local dir=$DIR/$tdir
6873
6874         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
6875         # Create composite files with three components
6876         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
6877         # Create non-composite files
6878         createmany -o $dir/${tfile}- 10
6879
6880         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
6881
6882         [[ $nfiles == 10 ]] ||
6883                 error "lfs find -E 1M found $nfiles != 10 files"
6884
6885         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
6886         [[ $nfiles == 25 ]] ||
6887                 error "lfs find ! -E 1M found $nfiles != 25 files"
6888
6889         # All files have a component that starts at 0
6890         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
6891         [[ $nfiles == 35 ]] ||
6892                 error "lfs find --component-start 0 - $nfiles != 35 files"
6893
6894         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
6895         [[ $nfiles == 15 ]] ||
6896                 error "lfs find --component-start 2M - $nfiles != 15 files"
6897
6898         # All files created here have a componenet that does not starts at 2M
6899         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
6900         [[ $nfiles == 35 ]] ||
6901                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
6902
6903         # Find files with a specified number of components
6904         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
6905         [[ $nfiles == 15 ]] ||
6906                 error "lfs find --component-count 3 - $nfiles != 15 files"
6907
6908         # Remember non-composite files have a component count of zero
6909         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
6910         [[ $nfiles == 10 ]] ||
6911                 error "lfs find --component-count 0 - $nfiles != 10 files"
6912
6913         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
6914         [[ $nfiles == 20 ]] ||
6915                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
6916
6917         # All files have a flag called "init"
6918         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
6919         [[ $nfiles == 35 ]] ||
6920                 error "lfs find --component-flags init - $nfiles != 35 files"
6921
6922         # Multi-component files will have a component not initialized
6923         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
6924         [[ $nfiles == 15 ]] ||
6925                 error "lfs find !--component-flags init - $nfiles != 15 files"
6926
6927         rm -rf $dir
6928
6929 }
6930 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
6931
6932 test_56ca() {
6933         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
6934                 skip "Need MDS version at least 2.10.57"
6935
6936         local td=$DIR/$tdir
6937         local tf=$td/$tfile
6938         local dir
6939         local nfiles
6940         local cmd
6941         local i
6942         local j
6943
6944         # create mirrored directories and mirrored files
6945         mkdir $td || error "mkdir $td failed"
6946         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
6947         createmany -o $tf- 10 || error "create $tf- failed"
6948
6949         for i in $(seq 2); do
6950                 dir=$td/dir$i
6951                 mkdir $dir || error "mkdir $dir failed"
6952                 $LFS mirror create -N$((3 + i)) $dir ||
6953                         error "create mirrored dir $dir failed"
6954                 createmany -o $dir/$tfile- 10 ||
6955                         error "create $dir/$tfile- failed"
6956         done
6957
6958         # change the states of some mirrored files
6959         echo foo > $tf-6
6960         for i in $(seq 2); do
6961                 dir=$td/dir$i
6962                 for j in $(seq 4 9); do
6963                         echo foo > $dir/$tfile-$j
6964                 done
6965         done
6966
6967         # find mirrored files with specific mirror count
6968         cmd="$LFS find --mirror-count 3 --type f $td"
6969         nfiles=$($cmd | wc -l)
6970         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
6971
6972         cmd="$LFS find ! --mirror-count 3 --type f $td"
6973         nfiles=$($cmd | wc -l)
6974         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
6975
6976         cmd="$LFS find --mirror-count +2 --type f $td"
6977         nfiles=$($cmd | wc -l)
6978         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6979
6980         cmd="$LFS find --mirror-count -6 --type f $td"
6981         nfiles=$($cmd | wc -l)
6982         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6983
6984         # find mirrored files with specific file state
6985         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
6986         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
6987
6988         cmd="$LFS find --mirror-state=ro --type f $td"
6989         nfiles=$($cmd | wc -l)
6990         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
6991
6992         cmd="$LFS find ! --mirror-state=ro --type f $td"
6993         nfiles=$($cmd | wc -l)
6994         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
6995
6996         cmd="$LFS find --mirror-state=wp --type f $td"
6997         nfiles=$($cmd | wc -l)
6998         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
6999
7000         cmd="$LFS find ! --mirror-state=sp --type f $td"
7001         nfiles=$($cmd | wc -l)
7002         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7003 }
7004 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
7005
7006 test_57a() {
7007         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7008         # note test will not do anything if MDS is not local
7009         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7010                 skip_env "ldiskfs only test"
7011         fi
7012         remote_mds_nodsh && skip "remote MDS with nodsh"
7013
7014         local MNTDEV="osd*.*MDT*.mntdev"
7015         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
7016         [ -z "$DEV" ] && error "can't access $MNTDEV"
7017         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
7018                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
7019                         error "can't access $DEV"
7020                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
7021                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
7022                 rm $TMP/t57a.dump
7023         done
7024 }
7025 run_test 57a "verify MDS filesystem created with large inodes =="
7026
7027 test_57b() {
7028         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7029         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7030                 skip_env "ldiskfs only test"
7031         fi
7032         remote_mds_nodsh && skip "remote MDS with nodsh"
7033
7034         local dir=$DIR/$tdir
7035         local filecount=100
7036         local file1=$dir/f1
7037         local fileN=$dir/f$filecount
7038
7039         rm -rf $dir || error "removing $dir"
7040         test_mkdir -c1 $dir
7041         local mdtidx=$($LFS getstripe -m $dir)
7042         local mdtname=MDT$(printf %04x $mdtidx)
7043         local facet=mds$((mdtidx + 1))
7044
7045         echo "mcreating $filecount files"
7046         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
7047
7048         # verify that files do not have EAs yet
7049         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
7050                 error "$file1 has an EA"
7051         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
7052                 error "$fileN has an EA"
7053
7054         sync
7055         sleep 1
7056         df $dir  #make sure we get new statfs data
7057         local mdsfree=$(do_facet $facet \
7058                         lctl get_param -n osd*.*$mdtname.kbytesfree)
7059         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7060         local file
7061
7062         echo "opening files to create objects/EAs"
7063         for file in $(seq -f $dir/f%g 1 $filecount); do
7064                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
7065                         error "opening $file"
7066         done
7067
7068         # verify that files have EAs now
7069         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
7070         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
7071
7072         sleep 1  #make sure we get new statfs data
7073         df $dir
7074         local mdsfree2=$(do_facet $facet \
7075                          lctl get_param -n osd*.*$mdtname.kbytesfree)
7076         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7077
7078         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
7079                 if [ "$mdsfree" != "$mdsfree2" ]; then
7080                         error "MDC before $mdcfree != after $mdcfree2"
7081                 else
7082                         echo "MDC before $mdcfree != after $mdcfree2"
7083                         echo "unable to confirm if MDS has large inodes"
7084                 fi
7085         fi
7086         rm -rf $dir
7087 }
7088 run_test 57b "default LOV EAs are stored inside large inodes ==="
7089
7090 test_58() {
7091         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7092         [ -z "$(which wiretest 2>/dev/null)" ] &&
7093                         skip_env "could not find wiretest"
7094
7095         wiretest
7096 }
7097 run_test 58 "verify cross-platform wire constants =============="
7098
7099 test_59() {
7100         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7101
7102         echo "touch 130 files"
7103         createmany -o $DIR/f59- 130
7104         echo "rm 130 files"
7105         unlinkmany $DIR/f59- 130
7106         sync
7107         # wait for commitment of removal
7108         wait_delete_completed
7109 }
7110 run_test 59 "verify cancellation of llog records async ========="
7111
7112 TEST60_HEAD="test_60 run $RANDOM"
7113 test_60a() {
7114         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7115         remote_mgs_nodsh && skip "remote MGS with nodsh"
7116         do_facet mgs "! which run-llog.sh &> /dev/null" &&
7117                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
7118                         skip_env "missing subtest run-llog.sh"
7119
7120         log "$TEST60_HEAD - from kernel mode"
7121         do_facet mgs "$LCTL dk > /dev/null"
7122         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
7123         do_facet mgs $LCTL dk > $TMP/$tfile
7124
7125         # LU-6388: test llog_reader
7126         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
7127         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
7128         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
7129                         skip_env "missing llog_reader"
7130         local fstype=$(facet_fstype mgs)
7131         [ $fstype != ldiskfs -a $fstype != zfs ] &&
7132                 skip_env "Only for ldiskfs or zfs type mgs"
7133
7134         local mntpt=$(facet_mntpt mgs)
7135         local mgsdev=$(mgsdevname 1)
7136         local fid_list
7137         local fid
7138         local rec_list
7139         local rec
7140         local rec_type
7141         local obj_file
7142         local path
7143         local seq
7144         local oid
7145         local pass=true
7146
7147         #get fid and record list
7148         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
7149                 tail -n 4))
7150         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
7151                 tail -n 4))
7152         #remount mgs as ldiskfs or zfs type
7153         stop mgs || error "stop mgs failed"
7154         mount_fstype mgs || error "remount mgs failed"
7155         for ((i = 0; i < ${#fid_list[@]}; i++)); do
7156                 fid=${fid_list[i]}
7157                 rec=${rec_list[i]}
7158                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
7159                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
7160                 oid=$((16#$oid))
7161
7162                 case $fstype in
7163                         ldiskfs )
7164                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
7165                         zfs )
7166                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
7167                 esac
7168                 echo "obj_file is $obj_file"
7169                 do_facet mgs $llog_reader $obj_file
7170
7171                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
7172                         awk '{ print $3 }' | sed -e "s/^type=//g")
7173                 if [ $rec_type != $rec ]; then
7174                         echo "FAILED test_60a wrong record type $rec_type," \
7175                               "should be $rec"
7176                         pass=false
7177                         break
7178                 fi
7179
7180                 #check obj path if record type is LLOG_LOGID_MAGIC
7181                 if [ "$rec" == "1064553b" ]; then
7182                         path=$(do_facet mgs $llog_reader $obj_file |
7183                                 grep "path=" | awk '{ print $NF }' |
7184                                 sed -e "s/^path=//g")
7185                         if [ $obj_file != $mntpt/$path ]; then
7186                                 echo "FAILED test_60a wrong obj path" \
7187                                       "$montpt/$path, should be $obj_file"
7188                                 pass=false
7189                                 break
7190                         fi
7191                 fi
7192         done
7193         rm -f $TMP/$tfile
7194         #restart mgs before "error", otherwise it will block the next test
7195         stop mgs || error "stop mgs failed"
7196         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
7197         $pass || error "test failed, see FAILED test_60a messages for specifics"
7198 }
7199 run_test 60a "llog_test run from kernel module and test llog_reader"
7200
7201 test_60b() { # bug 6411
7202         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7203
7204         dmesg > $DIR/$tfile
7205         LLOG_COUNT=$(do_facet mgs dmesg |
7206                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
7207                           /llog_[a-z]*.c:[0-9]/ {
7208                                 if (marker)
7209                                         from_marker++
7210                                 from_begin++
7211                           }
7212                           END {
7213                                 if (marker)
7214                                         print from_marker
7215                                 else
7216                                         print from_begin
7217                           }")
7218
7219         [[ $LLOG_COUNT -gt 120 ]] &&
7220                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
7221 }
7222 run_test 60b "limit repeated messages from CERROR/CWARN"
7223
7224 test_60c() {
7225         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7226
7227         echo "create 5000 files"
7228         createmany -o $DIR/f60c- 5000
7229 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
7230         lctl set_param fail_loc=0x80000137
7231         unlinkmany $DIR/f60c- 5000
7232         lctl set_param fail_loc=0
7233 }
7234 run_test 60c "unlink file when mds full"
7235
7236 test_60d() {
7237         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7238
7239         SAVEPRINTK=$(lctl get_param -n printk)
7240         # verify "lctl mark" is even working"
7241         MESSAGE="test message ID $RANDOM $$"
7242         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7243         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
7244
7245         lctl set_param printk=0 || error "set lnet.printk failed"
7246         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
7247         MESSAGE="new test message ID $RANDOM $$"
7248         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
7249         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7250         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
7251
7252         lctl set_param -n printk="$SAVEPRINTK"
7253 }
7254 run_test 60d "test printk console message masking"
7255
7256 test_60e() {
7257         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7258         remote_mds_nodsh && skip "remote MDS with nodsh"
7259
7260         touch $DIR/$tfile
7261 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
7262         do_facet mds1 lctl set_param fail_loc=0x15b
7263         rm $DIR/$tfile
7264 }
7265 run_test 60e "no space while new llog is being created"
7266
7267 test_60g() {
7268         local pid
7269         local i
7270
7271         test_mkdir -c $MDSCOUNT $DIR/$tdir
7272
7273         (
7274                 local index=0
7275                 while true; do
7276                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
7277                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
7278                                 2>/dev/null
7279                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
7280                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
7281                         index=$((index + 1))
7282                 done
7283         ) &
7284
7285         pid=$!
7286
7287         for i in {0..100}; do
7288                 # define OBD_FAIL_OSD_TXN_START    0x19a
7289                 local index=$((i % MDSCOUNT + 1))
7290
7291                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
7292                         > /dev/null
7293                 usleep 100
7294         done
7295
7296         kill -9 $pid
7297
7298         for i in $(seq $MDSCOUNT); do
7299                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
7300         done
7301
7302         mkdir $DIR/$tdir/new || error "mkdir failed"
7303         rmdir $DIR/$tdir/new || error "rmdir failed"
7304
7305         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
7306                 -t namespace
7307         for i in $(seq $MDSCOUNT); do
7308                 wait_update_facet mds$i "$LCTL get_param -n \
7309                         mdd.$(facet_svc mds$i).lfsck_namespace |
7310                         awk '/^status/ { print \\\$2 }'" "completed"
7311         done
7312
7313         ls -R $DIR/$tdir || error "ls failed"
7314         rm -rf $DIR/$tdir || error "rmdir failed"
7315 }
7316 run_test 60g "transaction abort won't cause MDT hung"
7317
7318 test_60h() {
7319         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
7320                 skip "Need MDS version at least 2.12.52"
7321         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
7322
7323         local f
7324
7325         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
7326         #define OBD_FAIL_MDS_STRIPE_FID          0x189
7327         for fail_loc in 0x80000188 0x80000189; do
7328                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
7329                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
7330                         error "mkdir $dir-$fail_loc failed"
7331                 for i in {0..10}; do
7332                         # create may fail on missing stripe
7333                         echo $i > $DIR/$tdir-$fail_loc/$i
7334                 done
7335                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7336                         error "getdirstripe $tdir-$fail_loc failed"
7337                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
7338                         error "migrate $tdir-$fail_loc failed"
7339                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7340                         error "getdirstripe $tdir-$fail_loc failed"
7341                 pushd $DIR/$tdir-$fail_loc
7342                 for f in *; do
7343                         echo $f | cmp $f - || error "$f data mismatch"
7344                 done
7345                 popd
7346                 rm -rf $DIR/$tdir-$fail_loc
7347         done
7348 }
7349 run_test 60h "striped directory with missing stripes can be accessed"
7350
7351 test_61a() {
7352         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7353
7354         f="$DIR/f61"
7355         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
7356         cancel_lru_locks osc
7357         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
7358         sync
7359 }
7360 run_test 61a "mmap() writes don't make sync hang ================"
7361
7362 test_61b() {
7363         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
7364 }
7365 run_test 61b "mmap() of unstriped file is successful"
7366
7367 # bug 2330 - insufficient obd_match error checking causes LBUG
7368 test_62() {
7369         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7370
7371         f="$DIR/f62"
7372         echo foo > $f
7373         cancel_lru_locks osc
7374         lctl set_param fail_loc=0x405
7375         cat $f && error "cat succeeded, expect -EIO"
7376         lctl set_param fail_loc=0
7377 }
7378 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
7379 # match every page all of the time.
7380 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
7381
7382 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
7383 # Though this test is irrelevant anymore, it helped to reveal some
7384 # other grant bugs (LU-4482), let's keep it.
7385 test_63a() {   # was test_63
7386         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7387
7388         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
7389
7390         for i in `seq 10` ; do
7391                 dd if=/dev/zero of=$DIR/f63 bs=8k &
7392                 sleep 5
7393                 kill $!
7394                 sleep 1
7395         done
7396
7397         rm -f $DIR/f63 || true
7398 }
7399 run_test 63a "Verify oig_wait interruption does not crash ======="
7400
7401 # bug 2248 - async write errors didn't return to application on sync
7402 # bug 3677 - async write errors left page locked
7403 test_63b() {
7404         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7405
7406         debugsave
7407         lctl set_param debug=-1
7408
7409         # ensure we have a grant to do async writes
7410         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
7411         rm $DIR/$tfile
7412
7413         sync    # sync lest earlier test intercept the fail_loc
7414
7415         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
7416         lctl set_param fail_loc=0x80000406
7417         $MULTIOP $DIR/$tfile Owy && \
7418                 error "sync didn't return ENOMEM"
7419         sync; sleep 2; sync     # do a real sync this time to flush page
7420         lctl get_param -n llite.*.dump_page_cache | grep locked && \
7421                 error "locked page left in cache after async error" || true
7422         debugrestore
7423 }
7424 run_test 63b "async write errors should be returned to fsync ==="
7425
7426 test_64a () {
7427         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7428
7429         df $DIR
7430         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur* | grep "[0-9]"
7431 }
7432 run_test 64a "verify filter grant calculations (in kernel) ====="
7433
7434 test_64b () {
7435         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7436
7437         sh oos.sh $MOUNT || error "oos.sh failed: $?"
7438 }
7439 run_test 64b "check out-of-space detection on client"
7440
7441 test_64c() {
7442         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
7443 }
7444 run_test 64c "verify grant shrink"
7445
7446 # this does exactly what osc_request.c:osc_announce_cached() does in
7447 # order to calculate max amount of grants to ask from server
7448 want_grant() {
7449         local tgt=$1
7450
7451         local nrpages=$($LCTL get_param -n osc.${tgt}.max_pages_per_rpc)
7452         local rpc_in_flight=$($LCTL get_param -n osc.${tgt}.max_rpcs_in_flight)
7453
7454         ((rpc_in_flight ++));
7455         nrpages=$((nrpages * rpc_in_flight))
7456
7457         local dirty_max_pages=$($LCTL get_param -n osc.${tgt}.max_dirty_mb)
7458
7459         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
7460
7461         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
7462         local undirty=$((nrpages * PAGE_SIZE))
7463
7464         local max_extent_pages
7465         max_extent_pages=$($LCTL get_param osc.${tgt}.import |
7466             grep grant_max_extent_size | awk '{print $2}')
7467         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
7468         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
7469         local grant_extent_tax
7470         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
7471             grep grant_extent_tax | awk '{print $2}')
7472
7473         undirty=$((undirty + nrextents * grant_extent_tax))
7474
7475         echo $undirty
7476 }
7477
7478 # this is size of unit for grant allocation. It should be equal to
7479 # what tgt_grant.c:tgt_grant_chunk() calculates
7480 grant_chunk() {
7481         local tgt=$1
7482         local max_brw_size
7483         local grant_extent_tax
7484
7485         max_brw_size=$($LCTL get_param osc.${tgt}.import |
7486             grep max_brw_size | awk '{print $2}')
7487
7488         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
7489             grep grant_extent_tax | awk '{print $2}')
7490
7491         echo $(((max_brw_size + grant_extent_tax) * 2))
7492 }
7493
7494 test_64d() {
7495         [ $OST1_VERSION -lt $(version_code 2.10.56) ] &&
7496                 skip "OST < 2.10.55 doesn't limit grants enough"
7497
7498         local tgt=$($LCTL dl | grep "0000-osc-[^mM]" | awk '{print $4}')
7499         local file=$DIR/$tfile
7500
7501         [[ $($LCTL get_param osc.${tgt}.import |
7502              grep "connect_flags:.*grant_param") ]] ||
7503                 skip "no grant_param connect flag"
7504
7505         local olddebug=$($LCTL get_param -n debug 2> /dev/null)
7506
7507         $LCTL set_param debug="$OLDDEBUG" 2> /dev/null || true
7508
7509         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
7510         stack_trap "rm -f $file" EXIT
7511
7512         $LFS setstripe $file -i 0 -c 1
7513         dd if=/dev/zero of=$file bs=1M count=1000 &
7514         ddpid=$!
7515
7516         while true
7517         do
7518                 local cur_grant=$($LCTL get_param -n osc.${tgt}.cur_grant_bytes)
7519                 if [[ $cur_grant -gt $max_cur_granted ]]
7520                 then
7521                         kill $ddpid
7522                         error "cur_grant $cur_grant > $max_cur_granted"
7523                 fi
7524                 kill -0 $ddpid
7525                 [[ $? -ne 0 ]] && break;
7526                 sleep 2
7527         done
7528
7529         rm -f $DIR/$tfile
7530         wait_delete_completed
7531         $LCTL set_param debug="$olddebug" 2> /dev/null || true
7532 }
7533 run_test 64d "check grant limit exceed"
7534
7535 # bug 1414 - set/get directories' stripe info
7536 test_65a() {
7537         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7538
7539         test_mkdir $DIR/$tdir
7540         touch $DIR/$tdir/f1
7541         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
7542 }
7543 run_test 65a "directory with no stripe info"
7544
7545 test_65b() {
7546         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7547
7548         test_mkdir $DIR/$tdir
7549         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7550
7551         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
7552                                                 error "setstripe"
7553         touch $DIR/$tdir/f2
7554         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
7555 }
7556 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
7557
7558 test_65c() {
7559         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7560         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
7561
7562         test_mkdir $DIR/$tdir
7563         local stripesize=$($LFS getstripe -S $DIR/$tdir)
7564
7565         $LFS setstripe -S $((stripesize * 4)) -i 1 \
7566                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
7567         touch $DIR/$tdir/f3
7568         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
7569 }
7570 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
7571
7572 test_65d() {
7573         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7574
7575         test_mkdir $DIR/$tdir
7576         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
7577         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7578
7579         if [[ $STRIPECOUNT -le 0 ]]; then
7580                 sc=1
7581         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
7582                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
7583                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
7584         else
7585                 sc=$(($STRIPECOUNT - 1))
7586         fi
7587         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
7588         touch $DIR/$tdir/f4 $DIR/$tdir/f5
7589         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
7590                 error "lverify failed"
7591 }
7592 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
7593
7594 test_65e() {
7595         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7596
7597         test_mkdir $DIR/$tdir
7598
7599         $LFS setstripe $DIR/$tdir || error "setstripe"
7600         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
7601                                         error "no stripe info failed"
7602         touch $DIR/$tdir/f6
7603         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
7604 }
7605 run_test 65e "directory setstripe defaults"
7606
7607 test_65f() {
7608         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7609
7610         test_mkdir $DIR/${tdir}f
7611         $RUNAS $LFS setstripe $DIR/${tdir}f &&
7612                 error "setstripe succeeded" || true
7613 }
7614 run_test 65f "dir setstripe permission (should return error) ==="
7615
7616 test_65g() {
7617         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7618
7619         test_mkdir $DIR/$tdir
7620         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7621
7622         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
7623                 error "setstripe -S failed"
7624         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
7625         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
7626                 error "delete default stripe failed"
7627 }
7628 run_test 65g "directory setstripe -d"
7629
7630 test_65h() {
7631         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7632
7633         test_mkdir $DIR/$tdir
7634         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7635
7636         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
7637                 error "setstripe -S failed"
7638         test_mkdir $DIR/$tdir/dd1
7639         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
7640                 error "stripe info inherit failed"
7641 }
7642 run_test 65h "directory stripe info inherit ===================="
7643
7644 test_65i() {
7645         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7646
7647         save_layout_restore_at_exit $MOUNT
7648
7649         # bug6367: set non-default striping on root directory
7650         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
7651
7652         # bug12836: getstripe on -1 default directory striping
7653         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
7654
7655         # bug12836: getstripe -v on -1 default directory striping
7656         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
7657
7658         # bug12836: new find on -1 default directory striping
7659         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
7660 }
7661 run_test 65i "various tests to set root directory striping"
7662
7663 test_65j() { # bug6367
7664         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7665
7666         sync; sleep 1
7667
7668         # if we aren't already remounting for each test, do so for this test
7669         if [ "$I_MOUNTED" = "yes" ]; then
7670                 cleanup || error "failed to unmount"
7671                 setup
7672         fi
7673
7674         save_layout_restore_at_exit $MOUNT
7675
7676         $LFS setstripe -d $MOUNT || error "setstripe failed"
7677 }
7678 run_test 65j "set default striping on root directory (bug 6367)="
7679
7680 cleanup_65k() {
7681         rm -rf $DIR/$tdir
7682         wait_delete_completed
7683         do_facet $SINGLEMDS "lctl set_param -n \
7684                 osp.$ost*MDT0000.max_create_count=$max_count"
7685         do_facet $SINGLEMDS "lctl set_param -n \
7686                 osp.$ost*MDT0000.create_count=$count"
7687         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
7688         echo $INACTIVE_OSC "is Activate"
7689
7690         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
7691 }
7692
7693 test_65k() { # bug11679
7694         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7695         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7696         remote_mds_nodsh && skip "remote MDS with nodsh"
7697
7698         local disable_precreate=true
7699         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
7700                 disable_precreate=false
7701
7702         echo "Check OST status: "
7703         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
7704                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
7705
7706         for OSC in $MDS_OSCS; do
7707                 echo $OSC "is active"
7708                 do_facet $SINGLEMDS lctl --device %$OSC activate
7709         done
7710
7711         for INACTIVE_OSC in $MDS_OSCS; do
7712                 local ost=$(osc_to_ost $INACTIVE_OSC)
7713                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
7714                                lov.*md*.target_obd |
7715                                awk -F: /$ost/'{ print $1 }' | head -n 1)
7716
7717                 mkdir -p $DIR/$tdir
7718                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
7719                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
7720
7721                 echo "Deactivate: " $INACTIVE_OSC
7722                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
7723
7724                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
7725                               osp.$ost*MDT0000.create_count")
7726                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
7727                                   osp.$ost*MDT0000.max_create_count")
7728                 $disable_precreate &&
7729                         do_facet $SINGLEMDS "lctl set_param -n \
7730                                 osp.$ost*MDT0000.max_create_count=0"
7731
7732                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
7733                         [ -f $DIR/$tdir/$idx ] && continue
7734                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
7735                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
7736                                 { cleanup_65k;
7737                                   error "setstripe $idx should succeed"; }
7738                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
7739                 done
7740                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
7741                 rmdir $DIR/$tdir
7742
7743                 do_facet $SINGLEMDS "lctl set_param -n \
7744                         osp.$ost*MDT0000.max_create_count=$max_count"
7745                 do_facet $SINGLEMDS "lctl set_param -n \
7746                         osp.$ost*MDT0000.create_count=$count"
7747                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
7748                 echo $INACTIVE_OSC "is Activate"
7749
7750                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
7751         done
7752 }
7753 run_test 65k "validate manual striping works properly with deactivated OSCs"
7754
7755 test_65l() { # bug 12836
7756         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7757
7758         test_mkdir -p $DIR/$tdir/test_dir
7759         $LFS setstripe -c -1 $DIR/$tdir/test_dir
7760         $LFS find -mtime -1 $DIR/$tdir >/dev/null
7761 }
7762 run_test 65l "lfs find on -1 stripe dir ========================"
7763
7764 test_65m() {
7765         local layout=$(save_layout $MOUNT)
7766         $RUNAS $LFS setstripe -c 2 $MOUNT && {
7767                 restore_layout $MOUNT $layout
7768                 error "setstripe should fail by non-root users"
7769         }
7770         true
7771 }
7772 run_test 65m "normal user can't set filesystem default stripe"
7773
7774 test_65n() {
7775         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
7776         [[ $(lustre_version_code $SINGLEMDS) -ge $(version_code 2.12.50) ]] ||
7777                 skip "Need MDS version at least 2.12.50"
7778         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
7779
7780         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7781         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
7782         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
7783
7784         local root_layout=$(save_layout $MOUNT)
7785         stack_trap "restore_layout $MOUNT $root_layout" EXIT
7786
7787         # new subdirectory under root directory should not inherit
7788         # the default layout from root
7789         local dir1=$MOUNT/$tdir-1
7790         mkdir $dir1 || error "mkdir $dir1 failed"
7791         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
7792                 error "$dir1 shouldn't have LOV EA"
7793
7794         # delete the default layout on root directory
7795         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
7796
7797         local dir2=$MOUNT/$tdir-2
7798         mkdir $dir2 || error "mkdir $dir2 failed"
7799         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
7800                 error "$dir2 shouldn't have LOV EA"
7801
7802         # set a new striping pattern on root directory
7803         local def_stripe_size=$($LFS getstripe -S $MOUNT)
7804         local new_def_stripe_size=$((def_stripe_size * 2))
7805         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
7806                 error "set stripe size on $MOUNT failed"
7807
7808         # new file created in $dir2 should inherit the new stripe size from
7809         # the filesystem default
7810         local file2=$dir2/$tfile-2
7811         touch $file2 || error "touch $file2 failed"
7812
7813         local file2_stripe_size=$($LFS getstripe -S $file2)
7814         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
7815                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
7816
7817         local dir3=$MOUNT/$tdir-3
7818         mkdir $dir3 || error "mkdir $dir3 failed"
7819         ! getfattr -n trusted.lov $dir3 &> /dev/null ||
7820                 error "$dir3 shouldn't have LOV EA"
7821
7822         # set OST pool on root directory
7823         local pool=$TESTNAME
7824         pool_add $pool || error "add $pool failed"
7825         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
7826                 error "add targets to $pool failed"
7827
7828         $LFS setstripe -p $pool $MOUNT ||
7829                 error "set OST pool on $MOUNT failed"
7830
7831         # new file created in $dir3 should inherit the pool from
7832         # the filesystem default
7833         local file3=$dir3/$tfile-3
7834         touch $file3 || error "touch $file3 failed"
7835
7836         local file3_pool=$($LFS getstripe -p $file3)
7837         [[ "$file3_pool" = "$pool" ]] ||
7838                 error "$file3 didn't inherit OST pool $pool"
7839
7840         local dir4=$MOUNT/$tdir-4
7841         mkdir $dir4 || error "mkdir $dir4 failed"
7842         ! getfattr -n trusted.lov $dir4 &> /dev/null ||
7843                 error "$dir4 shouldn't have LOV EA"
7844
7845         # new file created in $dir4 should inherit the pool from
7846         # the filesystem default
7847         local file4=$dir4/$tfile-4
7848         touch $file4 || error "touch $file4 failed"
7849
7850         local file4_pool=$($LFS getstripe -p $file4)
7851         [[ "$file4_pool" = "$pool" ]] ||
7852                 error "$file4 didn't inherit OST pool $pool"
7853
7854         # new subdirectory under non-root directory should inherit
7855         # the default layout from its parent directory
7856         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
7857                 error "set directory layout on $dir4 failed"
7858
7859         local dir5=$dir4/$tdir-5
7860         mkdir $dir5 || error "mkdir $dir5 failed"
7861
7862         local dir4_layout=$(get_layout_param $dir4)
7863         local dir5_layout=$(get_layout_param $dir5)
7864         [[ "$dir4_layout" = "$dir5_layout" ]] ||
7865                 error "$dir5 should inherit the default layout from $dir4"
7866
7867         # though subdir under ROOT doesn't inherit default layout, but
7868         # its sub dir/file should be created with default layout.
7869         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
7870         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
7871                 skip "Need MDS version at least 2.12.59"
7872
7873         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
7874         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
7875         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
7876
7877         if [ $default_lmv_hash == "none" ]; then
7878                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
7879         else
7880                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
7881                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
7882         fi
7883
7884         $LFS setdirstripe -D -c 2 $MOUNT ||
7885                 error "setdirstripe -D -c 2 failed"
7886         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
7887         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
7888         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
7889 }
7890 run_test 65n "don't inherit default layout from root for new subdirectories"
7891
7892 # bug 2543 - update blocks count on client
7893 test_66() {
7894         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7895
7896         COUNT=${COUNT:-8}
7897         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
7898         sync; sync_all_data; sync; sync_all_data
7899         cancel_lru_locks osc
7900         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
7901         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
7902 }
7903 run_test 66 "update inode blocks count on client ==============="
7904
7905 meminfo() {
7906         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
7907 }
7908
7909 swap_used() {
7910         swapon -s | awk '($1 == "'$1'") { print $4 }'
7911 }
7912
7913 # bug5265, obdfilter oa2dentry return -ENOENT
7914 # #define OBD_FAIL_SRV_ENOENT 0x217
7915 test_69() {
7916         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7917         remote_ost_nodsh && skip "remote OST with nodsh"
7918
7919         f="$DIR/$tfile"
7920         $LFS setstripe -c 1 -i 0 $f
7921
7922         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
7923
7924         do_facet ost1 lctl set_param fail_loc=0x217
7925         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
7926         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
7927
7928         do_facet ost1 lctl set_param fail_loc=0
7929         $DIRECTIO write $f 0 2 || error "write error"
7930
7931         cancel_lru_locks osc
7932         $DIRECTIO read $f 0 1 || error "read error"
7933
7934         do_facet ost1 lctl set_param fail_loc=0x217
7935         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
7936
7937         do_facet ost1 lctl set_param fail_loc=0
7938         rm -f $f
7939 }
7940 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
7941
7942 test_71() {
7943         test_mkdir $DIR/$tdir
7944         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
7945         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
7946 }
7947 run_test 71 "Running dbench on lustre (don't segment fault) ===="
7948
7949 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
7950         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7951         [ "$RUNAS_ID" = "$UID" ] &&
7952                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7953         # Check that testing environment is properly set up. Skip if not
7954         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
7955                 skip_env "User $RUNAS_ID does not exist - skipping"
7956
7957         touch $DIR/$tfile
7958         chmod 777 $DIR/$tfile
7959         chmod ug+s $DIR/$tfile
7960         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
7961                 error "$RUNAS dd $DIR/$tfile failed"
7962         # See if we are still setuid/sgid
7963         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
7964                 error "S/gid is not dropped on write"
7965         # Now test that MDS is updated too
7966         cancel_lru_locks mdc
7967         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
7968                 error "S/gid is not dropped on MDS"
7969         rm -f $DIR/$tfile
7970 }
7971 run_test 72a "Test that remove suid works properly (bug5695) ===="
7972
7973 test_72b() { # bug 24226 -- keep mode setting when size is not changing
7974         local perm
7975
7976         [ "$RUNAS_ID" = "$UID" ] &&
7977                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7978         [ "$RUNAS_ID" -eq 0 ] &&
7979                 skip_env "RUNAS_ID = 0 -- skipping"
7980         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7981         # Check that testing environment is properly set up. Skip if not
7982         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
7983                 skip_env "User $RUNAS_ID does not exist - skipping"
7984
7985         touch $DIR/${tfile}-f{g,u}
7986         test_mkdir $DIR/${tfile}-dg
7987         test_mkdir $DIR/${tfile}-du
7988         chmod 770 $DIR/${tfile}-{f,d}{g,u}
7989         chmod g+s $DIR/${tfile}-{f,d}g
7990         chmod u+s $DIR/${tfile}-{f,d}u
7991         for perm in 777 2777 4777; do
7992                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
7993                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
7994                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
7995                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
7996         done
7997         true
7998 }
7999 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
8000
8001 # bug 3462 - multiple simultaneous MDC requests
8002 test_73() {
8003         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8004
8005         test_mkdir $DIR/d73-1
8006         test_mkdir $DIR/d73-2
8007         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
8008         pid1=$!
8009
8010         lctl set_param fail_loc=0x80000129
8011         $MULTIOP $DIR/d73-1/f73-2 Oc &
8012         sleep 1
8013         lctl set_param fail_loc=0
8014
8015         $MULTIOP $DIR/d73-2/f73-3 Oc &
8016         pid3=$!
8017
8018         kill -USR1 $pid1
8019         wait $pid1 || return 1
8020
8021         sleep 25
8022
8023         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
8024         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
8025         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
8026
8027         rm -rf $DIR/d73-*
8028 }
8029 run_test 73 "multiple MDC requests (should not deadlock)"
8030
8031 test_74a() { # bug 6149, 6184
8032         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8033
8034         touch $DIR/f74a
8035         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8036         #
8037         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8038         # will spin in a tight reconnection loop
8039         $LCTL set_param fail_loc=0x8000030e
8040         # get any lock that won't be difficult - lookup works.
8041         ls $DIR/f74a
8042         $LCTL set_param fail_loc=0
8043         rm -f $DIR/f74a
8044         true
8045 }
8046 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
8047
8048 test_74b() { # bug 13310
8049         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8050
8051         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8052         #
8053         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8054         # will spin in a tight reconnection loop
8055         $LCTL set_param fail_loc=0x8000030e
8056         # get a "difficult" lock
8057         touch $DIR/f74b
8058         $LCTL set_param fail_loc=0
8059         rm -f $DIR/f74b
8060         true
8061 }
8062 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
8063
8064 test_74c() {
8065         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8066
8067         #define OBD_FAIL_LDLM_NEW_LOCK
8068         $LCTL set_param fail_loc=0x319
8069         touch $DIR/$tfile && error "touch successful"
8070         $LCTL set_param fail_loc=0
8071         true
8072 }
8073 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
8074
8075 num_inodes() {
8076         awk '/lustre_inode_cache/ {print $2; exit}' /proc/slabinfo
8077 }
8078
8079 test_76() { # Now for bug 20433, added originally in bug 1443
8080         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8081
8082         local CPUS=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
8083
8084         cancel_lru_locks osc
8085         BEFORE_INODES=$(num_inodes)
8086         echo "before inodes: $BEFORE_INODES"
8087         local COUNT=1000
8088         [ "$SLOW" = "no" ] && COUNT=100
8089         for i in $(seq $COUNT); do
8090                 touch $DIR/$tfile
8091                 rm -f $DIR/$tfile
8092         done
8093         cancel_lru_locks osc
8094         AFTER_INODES=$(num_inodes)
8095         echo "after inodes: $AFTER_INODES"
8096         local wait=0
8097         while [[ $((AFTER_INODES-1*${CPUS:-1})) -gt $BEFORE_INODES ]]; do
8098                 sleep 2
8099                 AFTER_INODES=$(num_inodes)
8100                 wait=$((wait+2))
8101                 echo "wait $wait seconds inodes: $AFTER_INODES"
8102                 if [ $wait -gt 30 ]; then
8103                         error "inode slab grew from $BEFORE_INODES to $AFTER_INODES"
8104                 fi
8105         done
8106 }
8107 run_test 76 "confirm clients recycle inodes properly ===="
8108
8109
8110 export ORIG_CSUM=""
8111 set_checksums()
8112 {
8113         # Note: in sptlrpc modes which enable its own bulk checksum, the
8114         # original crc32_le bulk checksum will be automatically disabled,
8115         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
8116         # will be checked by sptlrpc code against sptlrpc bulk checksum.
8117         # In this case set_checksums() will not be no-op, because sptlrpc
8118         # bulk checksum will be enabled all through the test.
8119
8120         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
8121         lctl set_param -n osc.*.checksums $1
8122         return 0
8123 }
8124
8125 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8126                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
8127 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8128                              tr -d [] | head -n1)}
8129 set_checksum_type()
8130 {
8131         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
8132         rc=$?
8133         log "set checksum type to $1, rc = $rc"
8134         return $rc
8135 }
8136
8137 get_osc_checksum_type()
8138 {
8139         # arugment 1: OST name, like OST0000
8140         ost=$1
8141         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
8142                         sed 's/.*\[\(.*\)\].*/\1/g')
8143         rc=$?
8144         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
8145         echo $checksum_type
8146 }
8147
8148 F77_TMP=$TMP/f77-temp
8149 F77SZ=8
8150 setup_f77() {
8151         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
8152                 error "error writing to $F77_TMP"
8153 }
8154
8155 test_77a() { # bug 10889
8156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8157         $GSS && skip_env "could not run with gss"
8158
8159         [ ! -f $F77_TMP ] && setup_f77
8160         set_checksums 1
8161         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
8162         set_checksums 0
8163         rm -f $DIR/$tfile
8164 }
8165 run_test 77a "normal checksum read/write operation"
8166
8167 test_77b() { # bug 10889
8168         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8169         $GSS && skip_env "could not run with gss"
8170
8171         [ ! -f $F77_TMP ] && setup_f77
8172         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8173         $LCTL set_param fail_loc=0x80000409
8174         set_checksums 1
8175
8176         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8177                 error "dd error: $?"
8178         $LCTL set_param fail_loc=0
8179
8180         for algo in $CKSUM_TYPES; do
8181                 cancel_lru_locks osc
8182                 set_checksum_type $algo
8183                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8184                 $LCTL set_param fail_loc=0x80000408
8185                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
8186                 $LCTL set_param fail_loc=0
8187         done
8188         set_checksums 0
8189         set_checksum_type $ORIG_CSUM_TYPE
8190         rm -f $DIR/$tfile
8191 }
8192 run_test 77b "checksum error on client write, read"
8193
8194 cleanup_77c() {
8195         trap 0
8196         set_checksums 0
8197         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
8198         $check_ost &&
8199                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
8200         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
8201         $check_ost && [ -n "$ost_file_prefix" ] &&
8202                 do_facet ost1 rm -f ${ost_file_prefix}\*
8203 }
8204
8205 test_77c() {
8206         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8207         $GSS && skip_env "could not run with gss"
8208         remote_ost_nodsh && skip "remote OST with nodsh"
8209
8210         local bad1
8211         local osc_file_prefix
8212         local osc_file
8213         local check_ost=false
8214         local ost_file_prefix
8215         local ost_file
8216         local orig_cksum
8217         local dump_cksum
8218         local fid
8219
8220         # ensure corruption will occur on first OSS/OST
8221         $LFS setstripe -i 0 $DIR/$tfile
8222
8223         [ ! -f $F77_TMP ] && setup_f77
8224         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8225                 error "dd write error: $?"
8226         fid=$($LFS path2fid $DIR/$tfile)
8227
8228         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
8229         then
8230                 check_ost=true
8231                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
8232                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
8233         else
8234                 echo "OSS do not support bulk pages dump upon error"
8235         fi
8236
8237         osc_file_prefix=$($LCTL get_param -n debug_path)
8238         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
8239
8240         trap cleanup_77c EXIT
8241
8242         set_checksums 1
8243         # enable bulk pages dump upon error on Client
8244         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
8245         # enable bulk pages dump upon error on OSS
8246         $check_ost &&
8247                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
8248
8249         # flush Client cache to allow next read to reach OSS
8250         cancel_lru_locks osc
8251
8252         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
8253         $LCTL set_param fail_loc=0x80000408
8254         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
8255         $LCTL set_param fail_loc=0
8256
8257         rm -f $DIR/$tfile
8258
8259         # check cksum dump on Client
8260         osc_file=$(ls ${osc_file_prefix}*)
8261         [ -n "$osc_file" ] || error "no checksum dump file on Client"
8262         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
8263         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
8264         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
8265         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
8266                      cksum)
8267         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
8268         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8269                 error "dump content does not match on Client"
8270
8271         $check_ost || skip "No need to check cksum dump on OSS"
8272
8273         # check cksum dump on OSS
8274         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
8275         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
8276         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
8277         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
8278         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8279                 error "dump content does not match on OSS"
8280
8281         cleanup_77c
8282 }
8283 run_test 77c "checksum error on client read with debug"
8284
8285 test_77d() { # bug 10889
8286         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8287         $GSS && skip_env "could not run with gss"
8288
8289         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8290         $LCTL set_param fail_loc=0x80000409
8291         set_checksums 1
8292         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8293                 error "direct write: rc=$?"
8294         $LCTL set_param fail_loc=0
8295         set_checksums 0
8296
8297         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8298         $LCTL set_param fail_loc=0x80000408
8299         set_checksums 1
8300         cancel_lru_locks osc
8301         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8302                 error "direct read: rc=$?"
8303         $LCTL set_param fail_loc=0
8304         set_checksums 0
8305 }
8306 run_test 77d "checksum error on OST direct write, read"
8307
8308 test_77f() { # bug 10889
8309         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8310         $GSS && skip_env "could not run with gss"
8311
8312         set_checksums 1
8313         for algo in $CKSUM_TYPES; do
8314                 cancel_lru_locks osc
8315                 set_checksum_type $algo
8316                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8317                 $LCTL set_param fail_loc=0x409
8318                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
8319                         error "direct write succeeded"
8320                 $LCTL set_param fail_loc=0
8321         done
8322         set_checksum_type $ORIG_CSUM_TYPE
8323         set_checksums 0
8324 }
8325 run_test 77f "repeat checksum error on write (expect error)"
8326
8327 test_77g() { # bug 10889
8328         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8329         $GSS && skip_env "could not run with gss"
8330         remote_ost_nodsh && skip "remote OST with nodsh"
8331
8332         [ ! -f $F77_TMP ] && setup_f77
8333
8334         local file=$DIR/$tfile
8335         stack_trap "rm -f $file" EXIT
8336
8337         $LFS setstripe -c 1 -i 0 $file
8338         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
8339         do_facet ost1 lctl set_param fail_loc=0x8000021a
8340         set_checksums 1
8341         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
8342                 error "write error: rc=$?"
8343         do_facet ost1 lctl set_param fail_loc=0
8344         set_checksums 0
8345
8346         cancel_lru_locks osc
8347         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
8348         do_facet ost1 lctl set_param fail_loc=0x8000021b
8349         set_checksums 1
8350         cmp $F77_TMP $file || error "file compare failed"
8351         do_facet ost1 lctl set_param fail_loc=0
8352         set_checksums 0
8353 }
8354 run_test 77g "checksum error on OST write, read"
8355
8356 test_77k() { # LU-10906
8357         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8358         $GSS && skip_env "could not run with gss"
8359
8360         local cksum_param="osc.$FSNAME*.checksums"
8361         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
8362         local checksum
8363         local i
8364
8365         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
8366         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM" EXIT
8367         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM" \
8368                 EXIT
8369
8370         for i in 0 1; do
8371                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
8372                         error "failed to set checksum=$i on MGS"
8373                 wait_update $HOSTNAME "$get_checksum" $i
8374                 #remount
8375                 echo "remount client, checksum should be $i"
8376                 remount_client $MOUNT || error "failed to remount client"
8377                 checksum=$(eval $get_checksum)
8378                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
8379         done
8380         # remove persistent param to avoid races with checksum mountopt below
8381         do_facet mgs $LCTL set_param -P -d $cksum_param ||
8382                 error "failed to delete checksum on MGS"
8383
8384         for opt in "checksum" "nochecksum"; do
8385                 #remount with mount option
8386                 echo "remount client with option $opt, checksum should be $i"
8387                 umount_client $MOUNT || error "failed to umount client"
8388                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
8389                         error "failed to mount client with option '$opt'"
8390                 checksum=$(eval $get_checksum)
8391                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
8392                 i=$((i - 1))
8393         done
8394
8395         remount_client $MOUNT || error "failed to remount client"
8396 }
8397 run_test 77k "enable/disable checksum correctly"
8398
8399 test_77l() {
8400         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8401         $GSS && skip_env "could not run with gss"
8402
8403         set_checksums 1
8404         stack_trap "set_checksums $ORIG_CSUM" EXIT
8405         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
8406
8407         set_checksum_type invalid && error "unexpected success of invalid checksum type"
8408
8409         $LFS setstripe -c 1 -i 0 $DIR/$tfile
8410         for algo in $CKSUM_TYPES; do
8411                 set_checksum_type $algo || error "fail to set checksum type $algo"
8412                 osc_algo=$(get_osc_checksum_type OST0000)
8413                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
8414
8415                 # no locks, no reqs to let the connection idle
8416                 cancel_lru_locks osc
8417                 lru_resize_disable osc
8418                 wait_osc_import_state client ost1 IDLE
8419
8420                 # ensure ost1 is connected
8421                 stat $DIR/$tfile >/dev/null || error "can't stat"
8422                 wait_osc_import_state client ost1 FULL
8423
8424                 osc_algo=$(get_osc_checksum_type OST0000)
8425                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
8426         done
8427         return 0
8428 }
8429 run_test 77l "preferred checksum type is remembered after reconnected"
8430
8431 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
8432 rm -f $F77_TMP
8433 unset F77_TMP
8434
8435 cleanup_test_78() {
8436         trap 0
8437         rm -f $DIR/$tfile
8438 }
8439
8440 test_78() { # bug 10901
8441         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8442         remote_ost || skip_env "local OST"
8443
8444         NSEQ=5
8445         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
8446         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
8447         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
8448         echo "MemTotal: $MEMTOTAL"
8449
8450         # reserve 256MB of memory for the kernel and other running processes,
8451         # and then take 1/2 of the remaining memory for the read/write buffers.
8452         if [ $MEMTOTAL -gt 512 ] ;then
8453                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
8454         else
8455                 # for those poor memory-starved high-end clusters...
8456                 MEMTOTAL=$((MEMTOTAL / 2))
8457         fi
8458         echo "Mem to use for directio: $MEMTOTAL"
8459
8460         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
8461         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
8462         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
8463         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
8464                 head -n1)
8465         echo "Smallest OST: $SMALLESTOST"
8466         [[ $SMALLESTOST -lt 10240 ]] &&
8467                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
8468
8469         trap cleanup_test_78 EXIT
8470
8471         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
8472                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
8473
8474         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
8475         echo "File size: $F78SIZE"
8476         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
8477         for i in $(seq 1 $NSEQ); do
8478                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
8479                 echo directIO rdwr round $i of $NSEQ
8480                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
8481         done
8482
8483         cleanup_test_78
8484 }
8485 run_test 78 "handle large O_DIRECT writes correctly ============"
8486
8487 test_79() { # bug 12743
8488         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8489
8490         wait_delete_completed
8491
8492         BKTOTAL=$(calc_osc_kbytes kbytestotal)
8493         BKFREE=$(calc_osc_kbytes kbytesfree)
8494         BKAVAIL=$(calc_osc_kbytes kbytesavail)
8495
8496         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
8497         DFTOTAL=`echo $STRING | cut -d, -f1`
8498         DFUSED=`echo $STRING  | cut -d, -f2`
8499         DFAVAIL=`echo $STRING | cut -d, -f3`
8500         DFFREE=$(($DFTOTAL - $DFUSED))
8501
8502         ALLOWANCE=$((64 * $OSTCOUNT))
8503
8504         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
8505            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
8506                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
8507         fi
8508         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
8509            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
8510                 error "df free($DFFREE) mismatch OST free($BKFREE)"
8511         fi
8512         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
8513            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
8514                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
8515         fi
8516 }
8517 run_test 79 "df report consistency check ======================="
8518
8519 test_80() { # bug 10718
8520         remote_ost_nodsh && skip "remote OST with nodsh"
8521         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8522
8523         # relax strong synchronous semantics for slow backends like ZFS
8524         local soc="obdfilter.*.sync_on_lock_cancel"
8525         local soc_old=$(do_facet ost1 lctl get_param -n $soc | head -n1)
8526         local hosts=
8527         if [ "$soc_old" != "never" ] &&
8528                 [ "$ost1_FSTYPE" != "ldiskfs" ]; then
8529                         hosts=$(for host in $(seq -f "ost%g" 1 $OSTCOUNT); do
8530                                 facet_active_host $host; done | sort -u)
8531                         do_nodes $hosts lctl set_param $soc=never
8532         fi
8533
8534         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
8535         sync; sleep 1; sync
8536         local BEFORE=`date +%s`
8537         cancel_lru_locks osc
8538         local AFTER=`date +%s`
8539         local DIFF=$((AFTER-BEFORE))
8540         if [ $DIFF -gt 1 ] ; then
8541                 error "elapsed for 1M@1T = $DIFF"
8542         fi
8543
8544         [ -n "$hosts" ] && do_nodes $hosts lctl set_param $soc=$soc_old
8545
8546         rm -f $DIR/$tfile
8547 }
8548 run_test 80 "Page eviction is equally fast at high offsets too  ===="
8549
8550 test_81a() { # LU-456
8551         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8552         remote_ost_nodsh && skip "remote OST with nodsh"
8553
8554         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
8555         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
8556         do_facet ost1 lctl set_param fail_loc=0x80000228
8557
8558         # write should trigger a retry and success
8559         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8560         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
8561         RC=$?
8562         if [ $RC -ne 0 ] ; then
8563                 error "write should success, but failed for $RC"
8564         fi
8565 }
8566 run_test 81a "OST should retry write when get -ENOSPC ==============="
8567
8568 test_81b() { # LU-456
8569         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8570         remote_ost_nodsh && skip "remote OST with nodsh"
8571
8572         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
8573         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
8574         do_facet ost1 lctl set_param fail_loc=0x228
8575
8576         # write should retry several times and return -ENOSPC finally
8577         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8578         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
8579         RC=$?
8580         ENOSPC=28
8581         if [ $RC -ne $ENOSPC ] ; then
8582                 error "dd should fail for -ENOSPC, but succeed."
8583         fi
8584 }
8585 run_test 81b "OST should return -ENOSPC when retry still fails ======="
8586
8587 test_82() { # LU-1031
8588         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10
8589         local gid1=14091995
8590         local gid2=16022000
8591
8592         multiop_bg_pause $DIR/$tfile OG${gid1}_g${gid1}c || return 1
8593         local MULTIPID1=$!
8594         multiop_bg_pause $DIR/$tfile O_G${gid2}r10g${gid2}c || return 2
8595         local MULTIPID2=$!
8596         kill -USR1 $MULTIPID2
8597         sleep 2
8598         if [[ `ps h -o comm -p $MULTIPID2` == "" ]]; then
8599                 error "First grouplock does not block second one"
8600         else
8601                 echo "Second grouplock blocks first one"
8602         fi
8603         kill -USR1 $MULTIPID1
8604         wait $MULTIPID1
8605         wait $MULTIPID2
8606 }
8607 run_test 82 "Basic grouplock test"
8608
8609 test_99() {
8610         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
8611
8612         test_mkdir $DIR/$tdir.cvsroot
8613         chown $RUNAS_ID $DIR/$tdir.cvsroot
8614
8615         cd $TMP
8616         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
8617
8618         cd /etc/init.d
8619         # some versions of cvs import exit(1) when asked to import links or
8620         # files they can't read.  ignore those files.
8621         local toignore=$(find . -type l -printf '-I %f\n' -o \
8622                          ! -perm /4 -printf '-I %f\n')
8623         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
8624                 $tdir.reposname vtag rtag
8625
8626         cd $DIR
8627         test_mkdir $DIR/$tdir.reposname
8628         chown $RUNAS_ID $DIR/$tdir.reposname
8629         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
8630
8631         cd $DIR/$tdir.reposname
8632         $RUNAS touch foo99
8633         $RUNAS cvs add -m 'addmsg' foo99
8634         $RUNAS cvs update
8635         $RUNAS cvs commit -m 'nomsg' foo99
8636         rm -fr $DIR/$tdir.cvsroot
8637 }
8638 run_test 99 "cvs strange file/directory operations"
8639
8640 test_100() {
8641         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8642         [[ "$NETTYPE" =~ tcp ]] ||
8643                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
8644         remote_ost_nodsh && skip "remote OST with nodsh"
8645         remote_mds_nodsh && skip "remote MDS with nodsh"
8646         remote_servers ||
8647                 skip "useless for local single node setup"
8648
8649         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
8650                 [ "$PROT" != "tcp" ] && continue
8651                 RPORT=$(echo $REMOTE | cut -d: -f2)
8652                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
8653
8654                 rc=0
8655                 LPORT=`echo $LOCAL | cut -d: -f2`
8656                 if [ $LPORT -ge 1024 ]; then
8657                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
8658                         netstat -tna
8659                         error_exit "local: $LPORT > 1024, remote: $RPORT"
8660                 fi
8661         done
8662         [ "$rc" = 0 ] || error_exit "privileged port not found" )
8663 }
8664 run_test 100 "check local port using privileged port ==========="
8665
8666 function get_named_value()
8667 {
8668     local tag
8669
8670     tag=$1
8671     while read ;do
8672         line=$REPLY
8673         case $line in
8674         $tag*)
8675             echo $line | sed "s/^$tag[ ]*//"
8676             break
8677             ;;
8678         esac
8679     done
8680 }
8681
8682 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
8683                    awk '/^max_cached_mb/ { print $2 }')
8684
8685 cleanup_101a() {
8686         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
8687         trap 0
8688 }
8689
8690 test_101a() {
8691         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8692
8693         local s
8694         local discard
8695         local nreads=10000
8696         local cache_limit=32
8697
8698         $LCTL set_param -n osc.*-osc*.rpc_stats 0
8699         trap cleanup_101a EXIT
8700         $LCTL set_param -n llite.*.read_ahead_stats 0
8701         $LCTL set_param -n llite.*.max_cached_mb $cache_limit
8702
8703         #
8704         # randomly read 10000 of 64K chunks from file 3x 32MB in size
8705         #
8706         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
8707         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
8708
8709         discard=0
8710         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
8711                 get_named_value 'read but discarded' | cut -d" " -f1); do
8712                         discard=$(($discard + $s))
8713         done
8714         cleanup_101a
8715
8716         $LCTL get_param osc.*-osc*.rpc_stats
8717         $LCTL get_param llite.*.read_ahead_stats
8718
8719         # Discard is generally zero, but sometimes a few random reads line up
8720         # and trigger larger readahead, which is wasted & leads to discards.
8721         if [[ $(($discard)) -gt $nreads ]]; then
8722                 error "too many ($discard) discarded pages"
8723         fi
8724         rm -f $DIR/$tfile || true
8725 }
8726 run_test 101a "check read-ahead for random reads"
8727
8728 setup_test101bc() {
8729         test_mkdir $DIR/$tdir
8730         local ssize=$1
8731         local FILE_LENGTH=$2
8732         STRIPE_OFFSET=0
8733
8734         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
8735
8736         local list=$(comma_list $(osts_nodes))
8737         set_osd_param $list '' read_cache_enable 0
8738         set_osd_param $list '' writethrough_cache_enable 0
8739
8740         trap cleanup_test101bc EXIT
8741         # prepare the read-ahead file
8742         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
8743
8744         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
8745                                 count=$FILE_SIZE_MB 2> /dev/null
8746
8747 }
8748
8749 cleanup_test101bc() {
8750         trap 0
8751         rm -rf $DIR/$tdir
8752         rm -f $DIR/$tfile
8753
8754         local list=$(comma_list $(osts_nodes))
8755         set_osd_param $list '' read_cache_enable 1
8756         set_osd_param $list '' writethrough_cache_enable 1
8757 }
8758
8759 calc_total() {
8760         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
8761 }
8762
8763 ra_check_101() {
8764         local READ_SIZE=$1
8765         local STRIPE_SIZE=$2
8766         local FILE_LENGTH=$3
8767         local RA_INC=1048576
8768         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
8769         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
8770                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
8771         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
8772                         get_named_value 'read but discarded' |
8773                         cut -d" " -f1 | calc_total)
8774         if [[ $DISCARD -gt $discard_limit ]]; then
8775                 $LCTL get_param llite.*.read_ahead_stats
8776                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
8777         else
8778                 echo "Read-ahead success for size ${READ_SIZE}"
8779         fi
8780 }
8781
8782 test_101b() {
8783         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8784         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8785
8786         local STRIPE_SIZE=1048576
8787         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
8788
8789         if [ $SLOW == "yes" ]; then
8790                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
8791         else
8792                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
8793         fi
8794
8795         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
8796
8797         # prepare the read-ahead file
8798         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
8799         cancel_lru_locks osc
8800         for BIDX in 2 4 8 16 32 64 128 256
8801         do
8802                 local BSIZE=$((BIDX*4096))
8803                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
8804                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
8805                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
8806                 $LCTL set_param -n llite.*.read_ahead_stats 0
8807                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
8808                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
8809                 cancel_lru_locks osc
8810                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
8811         done
8812         cleanup_test101bc
8813         true
8814 }
8815 run_test 101b "check stride-io mode read-ahead ================="
8816
8817 test_101c() {
8818         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8819
8820         local STRIPE_SIZE=1048576
8821         local FILE_LENGTH=$((STRIPE_SIZE*100))
8822         local nreads=10000
8823         local rsize=65536
8824         local osc_rpc_stats
8825
8826         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
8827
8828         cancel_lru_locks osc
8829         $LCTL set_param osc.*.rpc_stats 0
8830         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
8831         $LCTL get_param osc.*.rpc_stats
8832         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
8833                 local stats=$($LCTL get_param -n $osc_rpc_stats)
8834                 local lines=$(echo "$stats" | awk 'END {print NR;}')
8835                 local size
8836
8837                 if [ $lines -le 20 ]; then
8838                         echo "continue debug"
8839                         continue
8840                 fi
8841                 for size in 1 2 4 8; do
8842                         local rpc=$(echo "$stats" |
8843                                     awk '($1 == "'$size':") {print $2; exit; }')
8844                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
8845                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
8846                 done
8847                 echo "$osc_rpc_stats check passed!"
8848         done
8849         cleanup_test101bc
8850         true
8851 }
8852 run_test 101c "check stripe_size aligned read-ahead ================="
8853
8854 set_read_ahead() {
8855         $LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1
8856         $LCTL set_param -n llite.*.max_read_ahead_mb $1 > /dev/null 2>&1
8857 }
8858
8859 test_101d() {
8860         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8861
8862         local file=$DIR/$tfile
8863         local sz_MB=${FILESIZE_101d:-500}
8864         local ra_MB=${READAHEAD_MB:-40}
8865
8866         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
8867         [ $free_MB -lt $sz_MB ] &&
8868                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
8869
8870         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
8871         $LFS setstripe -c -1 $file || error "setstripe failed"
8872
8873         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
8874         echo Cancel LRU locks on lustre client to flush the client cache
8875         cancel_lru_locks osc
8876
8877         echo Disable read-ahead
8878         local old_READAHEAD=$(set_read_ahead 0)
8879
8880         echo Reading the test file $file with read-ahead disabled
8881         local raOFF=$(do_and_time "dd if=$file of=/dev/null bs=1M count=$sz_MB")
8882
8883         echo Cancel LRU locks on lustre client to flush the client cache
8884         cancel_lru_locks osc
8885         echo Enable read-ahead with ${ra_MB}MB
8886         set_read_ahead $ra_MB
8887
8888         echo Reading the test file $file with read-ahead enabled
8889         local raON=$(do_and_time "dd if=$file of=/dev/null bs=1M count=$sz_MB")
8890
8891         echo "read-ahead disabled time read $raOFF"
8892         echo "read-ahead enabled  time read $raON"
8893
8894         set_read_ahead $old_READAHEAD
8895         rm -f $file
8896         wait_delete_completed
8897
8898         [ $raOFF -le 1 ] || [ $raON -lt $raOFF ] ||
8899                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
8900 }
8901 run_test 101d "file read with and without read-ahead enabled"
8902
8903 test_101e() {
8904         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8905
8906         local file=$DIR/$tfile
8907         local size_KB=500  #KB
8908         local count=100
8909         local bsize=1024
8910
8911         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
8912         local need_KB=$((count * size_KB))
8913         [[ $free_KB -le $need_KB ]] &&
8914                 skip_env "Need free space $need_KB, have $free_KB"
8915
8916         echo "Creating $count ${size_KB}K test files"
8917         for ((i = 0; i < $count; i++)); do
8918                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
8919         done
8920
8921         echo "Cancel LRU locks on lustre client to flush the client cache"
8922         cancel_lru_locks $OSC
8923
8924         echo "Reset readahead stats"
8925         $LCTL set_param -n llite.*.read_ahead_stats 0
8926
8927         for ((i = 0; i < $count; i++)); do
8928                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
8929         done
8930
8931         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
8932                      get_named_value 'misses' | cut -d" " -f1 | calc_total)
8933
8934         for ((i = 0; i < $count; i++)); do
8935                 rm -rf $file.$i 2>/dev/null
8936         done
8937
8938         #10000 means 20% reads are missing in readahead
8939         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
8940 }
8941 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
8942
8943 test_101f() {
8944         which iozone || skip_env "no iozone installed"
8945
8946         local old_debug=$($LCTL get_param debug)
8947         old_debug=${old_debug#*=}
8948         $LCTL set_param debug="reada mmap"
8949
8950         # create a test file
8951         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
8952
8953         echo Cancel LRU locks on lustre client to flush the client cache
8954         cancel_lru_locks osc
8955
8956         echo Reset readahead stats
8957         $LCTL set_param -n llite.*.read_ahead_stats 0
8958
8959         echo mmap read the file with small block size
8960         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
8961                 > /dev/null 2>&1
8962
8963         echo checking missing pages
8964         $LCTL get_param llite.*.read_ahead_stats
8965         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
8966                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
8967
8968         $LCTL set_param debug="$old_debug"
8969         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
8970         rm -f $DIR/$tfile
8971 }
8972 run_test 101f "check mmap read performance"
8973
8974 test_101g_brw_size_test() {
8975         local mb=$1
8976         local pages=$((mb * 1048576 / PAGE_SIZE))
8977         local file=$DIR/$tfile
8978
8979         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
8980                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
8981         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
8982                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
8983                         return 2
8984         done
8985
8986         stack_trap "rm -f $file" EXIT
8987         $LCTL set_param -n osc.*.rpc_stats=0
8988
8989         # 10 RPCs should be enough for the test
8990         local count=10
8991         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
8992                 { error "dd write ${mb} MB blocks failed"; return 3; }
8993         cancel_lru_locks osc
8994         dd of=/dev/null if=$file bs=${mb}M count=$count ||
8995                 { error "dd write ${mb} MB blocks failed"; return 4; }
8996
8997         # calculate number of full-sized read and write RPCs
8998         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
8999                 sed -n '/pages per rpc/,/^$/p' |
9000                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
9001                 END { print reads,writes }'))
9002         [ ${rpcs[0]} -ne $count ] && error "${rpcs[0]} != $count read RPCs" &&
9003                 return 5
9004         [ ${rpcs[1]} -ne $count ] && error "${rpcs[1]} != $count write RPCs" &&
9005                 return 6
9006
9007         return 0
9008 }
9009
9010 test_101g() {
9011         remote_ost_nodsh && skip "remote OST with nodsh"
9012
9013         local rpcs
9014         local osts=$(get_facets OST)
9015         local list=$(comma_list $(osts_nodes))
9016         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9017         local brw_size="obdfilter.*.brw_size"
9018
9019         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9020
9021         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
9022
9023         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
9024                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
9025                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
9026            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
9027                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
9028                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
9029
9030                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
9031                         suffix="M"
9032
9033                 if [[ $orig_mb -lt 16 ]]; then
9034                         save_lustre_params $osts "$brw_size" > $p
9035                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
9036                                 error "set 16MB RPC size failed"
9037
9038                         echo "remount client to enable new RPC size"
9039                         remount_client $MOUNT || error "remount_client failed"
9040                 fi
9041
9042                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
9043                 # should be able to set brw_size=12, but no rpc_stats for that
9044                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
9045         fi
9046
9047         test_101g_brw_size_test 4 || error "4MB RPC test failed"
9048
9049         if [[ $orig_mb -lt 16 ]]; then
9050                 restore_lustre_params < $p
9051                 remount_client $MOUNT || error "remount_client restore failed"
9052         fi
9053
9054         rm -f $p $DIR/$tfile
9055 }
9056 run_test 101g "Big bulk(4/16 MiB) readahead"
9057
9058 test_101h() {
9059         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9060
9061         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
9062                 error "dd 70M file failed"
9063         echo Cancel LRU locks on lustre client to flush the client cache
9064         cancel_lru_locks osc
9065
9066         echo "Reset readahead stats"
9067         $LCTL set_param -n llite.*.read_ahead_stats 0
9068
9069         echo "Read 10M of data but cross 64M bundary"
9070         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
9071         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9072                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9073         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
9074         rm -f $p $DIR/$tfile
9075 }
9076 run_test 101h "Readahead should cover current read window"
9077
9078 setup_test102() {
9079         test_mkdir $DIR/$tdir
9080         chown $RUNAS_ID $DIR/$tdir
9081         STRIPE_SIZE=65536
9082         STRIPE_OFFSET=1
9083         STRIPE_COUNT=$OSTCOUNT
9084         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
9085
9086         trap cleanup_test102 EXIT
9087         cd $DIR
9088         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
9089         cd $DIR/$tdir
9090         for num in 1 2 3 4; do
9091                 for count in $(seq 1 $STRIPE_COUNT); do
9092                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
9093                                 local size=`expr $STRIPE_SIZE \* $num`
9094                                 local file=file"$num-$idx-$count"
9095                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
9096                         done
9097                 done
9098         done
9099
9100         cd $DIR
9101         $1 tar cf $TMP/f102.tar $tdir --xattrs
9102 }
9103
9104 cleanup_test102() {
9105         trap 0
9106         rm -f $TMP/f102.tar
9107         rm -rf $DIR/d0.sanity/d102
9108 }
9109
9110 test_102a() {
9111         [ "$UID" != 0 ] && skip "must run as root"
9112         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
9113                 skip_env "must have user_xattr"
9114
9115         [ -z "$(which setfattr 2>/dev/null)" ] &&
9116                 skip_env "could not find setfattr"
9117
9118         local testfile=$DIR/$tfile
9119
9120         touch $testfile
9121         echo "set/get xattr..."
9122         setfattr -n trusted.name1 -v value1 $testfile ||
9123                 error "setfattr -n trusted.name1=value1 $testfile failed"
9124         getfattr -n trusted.name1 $testfile 2> /dev/null |
9125           grep "trusted.name1=.value1" ||
9126                 error "$testfile missing trusted.name1=value1"
9127
9128         setfattr -n user.author1 -v author1 $testfile ||
9129                 error "setfattr -n user.author1=author1 $testfile failed"
9130         getfattr -n user.author1 $testfile 2> /dev/null |
9131           grep "user.author1=.author1" ||
9132                 error "$testfile missing trusted.author1=author1"
9133
9134         echo "listxattr..."
9135         setfattr -n trusted.name2 -v value2 $testfile ||
9136                 error "$testfile unable to set trusted.name2"
9137         setfattr -n trusted.name3 -v value3 $testfile ||
9138                 error "$testfile unable to set trusted.name3"
9139         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
9140             grep "trusted.name" | wc -l) -eq 3 ] ||
9141                 error "$testfile missing 3 trusted.name xattrs"
9142
9143         setfattr -n user.author2 -v author2 $testfile ||
9144                 error "$testfile unable to set user.author2"
9145         setfattr -n user.author3 -v author3 $testfile ||
9146                 error "$testfile unable to set user.author3"
9147         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
9148             grep "user.author" | wc -l) -eq 3 ] ||
9149                 error "$testfile missing 3 user.author xattrs"
9150
9151         echo "remove xattr..."
9152         setfattr -x trusted.name1 $testfile ||
9153                 error "$testfile error deleting trusted.name1"
9154         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
9155                 error "$testfile did not delete trusted.name1 xattr"
9156
9157         setfattr -x user.author1 $testfile ||
9158                 error "$testfile error deleting user.author1"
9159         echo "set lustre special xattr ..."
9160         $LFS setstripe -c1 $testfile
9161         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
9162                 awk -F "=" '/trusted.lov/ { print $2 }' )
9163         setfattr -n "trusted.lov" -v $lovea $testfile ||
9164                 error "$testfile doesn't ignore setting trusted.lov again"
9165         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
9166                 error "$testfile allow setting invalid trusted.lov"
9167         rm -f $testfile
9168 }
9169 run_test 102a "user xattr test =================================="
9170
9171 test_102b() {
9172         [ -z "$(which setfattr 2>/dev/null)" ] &&
9173                 skip_env "could not find setfattr"
9174         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9175
9176         # b10930: get/set/list trusted.lov xattr
9177         echo "get/set/list trusted.lov xattr ..."
9178         local testfile=$DIR/$tfile
9179         $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
9180                 error "setstripe failed"
9181         local STRIPECOUNT=$($LFS getstripe -c $testfile) ||
9182                 error "getstripe failed"
9183         getfattr -d -m "^trusted" $testfile 2>/dev/null | grep "trusted.lov" ||
9184                 error "can't get trusted.lov from $testfile"
9185
9186         local testfile2=${testfile}2
9187         local value=$(getfattr -n trusted.lov $testfile 2>/dev/null |
9188                         grep "trusted.lov" | sed -e 's/[^=]\+=//')
9189
9190         $MCREATE $testfile2
9191         setfattr -n trusted.lov -v $value $testfile2
9192         local stripe_size=$($LFS getstripe -S $testfile2)
9193         local stripe_count=$($LFS getstripe -c $testfile2)
9194         [[ $stripe_size -eq 65536 ]] ||
9195                 error "stripe size $stripe_size != 65536"
9196         [[ $stripe_count -eq $STRIPECOUNT ]] ||
9197                 error "stripe count $stripe_count != $STRIPECOUNT"
9198         rm -f $DIR/$tfile
9199 }
9200 run_test 102b "getfattr/setfattr for trusted.lov EAs ============"
9201
9202 test_102c() {
9203         [ -z "$(which setfattr 2>/dev/null)" ] &&
9204                 skip_env "could not find setfattr"
9205         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9206
9207         # b10930: get/set/list lustre.lov xattr
9208         echo "get/set/list lustre.lov xattr ..."
9209         test_mkdir $DIR/$tdir
9210         chown $RUNAS_ID $DIR/$tdir
9211         local testfile=$DIR/$tdir/$tfile
9212         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
9213                 error "setstripe failed"
9214         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
9215                 error "getstripe failed"
9216         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
9217         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
9218
9219         local testfile2=${testfile}2
9220         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
9221                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
9222
9223         $RUNAS $MCREATE $testfile2
9224         $RUNAS setfattr -n lustre.lov -v $value $testfile2
9225         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
9226         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
9227         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
9228         [ $stripe_count -eq $STRIPECOUNT ] ||
9229                 error "stripe count $stripe_count != $STRIPECOUNT"
9230 }
9231 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
9232
9233 compare_stripe_info1() {
9234         local stripe_index_all_zero=true
9235
9236         for num in 1 2 3 4; do
9237                 for count in $(seq 1 $STRIPE_COUNT); do
9238                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
9239                                 local size=$((STRIPE_SIZE * num))
9240                                 local file=file"$num-$offset-$count"
9241                                 stripe_size=$($LFS getstripe -S $PWD/$file)
9242                                 [[ $stripe_size -ne $size ]] &&
9243                                     error "$file: size $stripe_size != $size"
9244                                 stripe_count=$($LFS getstripe -c $PWD/$file)
9245                                 # allow fewer stripes to be created, ORI-601
9246                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
9247                                     error "$file: count $stripe_count != $count"
9248                                 stripe_index=$($LFS getstripe -i $PWD/$file)
9249                                 [[ $stripe_index -ne 0 ]] &&
9250                                         stripe_index_all_zero=false
9251                         done
9252                 done
9253         done
9254         $stripe_index_all_zero &&
9255                 error "all files are being extracted starting from OST index 0"
9256         return 0
9257 }
9258
9259 have_xattrs_include() {
9260         tar --help | grep -q xattrs-include &&
9261                 echo --xattrs-include="lustre.*"
9262 }
9263
9264 test_102d() {
9265         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9266         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9267
9268         XINC=$(have_xattrs_include)
9269         setup_test102
9270         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
9271         cd $DIR/$tdir/$tdir
9272         compare_stripe_info1
9273 }
9274 run_test 102d "tar restore stripe info from tarfile,not keep osts"
9275
9276 test_102f() {
9277         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9278         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9279
9280         XINC=$(have_xattrs_include)
9281         setup_test102
9282         test_mkdir $DIR/$tdir.restore
9283         cd $DIR
9284         tar cf - --xattrs $tdir | tar xf - \
9285                 -C $DIR/$tdir.restore --xattrs $XINC
9286         cd $DIR/$tdir.restore/$tdir
9287         compare_stripe_info1
9288 }
9289 run_test 102f "tar copy files, not keep osts"
9290
9291 grow_xattr() {
9292         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
9293                 skip "must have user_xattr"
9294         [ -z "$(which setfattr 2>/dev/null)" ] &&
9295                 skip_env "could not find setfattr"
9296         [ -z "$(which getfattr 2>/dev/null)" ] &&
9297                 skip_env "could not find getfattr"
9298
9299         local xsize=${1:-1024}  # in bytes
9300         local file=$DIR/$tfile
9301         local value="$(generate_string $xsize)"
9302         local xbig=trusted.big
9303         local toobig=$2
9304
9305         touch $file
9306         log "save $xbig on $file"
9307         if [ -z "$toobig" ]
9308         then
9309                 setfattr -n $xbig -v $value $file ||
9310                         error "saving $xbig on $file failed"
9311         else
9312                 setfattr -n $xbig -v $value $file &&
9313                         error "saving $xbig on $file succeeded"
9314                 return 0
9315         fi
9316
9317         local orig=$(get_xattr_value $xbig $file)
9318         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
9319
9320         local xsml=trusted.sml
9321         log "save $xsml on $file"
9322         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
9323
9324         local new=$(get_xattr_value $xbig $file)
9325         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
9326
9327         log "grow $xsml on $file"
9328         setfattr -n $xsml -v "$value" $file ||
9329                 error "growing $xsml on $file failed"
9330
9331         new=$(get_xattr_value $xbig $file)
9332         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
9333         log "$xbig still valid after growing $xsml"
9334
9335         rm -f $file
9336 }
9337
9338 test_102h() { # bug 15777
9339         grow_xattr 1024
9340 }
9341 run_test 102h "grow xattr from inside inode to external block"
9342
9343 test_102ha() {
9344         large_xattr_enabled || skip_env "ea_inode feature disabled"
9345
9346         echo "setting xattr of max xattr size: $(max_xattr_size)"
9347         grow_xattr $(max_xattr_size)
9348
9349         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
9350         echo "This should fail:"
9351         grow_xattr $(($(max_xattr_size) + 10)) 1
9352 }
9353 run_test 102ha "grow xattr from inside inode to external inode"
9354
9355 test_102i() { # bug 17038
9356         [ -z "$(which getfattr 2>/dev/null)" ] &&
9357                 skip "could not find getfattr"
9358
9359         touch $DIR/$tfile
9360         ln -s $DIR/$tfile $DIR/${tfile}link
9361         getfattr -n trusted.lov $DIR/$tfile ||
9362                 error "lgetxattr on $DIR/$tfile failed"
9363         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
9364                 grep -i "no such attr" ||
9365                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
9366         rm -f $DIR/$tfile $DIR/${tfile}link
9367 }
9368 run_test 102i "lgetxattr test on symbolic link ============"
9369
9370 test_102j() {
9371         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9372         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9373
9374         XINC=$(have_xattrs_include)
9375         setup_test102 "$RUNAS"
9376         chown $RUNAS_ID $DIR/$tdir
9377         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
9378         cd $DIR/$tdir/$tdir
9379         compare_stripe_info1 "$RUNAS"
9380 }
9381 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
9382
9383 test_102k() {
9384         [ -z "$(which setfattr 2>/dev/null)" ] &&
9385                 skip "could not find setfattr"
9386
9387         touch $DIR/$tfile
9388         # b22187 just check that does not crash for regular file.
9389         setfattr -n trusted.lov $DIR/$tfile
9390         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
9391         local test_kdir=$DIR/$tdir
9392         test_mkdir $test_kdir
9393         local default_size=$($LFS getstripe -S $test_kdir)
9394         local default_count=$($LFS getstripe -c $test_kdir)
9395         local default_offset=$($LFS getstripe -i $test_kdir)
9396         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
9397                 error 'dir setstripe failed'
9398         setfattr -n trusted.lov $test_kdir
9399         local stripe_size=$($LFS getstripe -S $test_kdir)
9400         local stripe_count=$($LFS getstripe -c $test_kdir)
9401         local stripe_offset=$($LFS getstripe -i $test_kdir)
9402         [ $stripe_size -eq $default_size ] ||
9403                 error "stripe size $stripe_size != $default_size"
9404         [ $stripe_count -eq $default_count ] ||
9405                 error "stripe count $stripe_count != $default_count"
9406         [ $stripe_offset -eq $default_offset ] ||
9407                 error "stripe offset $stripe_offset != $default_offset"
9408         rm -rf $DIR/$tfile $test_kdir
9409 }
9410 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
9411
9412 test_102l() {
9413         [ -z "$(which getfattr 2>/dev/null)" ] &&
9414                 skip "could not find getfattr"
9415
9416         # LU-532 trusted. xattr is invisible to non-root
9417         local testfile=$DIR/$tfile
9418
9419         touch $testfile
9420
9421         echo "listxattr as user..."
9422         chown $RUNAS_ID $testfile
9423         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
9424             grep -q "trusted" &&
9425                 error "$testfile trusted xattrs are user visible"
9426
9427         return 0;
9428 }
9429 run_test 102l "listxattr size test =================================="
9430
9431 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
9432         local path=$DIR/$tfile
9433         touch $path
9434
9435         listxattr_size_check $path || error "listattr_size_check $path failed"
9436 }
9437 run_test 102m "Ensure listxattr fails on small bufffer ========"
9438
9439 cleanup_test102
9440
9441 getxattr() { # getxattr path name
9442         # Return the base64 encoding of the value of xattr name on path.
9443         local path=$1
9444         local name=$2
9445
9446         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
9447         # file: $path
9448         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
9449         #
9450         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
9451
9452         getfattr --absolute-names --encoding=base64 --name=$name $path |
9453                 awk -F= -v name=$name '$1 == name {
9454                         print substr($0, index($0, "=") + 1);
9455         }'
9456 }
9457
9458 test_102n() { # LU-4101 mdt: protect internal xattrs
9459         [ -z "$(which setfattr 2>/dev/null)" ] &&
9460                 skip "could not find setfattr"
9461         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
9462         then
9463                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
9464         fi
9465
9466         local file0=$DIR/$tfile.0
9467         local file1=$DIR/$tfile.1
9468         local xattr0=$TMP/$tfile.0
9469         local xattr1=$TMP/$tfile.1
9470         local namelist="lov lma lmv link fid version som hsm"
9471         local name
9472         local value
9473
9474         rm -rf $file0 $file1 $xattr0 $xattr1
9475         touch $file0 $file1
9476
9477         # Get 'before' xattrs of $file1.
9478         getfattr --absolute-names --dump --match=- $file1 > $xattr0
9479
9480         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
9481                 namelist+=" lfsck_namespace"
9482         for name in $namelist; do
9483                 # Try to copy xattr from $file0 to $file1.
9484                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
9485
9486                 setfattr --name=trusted.$name --value="$value" $file1 ||
9487                         error "setxattr 'trusted.$name' failed"
9488
9489                 # Try to set a garbage xattr.
9490                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
9491
9492                 if [[ x$name == "xlov" ]]; then
9493                         setfattr --name=trusted.lov --value="$value" $file1 &&
9494                         error "setxattr invalid 'trusted.lov' success"
9495                 else
9496                         setfattr --name=trusted.$name --value="$value" $file1 ||
9497                                 error "setxattr invalid 'trusted.$name' failed"
9498                 fi
9499
9500                 # Try to remove the xattr from $file1. We don't care if this
9501                 # appears to succeed or fail, we just don't want there to be
9502                 # any changes or crashes.
9503                 setfattr --remove=$trusted.$name $file1 2> /dev/null
9504         done
9505
9506         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
9507         then
9508                 name="lfsck_ns"
9509                 # Try to copy xattr from $file0 to $file1.
9510                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
9511
9512                 setfattr --name=trusted.$name --value="$value" $file1 ||
9513                         error "setxattr 'trusted.$name' failed"
9514
9515                 # Try to set a garbage xattr.
9516                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
9517
9518                 setfattr --name=trusted.$name --value="$value" $file1 ||
9519                         error "setxattr 'trusted.$name' failed"
9520
9521                 # Try to remove the xattr from $file1. We don't care if this
9522                 # appears to succeed or fail, we just don't want there to be
9523                 # any changes or crashes.
9524                 setfattr --remove=$trusted.$name $file1 2> /dev/null
9525         fi
9526
9527         # Get 'after' xattrs of file1.
9528         getfattr --absolute-names --dump --match=- $file1 > $xattr1
9529
9530         if ! diff $xattr0 $xattr1; then
9531                 error "before and after xattrs of '$file1' differ"
9532         fi
9533
9534         rm -rf $file0 $file1 $xattr0 $xattr1
9535
9536         return 0
9537 }
9538 run_test 102n "silently ignore setxattr on internal trusted xattrs"
9539
9540 test_102p() { # LU-4703 setxattr did not check ownership
9541         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
9542                 skip "MDS needs to be at least 2.5.56"
9543
9544         local testfile=$DIR/$tfile
9545
9546         touch $testfile
9547
9548         echo "setfacl as user..."
9549         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
9550         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
9551
9552         echo "setfattr as user..."
9553         setfacl -m "u:$RUNAS_ID:---" $testfile
9554         $RUNAS setfattr -x system.posix_acl_access $testfile
9555         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
9556 }
9557 run_test 102p "check setxattr(2) correctly fails without permission"
9558
9559 test_102q() {
9560         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
9561                 skip "MDS needs to be at least 2.6.92"
9562
9563         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
9564 }
9565 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
9566
9567 test_102r() {
9568         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
9569                 skip "MDS needs to be at least 2.6.93"
9570
9571         touch $DIR/$tfile || error "touch"
9572         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
9573         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
9574         rm $DIR/$tfile || error "rm"
9575
9576         #normal directory
9577         mkdir -p $DIR/$tdir || error "mkdir"
9578         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
9579         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
9580         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
9581                 error "$testfile error deleting user.author1"
9582         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
9583                 grep "user.$(basename $tdir)" &&
9584                 error "$tdir did not delete user.$(basename $tdir)"
9585         rmdir $DIR/$tdir || error "rmdir"
9586
9587         #striped directory
9588         test_mkdir $DIR/$tdir
9589         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
9590         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
9591         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
9592                 error "$testfile error deleting user.author1"
9593         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
9594                 grep "user.$(basename $tdir)" &&
9595                 error "$tdir did not delete user.$(basename $tdir)"
9596         rmdir $DIR/$tdir || error "rm striped dir"
9597 }
9598 run_test 102r "set EAs with empty values"
9599
9600 test_102s() {
9601         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
9602                 skip "MDS needs to be at least 2.11.52"
9603
9604         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
9605
9606         save_lustre_params client "llite.*.xattr_cache" > $save
9607
9608         for cache in 0 1; do
9609                 lctl set_param llite.*.xattr_cache=$cache
9610
9611                 rm -f $DIR/$tfile
9612                 touch $DIR/$tfile || error "touch"
9613                 for prefix in lustre security system trusted user; do
9614                         # Note getxattr() may fail with 'Operation not
9615                         # supported' or 'No such attribute' depending
9616                         # on prefix and cache.
9617                         getfattr -n $prefix.n102s $DIR/$tfile &&
9618                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
9619                 done
9620         done
9621
9622         restore_lustre_params < $save
9623 }
9624 run_test 102s "getting nonexistent xattrs should fail"
9625
9626 test_102t() {
9627         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
9628                 skip "MDS needs to be at least 2.11.52"
9629
9630         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
9631
9632         save_lustre_params client "llite.*.xattr_cache" > $save
9633
9634         for cache in 0 1; do
9635                 lctl set_param llite.*.xattr_cache=$cache
9636
9637                 for buf_size in 0 256; do
9638                         rm -f $DIR/$tfile
9639                         touch $DIR/$tfile || error "touch"
9640                         setfattr -n user.multiop $DIR/$tfile
9641                         $MULTIOP $DIR/$tfile oa$buf_size ||
9642                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
9643                 done
9644         done
9645
9646         restore_lustre_params < $save
9647 }
9648 run_test 102t "zero length xattr values handled correctly"
9649
9650 run_acl_subtest()
9651 {
9652     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
9653     return $?
9654 }
9655
9656 test_103a() {
9657         [ "$UID" != 0 ] && skip "must run as root"
9658         $GSS && skip_env "could not run under gss"
9659         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
9660                 skip_env "must have acl enabled"
9661         [ -z "$(which setfacl 2>/dev/null)" ] &&
9662                 skip_env "could not find setfacl"
9663         remote_mds_nodsh && skip "remote MDS with nodsh"
9664
9665         gpasswd -a daemon bin                           # LU-5641
9666         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
9667
9668         declare -a identity_old
9669
9670         for num in $(seq $MDSCOUNT); do
9671                 switch_identity $num true || identity_old[$num]=$?
9672         done
9673
9674         SAVE_UMASK=$(umask)
9675         umask 0022
9676         mkdir -p $DIR/$tdir
9677         cd $DIR/$tdir
9678
9679         echo "performing cp ..."
9680         run_acl_subtest cp || error "run_acl_subtest cp failed"
9681         echo "performing getfacl-noacl..."
9682         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
9683         echo "performing misc..."
9684         run_acl_subtest misc || error  "misc test failed"
9685         echo "performing permissions..."
9686         run_acl_subtest permissions || error "permissions failed"
9687         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
9688         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
9689                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
9690                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
9691         then
9692                 echo "performing permissions xattr..."
9693                 run_acl_subtest permissions_xattr ||
9694                         error "permissions_xattr failed"
9695         fi
9696         echo "performing setfacl..."
9697         run_acl_subtest setfacl || error  "setfacl test failed"
9698
9699         # inheritance test got from HP
9700         echo "performing inheritance..."
9701         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
9702         chmod +x make-tree || error "chmod +x failed"
9703         run_acl_subtest inheritance || error "inheritance test failed"
9704         rm -f make-tree
9705
9706         echo "LU-974 ignore umask when acl is enabled..."
9707         run_acl_subtest 974 || error "LU-974 umask test failed"
9708         if [ $MDSCOUNT -ge 2 ]; then
9709                 run_acl_subtest 974_remote ||
9710                         error "LU-974 umask test failed under remote dir"
9711         fi
9712
9713         echo "LU-2561 newly created file is same size as directory..."
9714         if [ "$mds1_FSTYPE" != "zfs" ]; then
9715                 run_acl_subtest 2561 || error "LU-2561 test failed"
9716         else
9717                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
9718         fi
9719
9720         run_acl_subtest 4924 || error "LU-4924 test failed"
9721
9722         cd $SAVE_PWD
9723         umask $SAVE_UMASK
9724
9725         for num in $(seq $MDSCOUNT); do
9726                 if [ "${identity_old[$num]}" = 1 ]; then
9727                         switch_identity $num false || identity_old[$num]=$?
9728                 fi
9729         done
9730 }
9731 run_test 103a "acl test"
9732
9733 test_103b() {
9734         declare -a pids
9735         local U
9736
9737         for U in {0..511}; do
9738                 {
9739                 local O=$(printf "%04o" $U)
9740
9741                 umask $(printf "%04o" $((511 ^ $O)))
9742                 $LFS setstripe -c 1 $DIR/$tfile.s$O
9743                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
9744
9745                 (( $S == ($O & 0666) )) ||
9746                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
9747
9748                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
9749                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
9750                 (( $S == ($O & 0666) )) ||
9751                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
9752
9753                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
9754                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
9755                 (( $S == ($O & 0666) )) ||
9756                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
9757                 rm -f $DIR/$tfile.[smp]$0
9758                 } &
9759                 local pid=$!
9760
9761                 # limit the concurrently running threads to 64. LU-11878
9762                 local idx=$((U % 64))
9763                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
9764                 pids[idx]=$pid
9765         done
9766         wait
9767 }
9768 run_test 103b "umask lfs setstripe"
9769
9770 test_103c() {
9771         mkdir -p $DIR/$tdir
9772         cp -rp $DIR/$tdir $DIR/$tdir.bak
9773
9774         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
9775                 error "$DIR/$tdir shouldn't contain default ACL"
9776         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
9777                 error "$DIR/$tdir.bak shouldn't contain default ACL"
9778         true
9779 }
9780 run_test 103c "'cp -rp' won't set empty acl"
9781
9782 test_104a() {
9783         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9784
9785         touch $DIR/$tfile
9786         lfs df || error "lfs df failed"
9787         lfs df -ih || error "lfs df -ih failed"
9788         lfs df -h $DIR || error "lfs df -h $DIR failed"
9789         lfs df -i $DIR || error "lfs df -i $DIR failed"
9790         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
9791         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
9792
9793         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
9794         lctl --device %$OSC deactivate
9795         lfs df || error "lfs df with deactivated OSC failed"
9796         lctl --device %$OSC activate
9797         # wait the osc back to normal
9798         wait_osc_import_ready client ost
9799
9800         lfs df || error "lfs df with reactivated OSC failed"
9801         rm -f $DIR/$tfile
9802 }
9803 run_test 104a "lfs df [-ih] [path] test ========================="
9804
9805 test_104b() {
9806         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9807         [ $RUNAS_ID -eq $UID ] &&
9808                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9809
9810         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
9811                         grep "Permission denied" | wc -l)))
9812         if [ $denied_cnt -ne 0 ]; then
9813                 error "lfs check servers test failed"
9814         fi
9815 }
9816 run_test 104b "$RUNAS lfs check servers test ===================="
9817
9818 test_105a() {
9819         # doesn't work on 2.4 kernels
9820         touch $DIR/$tfile
9821         if $(flock_is_enabled); then
9822                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
9823         else
9824                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
9825         fi
9826         rm -f $DIR/$tfile
9827 }
9828 run_test 105a "flock when mounted without -o flock test ========"
9829
9830 test_105b() {
9831         touch $DIR/$tfile
9832         if $(flock_is_enabled); then
9833                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
9834         else
9835                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
9836         fi
9837         rm -f $DIR/$tfile
9838 }
9839 run_test 105b "fcntl when mounted without -o flock test ========"
9840
9841 test_105c() {
9842         touch $DIR/$tfile
9843         if $(flock_is_enabled); then
9844                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
9845         else
9846                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
9847         fi
9848         rm -f $DIR/$tfile
9849 }
9850 run_test 105c "lockf when mounted without -o flock test"
9851
9852 test_105d() { # bug 15924
9853         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9854
9855         test_mkdir $DIR/$tdir
9856         flock_is_enabled || skip_env "mount w/o flock enabled"
9857         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
9858         $LCTL set_param fail_loc=0x80000315
9859         flocks_test 2 $DIR/$tdir
9860 }
9861 run_test 105d "flock race (should not freeze) ========"
9862
9863 test_105e() { # bug 22660 && 22040
9864         flock_is_enabled || skip_env "mount w/o flock enabled"
9865
9866         touch $DIR/$tfile
9867         flocks_test 3 $DIR/$tfile
9868 }
9869 run_test 105e "Two conflicting flocks from same process"
9870
9871 test_106() { #bug 10921
9872         test_mkdir $DIR/$tdir
9873         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
9874         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
9875 }
9876 run_test 106 "attempt exec of dir followed by chown of that dir"
9877
9878 test_107() {
9879         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9880
9881         CDIR=`pwd`
9882         local file=core
9883
9884         cd $DIR
9885         rm -f $file
9886
9887         local save_pattern=$(sysctl -n kernel.core_pattern)
9888         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
9889         sysctl -w kernel.core_pattern=$file
9890         sysctl -w kernel.core_uses_pid=0
9891
9892         ulimit -c unlimited
9893         sleep 60 &
9894         SLEEPPID=$!
9895
9896         sleep 1
9897
9898         kill -s 11 $SLEEPPID
9899         wait $SLEEPPID
9900         if [ -e $file ]; then
9901                 size=`stat -c%s $file`
9902                 [ $size -eq 0 ] && error "Fail to create core file $file"
9903         else
9904                 error "Fail to create core file $file"
9905         fi
9906         rm -f $file
9907         sysctl -w kernel.core_pattern=$save_pattern
9908         sysctl -w kernel.core_uses_pid=$save_uses_pid
9909         cd $CDIR
9910 }
9911 run_test 107 "Coredump on SIG"
9912
9913 test_110() {
9914         test_mkdir $DIR/$tdir
9915         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
9916         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
9917                 error "mkdir with 256 char should fail, but did not"
9918         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
9919                 error "create with 255 char failed"
9920         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
9921                 error "create with 256 char should fail, but did not"
9922
9923         ls -l $DIR/$tdir
9924         rm -rf $DIR/$tdir
9925 }
9926 run_test 110 "filename length checking"
9927
9928 #
9929 # Purpose: To verify dynamic thread (OSS) creation.
9930 #
9931 test_115() {
9932         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9933         remote_ost_nodsh && skip "remote OST with nodsh"
9934
9935         # Lustre does not stop service threads once they are started.
9936         # Reset number of running threads to default.
9937         stopall
9938         setupall
9939
9940         local OSTIO_pre
9941         local save_params="$TMP/sanity-$TESTNAME.parameters"
9942
9943         # Get ll_ost_io count before I/O
9944         OSTIO_pre=$(do_facet ost1 \
9945                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
9946         # Exit if lustre is not running (ll_ost_io not running).
9947         [ -z "$OSTIO_pre" ] && error "no OSS threads"
9948
9949         echo "Starting with $OSTIO_pre threads"
9950         local thread_max=$((OSTIO_pre * 2))
9951         local rpc_in_flight=$((thread_max * 2))
9952         # Number of I/O Process proposed to be started.
9953         local nfiles
9954         local facets=$(get_facets OST)
9955
9956         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
9957         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
9958
9959         # Set in_flight to $rpc_in_flight
9960         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
9961                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
9962         nfiles=${rpc_in_flight}
9963         # Set ost thread_max to $thread_max
9964         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
9965
9966         # 5 Minutes should be sufficient for max number of OSS
9967         # threads(thread_max) to be created.
9968         local timeout=300
9969
9970         # Start I/O.
9971         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
9972         test_mkdir $DIR/$tdir
9973         for i in $(seq $nfiles); do
9974                 local file=$DIR/$tdir/${tfile}-$i
9975                 $LFS setstripe -c -1 -i 0 $file
9976                 ($WTL $file $timeout)&
9977         done
9978
9979         # I/O Started - Wait for thread_started to reach thread_max or report
9980         # error if thread_started is more than thread_max.
9981         echo "Waiting for thread_started to reach thread_max"
9982         local thread_started=0
9983         local end_time=$((SECONDS + timeout))
9984
9985         while [ $SECONDS -le $end_time ] ; do
9986                 echo -n "."
9987                 # Get ost i/o thread_started count.
9988                 thread_started=$(do_facet ost1 \
9989                         "$LCTL get_param \
9990                         ost.OSS.ost_io.threads_started | cut -d= -f2")
9991                 # Break out if thread_started is equal/greater than thread_max
9992                 if [[ $thread_started -ge $thread_max ]]; then
9993                         echo ll_ost_io thread_started $thread_started, \
9994                                 equal/greater than thread_max $thread_max
9995                         break
9996                 fi
9997                 sleep 1
9998         done
9999
10000         # Cleanup - We have the numbers, Kill i/o jobs if running.
10001         jobcount=($(jobs -p))
10002         for i in $(seq 0 $((${#jobcount[@]}-1)))
10003         do
10004                 kill -9 ${jobcount[$i]}
10005                 if [ $? -ne 0 ] ; then
10006                         echo Warning: \
10007                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
10008                 fi
10009         done
10010
10011         # Cleanup files left by WTL binary.
10012         for i in $(seq $nfiles); do
10013                 local file=$DIR/$tdir/${tfile}-$i
10014                 rm -rf $file
10015                 if [ $? -ne 0 ] ; then
10016                         echo "Warning: Failed to delete file $file"
10017                 fi
10018         done
10019
10020         restore_lustre_params <$save_params
10021         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
10022
10023         # Error out if no new thread has started or Thread started is greater
10024         # than thread max.
10025         if [[ $thread_started -le $OSTIO_pre ||
10026                         $thread_started -gt $thread_max ]]; then
10027                 error "ll_ost_io: thread_started $thread_started" \
10028                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
10029                       "No new thread started or thread started greater " \
10030                       "than thread_max."
10031         fi
10032 }
10033 run_test 115 "verify dynamic thread creation===================="
10034
10035 free_min_max () {
10036         wait_delete_completed
10037         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
10038         echo "OST kbytes available: ${AVAIL[@]}"
10039         MAXV=${AVAIL[0]}
10040         MAXI=0
10041         MINV=${AVAIL[0]}
10042         MINI=0
10043         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
10044                 #echo OST $i: ${AVAIL[i]}kb
10045                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
10046                         MAXV=${AVAIL[i]}
10047                         MAXI=$i
10048                 fi
10049                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
10050                         MINV=${AVAIL[i]}
10051                         MINI=$i
10052                 fi
10053         done
10054         echo "Min free space: OST $MINI: $MINV"
10055         echo "Max free space: OST $MAXI: $MAXV"
10056 }
10057
10058 test_116a() { # was previously test_116()
10059         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10060         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10061         remote_mds_nodsh && skip "remote MDS with nodsh"
10062
10063         echo -n "Free space priority "
10064         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
10065                 head -n1
10066         declare -a AVAIL
10067         free_min_max
10068
10069         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
10070         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
10071         trap simple_cleanup_common EXIT
10072
10073         # Check if we need to generate uneven OSTs
10074         test_mkdir -p $DIR/$tdir/OST${MINI}
10075         local FILL=$((MINV / 4))
10076         local DIFF=$((MAXV - MINV))
10077         local DIFF2=$((DIFF * 100 / MINV))
10078
10079         local threshold=$(do_facet $SINGLEMDS \
10080                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
10081         threshold=${threshold%%%}
10082         echo -n "Check for uneven OSTs: "
10083         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
10084
10085         if [[ $DIFF2 -gt $threshold ]]; then
10086                 echo "ok"
10087                 echo "Don't need to fill OST$MINI"
10088         else
10089                 # generate uneven OSTs. Write 2% over the QOS threshold value
10090                 echo "no"
10091                 DIFF=$((threshold - DIFF2 + 2))
10092                 DIFF2=$((MINV * DIFF / 100))
10093                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
10094                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
10095                         error "setstripe failed"
10096                 DIFF=$((DIFF2 / 2048))
10097                 i=0
10098                 while [ $i -lt $DIFF ]; do
10099                         i=$((i + 1))
10100                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
10101                                 bs=2M count=1 2>/dev/null
10102                         echo -n .
10103                 done
10104                 echo .
10105                 sync
10106                 sleep_maxage
10107                 free_min_max
10108         fi
10109
10110         DIFF=$((MAXV - MINV))
10111         DIFF2=$((DIFF * 100 / MINV))
10112         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
10113         if [ $DIFF2 -gt $threshold ]; then
10114                 echo "ok"
10115         else
10116                 echo "failed - QOS mode won't be used"
10117                 simple_cleanup_common
10118                 skip "QOS imbalance criteria not met"
10119         fi
10120
10121         MINI1=$MINI
10122         MINV1=$MINV
10123         MAXI1=$MAXI
10124         MAXV1=$MAXV
10125
10126         # now fill using QOS
10127         $LFS setstripe -c 1 $DIR/$tdir
10128         FILL=$((FILL / 200))
10129         if [ $FILL -gt 600 ]; then
10130                 FILL=600
10131         fi
10132         echo "writing $FILL files to QOS-assigned OSTs"
10133         i=0
10134         while [ $i -lt $FILL ]; do
10135                 i=$((i + 1))
10136                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
10137                         count=1 2>/dev/null
10138                 echo -n .
10139         done
10140         echo "wrote $i 200k files"
10141         sync
10142         sleep_maxage
10143
10144         echo "Note: free space may not be updated, so measurements might be off"
10145         free_min_max
10146         DIFF2=$((MAXV - MINV))
10147         echo "free space delta: orig $DIFF final $DIFF2"
10148         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
10149         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
10150         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
10151         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
10152         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
10153         if [[ $DIFF -gt 0 ]]; then
10154                 FILL=$((DIFF2 * 100 / DIFF - 100))
10155                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
10156         fi
10157
10158         # Figure out which files were written where
10159         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10160                awk '/'$MINI1': / {print $2; exit}')
10161         echo $UUID
10162         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10163         echo "$MINC files created on smaller OST $MINI1"
10164         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10165                awk '/'$MAXI1': / {print $2; exit}')
10166         echo $UUID
10167         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10168         echo "$MAXC files created on larger OST $MAXI1"
10169         if [[ $MINC -gt 0 ]]; then
10170                 FILL=$((MAXC * 100 / MINC - 100))
10171                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
10172         fi
10173         [[ $MAXC -gt $MINC ]] ||
10174                 error_ignore LU-9 "stripe QOS didn't balance free space"
10175         simple_cleanup_common
10176 }
10177 run_test 116a "stripe QOS: free space balance ==================="
10178
10179 test_116b() { # LU-2093
10180         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10181         remote_mds_nodsh && skip "remote MDS with nodsh"
10182
10183 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
10184         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
10185                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
10186         [ -z "$old_rr" ] && skip "no QOS"
10187         do_facet $SINGLEMDS lctl set_param \
10188                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
10189         mkdir -p $DIR/$tdir
10190         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
10191         createmany -o $DIR/$tdir/f- 20 || error "can't create"
10192         do_facet $SINGLEMDS lctl set_param fail_loc=0
10193         rm -rf $DIR/$tdir
10194         do_facet $SINGLEMDS lctl set_param \
10195                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
10196 }
10197 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
10198
10199 test_117() # bug 10891
10200 {
10201         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10202
10203         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
10204         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
10205         lctl set_param fail_loc=0x21e
10206         > $DIR/$tfile || error "truncate failed"
10207         lctl set_param fail_loc=0
10208         echo "Truncate succeeded."
10209         rm -f $DIR/$tfile
10210 }
10211 run_test 117 "verify osd extend =========="
10212
10213 NO_SLOW_RESENDCOUNT=4
10214 export OLD_RESENDCOUNT=""
10215 set_resend_count () {
10216         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
10217         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
10218         lctl set_param -n $PROC_RESENDCOUNT $1
10219         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
10220 }
10221
10222 # for reduce test_118* time (b=14842)
10223 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
10224
10225 # Reset async IO behavior after error case
10226 reset_async() {
10227         FILE=$DIR/reset_async
10228
10229         # Ensure all OSCs are cleared
10230         $LFS setstripe -c -1 $FILE
10231         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
10232         sync
10233         rm $FILE
10234 }
10235
10236 test_118a() #bug 11710
10237 {
10238         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10239
10240         reset_async
10241
10242         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10243         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10244         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10245
10246         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10247                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10248                 return 1;
10249         fi
10250         rm -f $DIR/$tfile
10251 }
10252 run_test 118a "verify O_SYNC works =========="
10253
10254 test_118b()
10255 {
10256         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10257         remote_ost_nodsh && skip "remote OST with nodsh"
10258
10259         reset_async
10260
10261         #define OBD_FAIL_SRV_ENOENT 0x217
10262         set_nodes_failloc "$(osts_nodes)" 0x217
10263         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10264         RC=$?
10265         set_nodes_failloc "$(osts_nodes)" 0
10266         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10267         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10268                     grep -c writeback)
10269
10270         if [[ $RC -eq 0 ]]; then
10271                 error "Must return error due to dropped pages, rc=$RC"
10272                 return 1;
10273         fi
10274
10275         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10276                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10277                 return 1;
10278         fi
10279
10280         echo "Dirty pages not leaked on ENOENT"
10281
10282         # Due to the above error the OSC will issue all RPCs syncronously
10283         # until a subsequent RPC completes successfully without error.
10284         $MULTIOP $DIR/$tfile Ow4096yc
10285         rm -f $DIR/$tfile
10286
10287         return 0
10288 }
10289 run_test 118b "Reclaim dirty pages on fatal error =========="
10290
10291 test_118c()
10292 {
10293         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10294
10295         # for 118c, restore the original resend count, LU-1940
10296         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
10297                                 set_resend_count $OLD_RESENDCOUNT
10298         remote_ost_nodsh && skip "remote OST with nodsh"
10299
10300         reset_async
10301
10302         #define OBD_FAIL_OST_EROFS               0x216
10303         set_nodes_failloc "$(osts_nodes)" 0x216
10304
10305         # multiop should block due to fsync until pages are written
10306         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10307         MULTIPID=$!
10308         sleep 1
10309
10310         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
10311                 error "Multiop failed to block on fsync, pid=$MULTIPID"
10312         fi
10313
10314         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10315                     grep -c writeback)
10316         if [[ $WRITEBACK -eq 0 ]]; then
10317                 error "No page in writeback, writeback=$WRITEBACK"
10318         fi
10319
10320         set_nodes_failloc "$(osts_nodes)" 0
10321         wait $MULTIPID
10322         RC=$?
10323         if [[ $RC -ne 0 ]]; then
10324                 error "Multiop fsync failed, rc=$RC"
10325         fi
10326
10327         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10328         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10329                     grep -c writeback)
10330         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10331                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10332         fi
10333
10334         rm -f $DIR/$tfile
10335         echo "Dirty pages flushed via fsync on EROFS"
10336         return 0
10337 }
10338 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
10339
10340 # continue to use small resend count to reduce test_118* time (b=14842)
10341 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
10342
10343 test_118d()
10344 {
10345         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10346         remote_ost_nodsh && skip "remote OST with nodsh"
10347
10348         reset_async
10349
10350         #define OBD_FAIL_OST_BRW_PAUSE_BULK
10351         set_nodes_failloc "$(osts_nodes)" 0x214
10352         # multiop should block due to fsync until pages are written
10353         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10354         MULTIPID=$!
10355         sleep 1
10356
10357         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
10358                 error "Multiop failed to block on fsync, pid=$MULTIPID"
10359         fi
10360
10361         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10362                     grep -c writeback)
10363         if [[ $WRITEBACK -eq 0 ]]; then
10364                 error "No page in writeback, writeback=$WRITEBACK"
10365         fi
10366
10367         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
10368         set_nodes_failloc "$(osts_nodes)" 0
10369
10370         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10371         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10372                     grep -c writeback)
10373         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10374                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10375         fi
10376
10377         rm -f $DIR/$tfile
10378         echo "Dirty pages gaurenteed flushed via fsync"
10379         return 0
10380 }
10381 run_test 118d "Fsync validation inject a delay of the bulk =========="
10382
10383 test_118f() {
10384         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10385
10386         reset_async
10387
10388         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
10389         lctl set_param fail_loc=0x8000040a
10390
10391         # Should simulate EINVAL error which is fatal
10392         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10393         RC=$?
10394         if [[ $RC -eq 0 ]]; then
10395                 error "Must return error due to dropped pages, rc=$RC"
10396         fi
10397
10398         lctl set_param fail_loc=0x0
10399
10400         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10401         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10402         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10403                     grep -c writeback)
10404         if [[ $LOCKED -ne 0 ]]; then
10405                 error "Locked pages remain in cache, locked=$LOCKED"
10406         fi
10407
10408         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10409                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10410         fi
10411
10412         rm -f $DIR/$tfile
10413         echo "No pages locked after fsync"
10414
10415         reset_async
10416         return 0
10417 }
10418 run_test 118f "Simulate unrecoverable OSC side error =========="
10419
10420 test_118g() {
10421         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10422
10423         reset_async
10424
10425         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
10426         lctl set_param fail_loc=0x406
10427
10428         # simulate local -ENOMEM
10429         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10430         RC=$?
10431
10432         lctl set_param fail_loc=0
10433         if [[ $RC -eq 0 ]]; then
10434                 error "Must return error due to dropped pages, rc=$RC"
10435         fi
10436
10437         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10438         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10439         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10440                         grep -c writeback)
10441         if [[ $LOCKED -ne 0 ]]; then
10442                 error "Locked pages remain in cache, locked=$LOCKED"
10443         fi
10444
10445         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10446                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10447         fi
10448
10449         rm -f $DIR/$tfile
10450         echo "No pages locked after fsync"
10451
10452         reset_async
10453         return 0
10454 }
10455 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
10456
10457 test_118h() {
10458         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10459         remote_ost_nodsh && skip "remote OST with nodsh"
10460
10461         reset_async
10462
10463         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
10464         set_nodes_failloc "$(osts_nodes)" 0x20e
10465         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
10466         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10467         RC=$?
10468
10469         set_nodes_failloc "$(osts_nodes)" 0
10470         if [[ $RC -eq 0 ]]; then
10471                 error "Must return error due to dropped pages, rc=$RC"
10472         fi
10473
10474         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10475         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10476         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10477                     grep -c writeback)
10478         if [[ $LOCKED -ne 0 ]]; then
10479                 error "Locked pages remain in cache, locked=$LOCKED"
10480         fi
10481
10482         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10483                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10484         fi
10485
10486         rm -f $DIR/$tfile
10487         echo "No pages locked after fsync"
10488
10489         return 0
10490 }
10491 run_test 118h "Verify timeout in handling recoverables errors  =========="
10492
10493 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
10494
10495 test_118i() {
10496         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10497         remote_ost_nodsh && skip "remote OST with nodsh"
10498
10499         reset_async
10500
10501         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
10502         set_nodes_failloc "$(osts_nodes)" 0x20e
10503
10504         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
10505         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10506         PID=$!
10507         sleep 5
10508         set_nodes_failloc "$(osts_nodes)" 0
10509
10510         wait $PID
10511         RC=$?
10512         if [[ $RC -ne 0 ]]; then
10513                 error "got error, but should be not, rc=$RC"
10514         fi
10515
10516         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10517         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10518         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10519         if [[ $LOCKED -ne 0 ]]; then
10520                 error "Locked pages remain in cache, locked=$LOCKED"
10521         fi
10522
10523         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10524                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10525         fi
10526
10527         rm -f $DIR/$tfile
10528         echo "No pages locked after fsync"
10529
10530         return 0
10531 }
10532 run_test 118i "Fix error before timeout in recoverable error  =========="
10533
10534 [ "$SLOW" = "no" ] && set_resend_count 4
10535
10536 test_118j() {
10537         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10538         remote_ost_nodsh && skip "remote OST with nodsh"
10539
10540         reset_async
10541
10542         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
10543         set_nodes_failloc "$(osts_nodes)" 0x220
10544
10545         # return -EIO from OST
10546         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10547         RC=$?
10548         set_nodes_failloc "$(osts_nodes)" 0x0
10549         if [[ $RC -eq 0 ]]; then
10550                 error "Must return error due to dropped pages, rc=$RC"
10551         fi
10552
10553         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10554         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10555         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10556         if [[ $LOCKED -ne 0 ]]; then
10557                 error "Locked pages remain in cache, locked=$LOCKED"
10558         fi
10559
10560         # in recoverable error on OST we want resend and stay until it finished
10561         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10562                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10563         fi
10564
10565         rm -f $DIR/$tfile
10566         echo "No pages locked after fsync"
10567
10568         return 0
10569 }
10570 run_test 118j "Simulate unrecoverable OST side error =========="
10571
10572 test_118k()
10573 {
10574         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10575         remote_ost_nodsh && skip "remote OSTs with nodsh"
10576
10577         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
10578         set_nodes_failloc "$(osts_nodes)" 0x20e
10579         test_mkdir $DIR/$tdir
10580
10581         for ((i=0;i<10;i++)); do
10582                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
10583                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
10584                 SLEEPPID=$!
10585                 sleep 0.500s
10586                 kill $SLEEPPID
10587                 wait $SLEEPPID
10588         done
10589
10590         set_nodes_failloc "$(osts_nodes)" 0
10591         rm -rf $DIR/$tdir
10592 }
10593 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
10594
10595 test_118l() # LU-646
10596 {
10597         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10598
10599         test_mkdir $DIR/$tdir
10600         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
10601         rm -rf $DIR/$tdir
10602 }
10603 run_test 118l "fsync dir"
10604
10605 test_118m() # LU-3066
10606 {
10607         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10608
10609         test_mkdir $DIR/$tdir
10610         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
10611         rm -rf $DIR/$tdir
10612 }
10613 run_test 118m "fdatasync dir ========="
10614
10615 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
10616
10617 test_118n()
10618 {
10619         local begin
10620         local end
10621
10622         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10623         remote_ost_nodsh && skip "remote OSTs with nodsh"
10624
10625         # Sleep to avoid a cached response.
10626         #define OBD_STATFS_CACHE_SECONDS 1
10627         sleep 2
10628
10629         # Inject a 10 second delay in the OST_STATFS handler.
10630         #define OBD_FAIL_OST_STATFS_DELAY 0x242
10631         set_nodes_failloc "$(osts_nodes)" 0x242
10632
10633         begin=$SECONDS
10634         stat --file-system $MOUNT > /dev/null
10635         end=$SECONDS
10636
10637         set_nodes_failloc "$(osts_nodes)" 0
10638
10639         if ((end - begin > 20)); then
10640             error "statfs took $((end - begin)) seconds, expected 10"
10641         fi
10642 }
10643 run_test 118n "statfs() sends OST_STATFS requests in parallel"
10644
10645 test_119a() # bug 11737
10646 {
10647         BSIZE=$((512 * 1024))
10648         directio write $DIR/$tfile 0 1 $BSIZE
10649         # We ask to read two blocks, which is more than a file size.
10650         # directio will indicate an error when requested and actual
10651         # sizes aren't equeal (a normal situation in this case) and
10652         # print actual read amount.
10653         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
10654         if [ "$NOB" != "$BSIZE" ]; then
10655                 error "read $NOB bytes instead of $BSIZE"
10656         fi
10657         rm -f $DIR/$tfile
10658 }
10659 run_test 119a "Short directIO read must return actual read amount"
10660
10661 test_119b() # bug 11737
10662 {
10663         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10664
10665         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
10666         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
10667         sync
10668         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
10669                 error "direct read failed"
10670         rm -f $DIR/$tfile
10671 }
10672 run_test 119b "Sparse directIO read must return actual read amount"
10673
10674 test_119c() # bug 13099
10675 {
10676         BSIZE=1048576
10677         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
10678         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
10679         rm -f $DIR/$tfile
10680 }
10681 run_test 119c "Testing for direct read hitting hole"
10682
10683 test_119d() # bug 15950
10684 {
10685         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10686
10687         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
10688         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
10689         BSIZE=1048576
10690         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
10691         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
10692         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
10693         lctl set_param fail_loc=0x40d
10694         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
10695         pid_dio=$!
10696         sleep 1
10697         cat $DIR/$tfile > /dev/null &
10698         lctl set_param fail_loc=0
10699         pid_reads=$!
10700         wait $pid_dio
10701         log "the DIO writes have completed, now wait for the reads (should not block very long)"
10702         sleep 2
10703         [ -n "`ps h -p $pid_reads -o comm`" ] && \
10704         error "the read rpcs have not completed in 2s"
10705         rm -f $DIR/$tfile
10706         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
10707 }
10708 run_test 119d "The DIO path should try to send a new rpc once one is completed"
10709
10710 test_120a() {
10711         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10712         remote_mds_nodsh && skip "remote MDS with nodsh"
10713         test_mkdir -i0 -c1 $DIR/$tdir
10714         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10715                 skip_env "no early lock cancel on server"
10716
10717         lru_resize_disable mdc
10718         lru_resize_disable osc
10719         cancel_lru_locks mdc
10720         # asynchronous object destroy at MDT could cause bl ast to client
10721         cancel_lru_locks osc
10722
10723         stat $DIR/$tdir > /dev/null
10724         can1=$(do_facet mds1 \
10725                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10726                awk '/ldlm_cancel/ {print $2}')
10727         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10728                awk '/ldlm_bl_callback/ {print $2}')
10729         test_mkdir -i0 -c1 $DIR/$tdir/d1
10730         can2=$(do_facet mds1 \
10731                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10732                awk '/ldlm_cancel/ {print $2}')
10733         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10734                awk '/ldlm_bl_callback/ {print $2}')
10735         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10736         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10737         lru_resize_enable mdc
10738         lru_resize_enable osc
10739 }
10740 run_test 120a "Early Lock Cancel: mkdir test"
10741
10742 test_120b() {
10743         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10744         remote_mds_nodsh && skip "remote MDS with nodsh"
10745         test_mkdir $DIR/$tdir
10746         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10747                 skip_env "no early lock cancel on server"
10748
10749         lru_resize_disable mdc
10750         lru_resize_disable osc
10751         cancel_lru_locks mdc
10752         stat $DIR/$tdir > /dev/null
10753         can1=$(do_facet $SINGLEMDS \
10754                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10755                awk '/ldlm_cancel/ {print $2}')
10756         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10757                awk '/ldlm_bl_callback/ {print $2}')
10758         touch $DIR/$tdir/f1
10759         can2=$(do_facet $SINGLEMDS \
10760                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10761                awk '/ldlm_cancel/ {print $2}')
10762         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10763                awk '/ldlm_bl_callback/ {print $2}')
10764         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10765         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10766         lru_resize_enable mdc
10767         lru_resize_enable osc
10768 }
10769 run_test 120b "Early Lock Cancel: create test"
10770
10771 test_120c() {
10772         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10773         remote_mds_nodsh && skip "remote MDS with nodsh"
10774         test_mkdir -i0 -c1 $DIR/$tdir
10775         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10776                 skip "no early lock cancel on server"
10777
10778         lru_resize_disable mdc
10779         lru_resize_disable osc
10780         test_mkdir -i0 -c1 $DIR/$tdir/d1
10781         test_mkdir -i0 -c1 $DIR/$tdir/d2
10782         touch $DIR/$tdir/d1/f1
10783         cancel_lru_locks mdc
10784         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
10785         can1=$(do_facet mds1 \
10786                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10787                awk '/ldlm_cancel/ {print $2}')
10788         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10789                awk '/ldlm_bl_callback/ {print $2}')
10790         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
10791         can2=$(do_facet mds1 \
10792                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10793                awk '/ldlm_cancel/ {print $2}')
10794         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10795                awk '/ldlm_bl_callback/ {print $2}')
10796         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10797         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10798         lru_resize_enable mdc
10799         lru_resize_enable osc
10800 }
10801 run_test 120c "Early Lock Cancel: link test"
10802
10803 test_120d() {
10804         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10805         remote_mds_nodsh && skip "remote MDS with nodsh"
10806         test_mkdir -i0 -c1 $DIR/$tdir
10807         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10808                 skip_env "no early lock cancel on server"
10809
10810         lru_resize_disable mdc
10811         lru_resize_disable osc
10812         touch $DIR/$tdir
10813         cancel_lru_locks mdc
10814         stat $DIR/$tdir > /dev/null
10815         can1=$(do_facet mds1 \
10816                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10817                awk '/ldlm_cancel/ {print $2}')
10818         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10819                awk '/ldlm_bl_callback/ {print $2}')
10820         chmod a+x $DIR/$tdir
10821         can2=$(do_facet mds1 \
10822                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10823                awk '/ldlm_cancel/ {print $2}')
10824         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10825                awk '/ldlm_bl_callback/ {print $2}')
10826         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10827         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10828         lru_resize_enable mdc
10829         lru_resize_enable osc
10830 }
10831 run_test 120d "Early Lock Cancel: setattr test"
10832
10833 test_120e() {
10834         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10835         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10836                 skip_env "no early lock cancel on server"
10837         remote_mds_nodsh && skip "remote MDS with nodsh"
10838
10839         local dlmtrace_set=false
10840
10841         test_mkdir -i0 -c1 $DIR/$tdir
10842         lru_resize_disable mdc
10843         lru_resize_disable osc
10844         ! $LCTL get_param debug | grep -q dlmtrace &&
10845                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
10846         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
10847         cancel_lru_locks mdc
10848         cancel_lru_locks osc
10849         dd if=$DIR/$tdir/f1 of=/dev/null
10850         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
10851         # XXX client can not do early lock cancel of OST lock
10852         # during unlink (LU-4206), so cancel osc lock now.
10853         sleep 2
10854         cancel_lru_locks osc
10855         can1=$(do_facet mds1 \
10856                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10857                awk '/ldlm_cancel/ {print $2}')
10858         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10859                awk '/ldlm_bl_callback/ {print $2}')
10860         unlink $DIR/$tdir/f1
10861         sleep 5
10862         can2=$(do_facet mds1 \
10863                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10864                awk '/ldlm_cancel/ {print $2}')
10865         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10866                awk '/ldlm_bl_callback/ {print $2}')
10867         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
10868                 $LCTL dk $TMP/cancel.debug.txt
10869         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
10870                 $LCTL dk $TMP/blocking.debug.txt
10871         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
10872         lru_resize_enable mdc
10873         lru_resize_enable osc
10874 }
10875 run_test 120e "Early Lock Cancel: unlink test"
10876
10877 test_120f() {
10878         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10879         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10880                 skip_env "no early lock cancel on server"
10881         remote_mds_nodsh && skip "remote MDS with nodsh"
10882
10883         test_mkdir -i0 -c1 $DIR/$tdir
10884         lru_resize_disable mdc
10885         lru_resize_disable osc
10886         test_mkdir -i0 -c1 $DIR/$tdir/d1
10887         test_mkdir -i0 -c1 $DIR/$tdir/d2
10888         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
10889         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
10890         cancel_lru_locks mdc
10891         cancel_lru_locks osc
10892         dd if=$DIR/$tdir/d1/f1 of=/dev/null
10893         dd if=$DIR/$tdir/d2/f2 of=/dev/null
10894         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
10895         # XXX client can not do early lock cancel of OST lock
10896         # during rename (LU-4206), so cancel osc lock now.
10897         sleep 2
10898         cancel_lru_locks osc
10899         can1=$(do_facet mds1 \
10900                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10901                awk '/ldlm_cancel/ {print $2}')
10902         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10903                awk '/ldlm_bl_callback/ {print $2}')
10904         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
10905         sleep 5
10906         can2=$(do_facet mds1 \
10907                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10908                awk '/ldlm_cancel/ {print $2}')
10909         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10910                awk '/ldlm_bl_callback/ {print $2}')
10911         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10912         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10913         lru_resize_enable mdc
10914         lru_resize_enable osc
10915 }
10916 run_test 120f "Early Lock Cancel: rename test"
10917
10918 test_120g() {
10919         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10920         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10921                 skip_env "no early lock cancel on server"
10922         remote_mds_nodsh && skip "remote MDS with nodsh"
10923
10924         lru_resize_disable mdc
10925         lru_resize_disable osc
10926         count=10000
10927         echo create $count files
10928         test_mkdir $DIR/$tdir
10929         cancel_lru_locks mdc
10930         cancel_lru_locks osc
10931         t0=$(date +%s)
10932
10933         can0=$(do_facet $SINGLEMDS \
10934                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10935                awk '/ldlm_cancel/ {print $2}')
10936         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10937                awk '/ldlm_bl_callback/ {print $2}')
10938         createmany -o $DIR/$tdir/f $count
10939         sync
10940         can1=$(do_facet $SINGLEMDS \
10941                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10942                awk '/ldlm_cancel/ {print $2}')
10943         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10944                awk '/ldlm_bl_callback/ {print $2}')
10945         t1=$(date +%s)
10946         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
10947         echo rm $count files
10948         rm -r $DIR/$tdir
10949         sync
10950         can2=$(do_facet $SINGLEMDS \
10951                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10952                awk '/ldlm_cancel/ {print $2}')
10953         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10954                awk '/ldlm_bl_callback/ {print $2}')
10955         t2=$(date +%s)
10956         echo total: $count removes in $((t2-t1))
10957         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
10958         sleep 2
10959         # wait for commitment of removal
10960         lru_resize_enable mdc
10961         lru_resize_enable osc
10962 }
10963 run_test 120g "Early Lock Cancel: performance test"
10964
10965 test_121() { #bug #10589
10966         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10967
10968         rm -rf $DIR/$tfile
10969         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
10970 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
10971         lctl set_param fail_loc=0x310
10972         cancel_lru_locks osc > /dev/null
10973         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
10974         lctl set_param fail_loc=0
10975         [[ $reads -eq $writes ]] ||
10976                 error "read $reads blocks, must be $writes blocks"
10977 }
10978 run_test 121 "read cancel race ========="
10979
10980 test_123a() { # was test 123, statahead(bug 11401)
10981         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10982
10983         SLOWOK=0
10984         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
10985                 log "testing UP system. Performance may be lower than expected."
10986                 SLOWOK=1
10987         fi
10988
10989         rm -rf $DIR/$tdir
10990         test_mkdir $DIR/$tdir
10991         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
10992         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
10993         MULT=10
10994         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
10995                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
10996
10997                 max=`lctl get_param -n llite.*.statahead_max | head -n 1`
10998                 lctl set_param -n llite.*.statahead_max 0
10999                 lctl get_param llite.*.statahead_max
11000                 cancel_lru_locks mdc
11001                 cancel_lru_locks osc
11002                 stime=`date +%s`
11003                 time ls -l $DIR/$tdir | wc -l
11004                 etime=`date +%s`
11005                 delta=$((etime - stime))
11006                 log "ls $i files without statahead: $delta sec"
11007                 lctl set_param llite.*.statahead_max=$max
11008
11009                 swrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
11010                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
11011                 cancel_lru_locks mdc
11012                 cancel_lru_locks osc
11013                 stime=`date +%s`
11014                 time ls -l $DIR/$tdir | wc -l
11015                 etime=`date +%s`
11016                 delta_sa=$((etime - stime))
11017                 log "ls $i files with statahead: $delta_sa sec"
11018                 lctl get_param -n llite.*.statahead_stats
11019                 ewrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
11020
11021                 [[ $swrong -lt $ewrong ]] &&
11022                         log "statahead was stopped, maybe too many locks held!"
11023                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
11024
11025                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
11026                     max=`lctl get_param -n llite.*.statahead_max | head -n 1`
11027                     lctl set_param -n llite.*.statahead_max 0
11028                     lctl get_param llite.*.statahead_max
11029                     cancel_lru_locks mdc
11030                     cancel_lru_locks osc
11031                     stime=`date +%s`
11032                     time ls -l $DIR/$tdir | wc -l
11033                     etime=`date +%s`
11034                     delta=$((etime - stime))
11035                     log "ls $i files again without statahead: $delta sec"
11036                     lctl set_param llite.*.statahead_max=$max
11037                     if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
11038                         if [  $SLOWOK -eq 0 ]; then
11039                                 error "ls $i files is slower with statahead!"
11040                         else
11041                                 log "ls $i files is slower with statahead!"
11042                         fi
11043                         break
11044                     fi
11045                 fi
11046
11047                 [ $delta -gt 20 ] && break
11048                 [ $delta -gt 8 ] && MULT=$((50 / delta))
11049                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
11050         done
11051         log "ls done"
11052
11053         stime=`date +%s`
11054         rm -r $DIR/$tdir
11055         sync
11056         etime=`date +%s`
11057         delta=$((etime - stime))
11058         log "rm -r $DIR/$tdir/: $delta seconds"
11059         log "rm done"
11060         lctl get_param -n llite.*.statahead_stats
11061 }
11062 run_test 123a "verify statahead work"
11063
11064 test_123b () { # statahead(bug 15027)
11065         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11066
11067         test_mkdir $DIR/$tdir
11068         createmany -o $DIR/$tdir/$tfile-%d 1000
11069
11070         cancel_lru_locks mdc
11071         cancel_lru_locks osc
11072
11073 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
11074         lctl set_param fail_loc=0x80000803
11075         ls -lR $DIR/$tdir > /dev/null
11076         log "ls done"
11077         lctl set_param fail_loc=0x0
11078         lctl get_param -n llite.*.statahead_stats
11079         rm -r $DIR/$tdir
11080         sync
11081
11082 }
11083 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
11084
11085 test_124a() {
11086         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11087         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11088                 skip_env "no lru resize on server"
11089
11090         local NR=2000
11091
11092         test_mkdir $DIR/$tdir
11093
11094         log "create $NR files at $DIR/$tdir"
11095         createmany -o $DIR/$tdir/f $NR ||
11096                 error "failed to create $NR files in $DIR/$tdir"
11097
11098         cancel_lru_locks mdc
11099         ls -l $DIR/$tdir > /dev/null
11100
11101         local NSDIR=""
11102         local LRU_SIZE=0
11103         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
11104                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
11105                 LRU_SIZE=$($LCTL get_param -n $PARAM)
11106                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
11107                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
11108                         log "NSDIR=$NSDIR"
11109                         log "NS=$(basename $NSDIR)"
11110                         break
11111                 fi
11112         done
11113
11114         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
11115                 skip "Not enough cached locks created!"
11116         fi
11117         log "LRU=$LRU_SIZE"
11118
11119         local SLEEP=30
11120
11121         # We know that lru resize allows one client to hold $LIMIT locks
11122         # for 10h. After that locks begin to be killed by client.
11123         local MAX_HRS=10
11124         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
11125         log "LIMIT=$LIMIT"
11126         if [ $LIMIT -lt $LRU_SIZE ]; then
11127                 skip "Limit is too small $LIMIT"
11128         fi
11129
11130         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
11131         # killing locks. Some time was spent for creating locks. This means
11132         # that up to the moment of sleep finish we must have killed some of
11133         # them (10-100 locks). This depends on how fast ther were created.
11134         # Many of them were touched in almost the same moment and thus will
11135         # be killed in groups.
11136         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE))
11137
11138         # Use $LRU_SIZE_B here to take into account real number of locks
11139         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
11140         local LRU_SIZE_B=$LRU_SIZE
11141         log "LVF=$LVF"
11142         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
11143         log "OLD_LVF=$OLD_LVF"
11144         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
11145
11146         # Let's make sure that we really have some margin. Client checks
11147         # cached locks every 10 sec.
11148         SLEEP=$((SLEEP+20))
11149         log "Sleep ${SLEEP} sec"
11150         local SEC=0
11151         while ((SEC<$SLEEP)); do
11152                 echo -n "..."
11153                 sleep 5
11154                 SEC=$((SEC+5))
11155                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
11156                 echo -n "$LRU_SIZE"
11157         done
11158         echo ""
11159         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
11160         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
11161
11162         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
11163                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
11164                 unlinkmany $DIR/$tdir/f $NR
11165                 return
11166         }
11167
11168         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
11169         log "unlink $NR files at $DIR/$tdir"
11170         unlinkmany $DIR/$tdir/f $NR
11171 }
11172 run_test 124a "lru resize ======================================="
11173
11174 get_max_pool_limit()
11175 {
11176         local limit=$($LCTL get_param \
11177                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
11178         local max=0
11179         for l in $limit; do
11180                 if [[ $l -gt $max ]]; then
11181                         max=$l
11182                 fi
11183         done
11184         echo $max
11185 }
11186
11187 test_124b() {
11188         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11189         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11190                 skip_env "no lru resize on server"
11191
11192         LIMIT=$(get_max_pool_limit)
11193
11194         NR=$(($(default_lru_size)*20))
11195         if [[ $NR -gt $LIMIT ]]; then
11196                 log "Limit lock number by $LIMIT locks"
11197                 NR=$LIMIT
11198         fi
11199
11200         IFree=$(mdsrate_inodes_available)
11201         if [ $IFree -lt $NR ]; then
11202                 log "Limit lock number by $IFree inodes"
11203                 NR=$IFree
11204         fi
11205
11206         lru_resize_disable mdc
11207         test_mkdir -p $DIR/$tdir/disable_lru_resize
11208
11209         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
11210         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
11211         cancel_lru_locks mdc
11212         stime=`date +%s`
11213         PID=""
11214         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11215         PID="$PID $!"
11216         sleep 2
11217         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11218         PID="$PID $!"
11219         sleep 2
11220         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11221         PID="$PID $!"
11222         wait $PID
11223         etime=`date +%s`
11224         nolruresize_delta=$((etime-stime))
11225         log "ls -la time: $nolruresize_delta seconds"
11226         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
11227         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
11228
11229         lru_resize_enable mdc
11230         test_mkdir -p $DIR/$tdir/enable_lru_resize
11231
11232         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
11233         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
11234         cancel_lru_locks mdc
11235         stime=`date +%s`
11236         PID=""
11237         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11238         PID="$PID $!"
11239         sleep 2
11240         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11241         PID="$PID $!"
11242         sleep 2
11243         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11244         PID="$PID $!"
11245         wait $PID
11246         etime=`date +%s`
11247         lruresize_delta=$((etime-stime))
11248         log "ls -la time: $lruresize_delta seconds"
11249         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
11250
11251         if [ $lruresize_delta -gt $nolruresize_delta ]; then
11252                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
11253         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
11254                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
11255         else
11256                 log "lru resize performs the same with no lru resize"
11257         fi
11258         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
11259 }
11260 run_test 124b "lru resize (performance test) ======================="
11261
11262 test_124c() {
11263         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11264         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11265                 skip_env "no lru resize on server"
11266
11267         # cache ununsed locks on client
11268         local nr=100
11269         cancel_lru_locks mdc
11270         test_mkdir $DIR/$tdir
11271         createmany -o $DIR/$tdir/f $nr ||
11272                 error "failed to create $nr files in $DIR/$tdir"
11273         ls -l $DIR/$tdir > /dev/null
11274
11275         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
11276         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11277         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
11278         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
11279         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
11280
11281         # set lru_max_age to 1 sec
11282         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
11283         echo "sleep $((recalc_p * 2)) seconds..."
11284         sleep $((recalc_p * 2))
11285
11286         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
11287         # restore lru_max_age
11288         $LCTL set_param -n $nsdir.lru_max_age $max_age
11289         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
11290         unlinkmany $DIR/$tdir/f $nr
11291 }
11292 run_test 124c "LRUR cancel very aged locks"
11293
11294 test_124d() {
11295         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11296         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11297                 skip_env "no lru resize on server"
11298
11299         # cache ununsed locks on client
11300         local nr=100
11301
11302         lru_resize_disable mdc
11303         stack_trap "lru_resize_enable mdc" EXIT
11304
11305         cancel_lru_locks mdc
11306
11307         # asynchronous object destroy at MDT could cause bl ast to client
11308         test_mkdir $DIR/$tdir
11309         createmany -o $DIR/$tdir/f $nr ||
11310                 error "failed to create $nr files in $DIR/$tdir"
11311         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
11312
11313         ls -l $DIR/$tdir > /dev/null
11314
11315         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
11316         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11317         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
11318         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
11319
11320         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
11321
11322         # set lru_max_age to 1 sec
11323         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
11324         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
11325
11326         echo "sleep $((recalc_p * 2)) seconds..."
11327         sleep $((recalc_p * 2))
11328
11329         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
11330
11331         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
11332 }
11333 run_test 124d "cancel very aged locks if lru-resize diasbaled"
11334
11335 test_125() { # 13358
11336         $LCTL get_param -n llite.*.client_type | grep -q local ||
11337                 skip "must run as local client"
11338         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
11339                 skip_env "must have acl enabled"
11340         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
11341
11342         test_mkdir $DIR/$tdir
11343         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
11344         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
11345         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
11346 }
11347 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
11348
11349 test_126() { # bug 12829/13455
11350         $GSS && skip_env "must run as gss disabled"
11351         $LCTL get_param -n llite.*.client_type | grep -q local ||
11352                 skip "must run as local client"
11353         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
11354
11355         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
11356         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
11357         rm -f $DIR/$tfile
11358         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
11359 }
11360 run_test 126 "check that the fsgid provided by the client is taken into account"
11361
11362 test_127a() { # bug 15521
11363         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11364         local name count samp unit min max sum sumsq
11365
11366         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
11367         echo "stats before reset"
11368         $LCTL get_param osc.*.stats
11369         $LCTL set_param osc.*.stats=0
11370         local fsize=$((2048 * 1024))
11371
11372         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
11373         cancel_lru_locks osc
11374         dd if=$DIR/$tfile of=/dev/null bs=$fsize
11375
11376         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
11377         stack_trap "rm -f $TMP/$tfile.tmp"
11378         while read name count samp unit min max sum sumsq; do
11379                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
11380                 [ ! $min ] && error "Missing min value for $name proc entry"
11381                 eval $name=$count || error "Wrong proc format"
11382
11383                 case $name in
11384                 read_bytes|write_bytes)
11385                         [[ "$unit" =~ "bytes" ]] ||
11386                                 error "unit is not 'bytes': $unit"
11387                         (( $min >= 4096 )) || error "min is too small: $min"
11388                         (( $min <= $fsize )) || error "min is too big: $min"
11389                         (( $max >= 4096 )) || error "max is too small: $max"
11390                         (( $max <= $fsize )) || error "max is too big: $max"
11391                         (( $sum == $fsize )) || error "sum is wrong: $sum"
11392                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
11393                                 error "sumsquare is too small: $sumsq"
11394                         (( $sumsq <= $fsize * $fsize )) ||
11395                                 error "sumsquare is too big: $sumsq"
11396                         ;;
11397                 ost_read|ost_write)
11398                         [[ "$unit" =~ "usec" ]] ||
11399                                 error "unit is not 'usec': $unit"
11400                         ;;
11401                 *)      ;;
11402                 esac
11403         done < $DIR/$tfile.tmp
11404
11405         #check that we actually got some stats
11406         [ "$read_bytes" ] || error "Missing read_bytes stats"
11407         [ "$write_bytes" ] || error "Missing write_bytes stats"
11408         [ "$read_bytes" != 0 ] || error "no read done"
11409         [ "$write_bytes" != 0 ] || error "no write done"
11410 }
11411 run_test 127a "verify the client stats are sane"
11412
11413 test_127b() { # bug LU-333
11414         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11415         local name count samp unit min max sum sumsq
11416
11417         echo "stats before reset"
11418         $LCTL get_param llite.*.stats
11419         $LCTL set_param llite.*.stats=0
11420
11421         # perform 2 reads and writes so MAX is different from SUM.
11422         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
11423         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
11424         cancel_lru_locks osc
11425         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
11426         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
11427
11428         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
11429         stack_trap "rm -f $TMP/$tfile.tmp"
11430         while read name count samp unit min max sum sumsq; do
11431                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
11432                 eval $name=$count || error "Wrong proc format"
11433
11434                 case $name in
11435                 read_bytes|write_bytes)
11436                         [[ "$unit" =~ "bytes" ]] ||
11437                                 error "unit is not 'bytes': $unit"
11438                         (( $count == 2 )) || error "count is not 2: $count"
11439                         (( $min == $PAGE_SIZE )) ||
11440                                 error "min is not $PAGE_SIZE: $min"
11441                         (( $max == $PAGE_SIZE )) ||
11442                                 error "max is not $PAGE_SIZE: $max"
11443                         (( $sum == $PAGE_SIZE * 2 )) ||
11444                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
11445                         ;;
11446                 read|write)
11447                         [[ "$unit" =~ "usec" ]] ||
11448                                 error "unit is not 'usec': $unit"
11449                         ;;
11450                 *)      ;;
11451                 esac
11452         done < $TMP/$tfile.tmp
11453
11454         #check that we actually got some stats
11455         [ "$read_bytes" ] || error "Missing read_bytes stats"
11456         [ "$write_bytes" ] || error "Missing write_bytes stats"
11457         [ "$read_bytes" != 0 ] || error "no read done"
11458         [ "$write_bytes" != 0 ] || error "no write done"
11459 }
11460 run_test 127b "verify the llite client stats are sane"
11461
11462 test_127c() { # LU-12394
11463         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
11464         local size
11465         local bsize
11466         local reads
11467         local writes
11468         local count
11469
11470         $LCTL set_param llite.*.extents_stats=1
11471         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
11472
11473         # Use two stripes so there is enough space in default config
11474         $LFS setstripe -c 2 $DIR/$tfile
11475
11476         # Extent stats start at 0-4K and go in power of two buckets
11477         # LL_HIST_START = 12 --> 2^12 = 4K
11478         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
11479         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
11480         # small configs
11481         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
11482                 do
11483                 # Write and read, 2x each, second time at a non-zero offset
11484                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
11485                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
11486                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
11487                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
11488                 rm -f $DIR/$tfile
11489         done
11490
11491         $LCTL get_param llite.*.extents_stats
11492
11493         count=2
11494         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
11495                 do
11496                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
11497                                 grep -m 1 $bsize)
11498                 reads=$(echo $bucket | awk '{print $5}')
11499                 writes=$(echo $bucket | awk '{print $9}')
11500                 [ "$reads" -eq $count ] ||
11501                         error "$reads reads in < $bsize bucket, expect $count"
11502                 [ "$writes" -eq $count ] ||
11503                         error "$writes writes in < $bsize bucket, expect $count"
11504         done
11505
11506         # Test mmap write and read
11507         $LCTL set_param llite.*.extents_stats=c
11508         size=512
11509         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
11510         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
11511         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
11512
11513         $LCTL get_param llite.*.extents_stats
11514
11515         count=$(((size*1024) / PAGE_SIZE))
11516
11517         bsize=$((2 * PAGE_SIZE / 1024))K
11518
11519         bucket=$($LCTL get_param -n llite.*.extents_stats |
11520                         grep -m 1 $bsize)
11521         reads=$(echo $bucket | awk '{print $5}')
11522         writes=$(echo $bucket | awk '{print $9}')
11523         # mmap writes fault in the page first, creating an additonal read
11524         [ "$reads" -eq $((2 * count)) ] ||
11525                 error "$reads reads in < $bsize bucket, expect $count"
11526         [ "$writes" -eq $count ] ||
11527                 error "$writes writes in < $bsize bucket, expect $count"
11528 }
11529 run_test 127c "test llite extent stats with regular & mmap i/o"
11530
11531 test_128() { # bug 15212
11532         touch $DIR/$tfile
11533         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
11534                 find $DIR/$tfile
11535                 find $DIR/$tfile
11536         EOF
11537
11538         result=$(grep error $TMP/$tfile.log)
11539         rm -f $DIR/$tfile $TMP/$tfile.log
11540         [ -z "$result" ] ||
11541                 error "consecutive find's under interactive lfs failed"
11542 }
11543 run_test 128 "interactive lfs for 2 consecutive find's"
11544
11545 set_dir_limits () {
11546         local mntdev
11547         local canondev
11548         local node
11549
11550         local ldproc=/proc/fs/ldiskfs
11551         local facets=$(get_facets MDS)
11552
11553         for facet in ${facets//,/ }; do
11554                 canondev=$(ldiskfs_canon \
11555                            *.$(convert_facet2label $facet).mntdev $facet)
11556                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
11557                         ldproc=/sys/fs/ldiskfs
11558                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
11559                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
11560         done
11561 }
11562
11563 check_mds_dmesg() {
11564         local facets=$(get_facets MDS)
11565         for facet in ${facets//,/ }; do
11566                 do_facet $facet "dmesg | tail -3 | grep -q $1" && return 0
11567         done
11568         return 1
11569 }
11570
11571 test_129() {
11572         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11573         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
11574                 skip "Need MDS version with at least 2.5.56"
11575         if [ "$mds1_FSTYPE" != ldiskfs ]; then
11576                 skip_env "ldiskfs only test"
11577         fi
11578         remote_mds_nodsh && skip "remote MDS with nodsh"
11579
11580         local ENOSPC=28
11581         local EFBIG=27
11582         local has_warning=false
11583
11584         rm -rf $DIR/$tdir
11585         mkdir -p $DIR/$tdir
11586
11587         # block size of mds1
11588         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 5))
11589         set_dir_limits $maxsize $maxsize
11590         local dirsize=$(stat -c%s "$DIR/$tdir")
11591         local nfiles=0
11592         while [[ $dirsize -le $maxsize ]]; do
11593                 $MULTIOP $DIR/$tdir/file_base_$nfiles Oc
11594                 rc=$?
11595                 if ! $has_warning; then
11596                         check_mds_dmesg '"is approaching"' && has_warning=true
11597                 fi
11598                 # check two errors:
11599                 # ENOSPC for new ext4 max_dir_size (kernel commit df981d03ee)
11600                 # EFBIG for previous versions included in ldiskfs series
11601                 if [ $rc -eq $EFBIG ] || [ $rc -eq $ENOSPC ]; then
11602                         set_dir_limits 0 0
11603                         echo "return code $rc received as expected"
11604
11605                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
11606                                 error_exit "create failed w/o dir size limit"
11607
11608                         check_mds_dmesg '"has reached"' ||
11609                                 error_exit "reached message should be output"
11610
11611                         [ $has_warning = "false" ] &&
11612                                 error_exit "warning message should be output"
11613
11614                         dirsize=$(stat -c%s "$DIR/$tdir")
11615
11616                         [[ $dirsize -ge $maxsize ]] && return 0
11617                         error_exit "current dir size $dirsize, " \
11618                                    "previous limit $maxsize"
11619                 elif [ $rc -ne 0 ]; then
11620                         set_dir_limits 0 0
11621                         error_exit "return $rc received instead of expected " \
11622                                    "$EFBIG or $ENOSPC, files in dir $dirsize"
11623                 fi
11624                 nfiles=$((nfiles + 1))
11625                 dirsize=$(stat -c%s "$DIR/$tdir")
11626         done
11627
11628         set_dir_limits 0 0
11629         error "exceeded dir size limit $maxsize($MDSCOUNT) : $dirsize bytes"
11630 }
11631 run_test 129 "test directory size limit ========================"
11632
11633 OLDIFS="$IFS"
11634 cleanup_130() {
11635         trap 0
11636         IFS="$OLDIFS"
11637 }
11638
11639 test_130a() {
11640         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11641         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
11642
11643         trap cleanup_130 EXIT RETURN
11644
11645         local fm_file=$DIR/$tfile
11646         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
11647         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
11648                 error "dd failed for $fm_file"
11649
11650         # LU-1795: test filefrag/FIEMAP once, even if unsupported
11651         filefrag -ves $fm_file
11652         RC=$?
11653         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11654                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11655         [ $RC != 0 ] && error "filefrag $fm_file failed"
11656
11657         filefrag_op=$(filefrag -ve -k $fm_file |
11658                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11659         lun=$($LFS getstripe -i $fm_file)
11660
11661         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
11662         IFS=$'\n'
11663         tot_len=0
11664         for line in $filefrag_op
11665         do
11666                 frag_lun=`echo $line | cut -d: -f5`
11667                 ext_len=`echo $line | cut -d: -f4`
11668                 if (( $frag_lun != $lun )); then
11669                         cleanup_130
11670                         error "FIEMAP on 1-stripe file($fm_file) failed"
11671                         return
11672                 fi
11673                 (( tot_len += ext_len ))
11674         done
11675
11676         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
11677                 cleanup_130
11678                 error "FIEMAP on 1-stripe file($fm_file) failed;"
11679                 return
11680         fi
11681
11682         cleanup_130
11683
11684         echo "FIEMAP on single striped file succeeded"
11685 }
11686 run_test 130a "FIEMAP (1-stripe file)"
11687
11688 test_130b() {
11689         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
11690
11691         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11692         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
11693
11694         trap cleanup_130 EXIT RETURN
11695
11696         local fm_file=$DIR/$tfile
11697         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
11698                         error "setstripe on $fm_file"
11699         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11700                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11701
11702         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
11703                 error "dd failed on $fm_file"
11704
11705         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11706         filefrag_op=$(filefrag -ve -k $fm_file |
11707                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11708
11709         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11710                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11711
11712         IFS=$'\n'
11713         tot_len=0
11714         num_luns=1
11715         for line in $filefrag_op
11716         do
11717                 frag_lun=$(echo $line | cut -d: -f5 |
11718                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11719                 ext_len=$(echo $line | cut -d: -f4)
11720                 if (( $frag_lun != $last_lun )); then
11721                         if (( tot_len != 1024 )); then
11722                                 cleanup_130
11723                                 error "FIEMAP on $fm_file failed; returned " \
11724                                 "len $tot_len for OST $last_lun instead of 1024"
11725                                 return
11726                         else
11727                                 (( num_luns += 1 ))
11728                                 tot_len=0
11729                         fi
11730                 fi
11731                 (( tot_len += ext_len ))
11732                 last_lun=$frag_lun
11733         done
11734         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
11735                 cleanup_130
11736                 error "FIEMAP on $fm_file failed; returned wrong number of " \
11737                         "luns or wrong len for OST $last_lun"
11738                 return
11739         fi
11740
11741         cleanup_130
11742
11743         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
11744 }
11745 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
11746
11747 test_130c() {
11748         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11749
11750         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11751         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
11752
11753         trap cleanup_130 EXIT RETURN
11754
11755         local fm_file=$DIR/$tfile
11756         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
11757         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11758                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11759
11760         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
11761                         error "dd failed on $fm_file"
11762
11763         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11764         filefrag_op=$(filefrag -ve -k $fm_file |
11765                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11766
11767         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11768                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11769
11770         IFS=$'\n'
11771         tot_len=0
11772         num_luns=1
11773         for line in $filefrag_op
11774         do
11775                 frag_lun=$(echo $line | cut -d: -f5 |
11776                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11777                 ext_len=$(echo $line | cut -d: -f4)
11778                 if (( $frag_lun != $last_lun )); then
11779                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
11780                         if (( logical != 512 )); then
11781                                 cleanup_130
11782                                 error "FIEMAP on $fm_file failed; returned " \
11783                                 "logical start for lun $logical instead of 512"
11784                                 return
11785                         fi
11786                         if (( tot_len != 512 )); then
11787                                 cleanup_130
11788                                 error "FIEMAP on $fm_file failed; returned " \
11789                                 "len $tot_len for OST $last_lun instead of 1024"
11790                                 return
11791                         else
11792                                 (( num_luns += 1 ))
11793                                 tot_len=0
11794                         fi
11795                 fi
11796                 (( tot_len += ext_len ))
11797                 last_lun=$frag_lun
11798         done
11799         if (( num_luns != 2 || tot_len != 512 )); then
11800                 cleanup_130
11801                 error "FIEMAP on $fm_file failed; returned wrong number of " \
11802                         "luns or wrong len for OST $last_lun"
11803                 return
11804         fi
11805
11806         cleanup_130
11807
11808         echo "FIEMAP on 2-stripe file with hole succeeded"
11809 }
11810 run_test 130c "FIEMAP (2-stripe file with hole)"
11811
11812 test_130d() {
11813         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
11814
11815         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11816         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
11817
11818         trap cleanup_130 EXIT RETURN
11819
11820         local fm_file=$DIR/$tfile
11821         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
11822                         error "setstripe on $fm_file"
11823         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11824                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11825
11826         local actual_stripe_count=$($LFS getstripe -c $fm_file)
11827         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
11828                 error "dd failed on $fm_file"
11829
11830         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11831         filefrag_op=$(filefrag -ve -k $fm_file |
11832                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11833
11834         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11835                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11836
11837         IFS=$'\n'
11838         tot_len=0
11839         num_luns=1
11840         for line in $filefrag_op
11841         do
11842                 frag_lun=$(echo $line | cut -d: -f5 |
11843                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11844                 ext_len=$(echo $line | cut -d: -f4)
11845                 if (( $frag_lun != $last_lun )); then
11846                         if (( tot_len != 1024 )); then
11847                                 cleanup_130
11848                                 error "FIEMAP on $fm_file failed; returned " \
11849                                 "len $tot_len for OST $last_lun instead of 1024"
11850                                 return
11851                         else
11852                                 (( num_luns += 1 ))
11853                                 tot_len=0
11854                         fi
11855                 fi
11856                 (( tot_len += ext_len ))
11857                 last_lun=$frag_lun
11858         done
11859         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
11860                 cleanup_130
11861                 error "FIEMAP on $fm_file failed; returned wrong number of " \
11862                         "luns or wrong len for OST $last_lun"
11863                 return
11864         fi
11865
11866         cleanup_130
11867
11868         echo "FIEMAP on N-stripe file succeeded"
11869 }
11870 run_test 130d "FIEMAP (N-stripe file)"
11871
11872 test_130e() {
11873         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11874
11875         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11876         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
11877
11878         trap cleanup_130 EXIT RETURN
11879
11880         local fm_file=$DIR/$tfile
11881         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
11882         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11883                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11884
11885         NUM_BLKS=512
11886         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
11887         for ((i = 0; i < $NUM_BLKS; i++))
11888         do
11889                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) conv=notrunc > /dev/null 2>&1
11890         done
11891
11892         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11893         filefrag_op=$(filefrag -ve -k $fm_file |
11894                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11895
11896         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11897                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11898
11899         IFS=$'\n'
11900         tot_len=0
11901         num_luns=1
11902         for line in $filefrag_op
11903         do
11904                 frag_lun=$(echo $line | cut -d: -f5 |
11905                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11906                 ext_len=$(echo $line | cut -d: -f4)
11907                 if (( $frag_lun != $last_lun )); then
11908                         if (( tot_len != $EXPECTED_LEN )); then
11909                                 cleanup_130
11910                                 error "FIEMAP on $fm_file failed; returned " \
11911                                 "len $tot_len for OST $last_lun instead " \
11912                                 "of $EXPECTED_LEN"
11913                                 return
11914                         else
11915                                 (( num_luns += 1 ))
11916                                 tot_len=0
11917                         fi
11918                 fi
11919                 (( tot_len += ext_len ))
11920                 last_lun=$frag_lun
11921         done
11922         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
11923                 cleanup_130
11924                 error "FIEMAP on $fm_file failed; returned wrong number " \
11925                         "of luns or wrong len for OST $last_lun"
11926                 return
11927         fi
11928
11929         cleanup_130
11930
11931         echo "FIEMAP with continuation calls succeeded"
11932 }
11933 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
11934
11935 test_130f() {
11936         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11937         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
11938
11939         local fm_file=$DIR/$tfile
11940         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
11941                 error "multiop create with lov_delay_create on $fm_file"
11942
11943         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11944         filefrag_extents=$(filefrag -vek $fm_file |
11945                            awk '/extents? found/ { print $2 }')
11946         if [[ "$filefrag_extents" != "0" ]]; then
11947                 error "FIEMAP on $fm_file failed; " \
11948                       "returned $filefrag_extents expected 0"
11949         fi
11950
11951         rm -f $fm_file
11952 }
11953 run_test 130f "FIEMAP (unstriped file)"
11954
11955 # Test for writev/readv
11956 test_131a() {
11957         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
11958                 error "writev test failed"
11959         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
11960                 error "readv failed"
11961         rm -f $DIR/$tfile
11962 }
11963 run_test 131a "test iov's crossing stripe boundary for writev/readv"
11964
11965 test_131b() {
11966         local fsize=$((524288 + 1048576 + 1572864))
11967         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
11968                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
11969                         error "append writev test failed"
11970
11971         ((fsize += 1572864 + 1048576))
11972         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
11973                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
11974                         error "append writev test failed"
11975         rm -f $DIR/$tfile
11976 }
11977 run_test 131b "test append writev"
11978
11979 test_131c() {
11980         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
11981         error "NOT PASS"
11982 }
11983 run_test 131c "test read/write on file w/o objects"
11984
11985 test_131d() {
11986         rwv -f $DIR/$tfile -w -n 1 1572864
11987         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
11988         if [ "$NOB" != 1572864 ]; then
11989                 error "Short read filed: read $NOB bytes instead of 1572864"
11990         fi
11991         rm -f $DIR/$tfile
11992 }
11993 run_test 131d "test short read"
11994
11995 test_131e() {
11996         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
11997         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
11998         error "read hitting hole failed"
11999         rm -f $DIR/$tfile
12000 }
12001 run_test 131e "test read hitting hole"
12002
12003 check_stats() {
12004         local facet=$1
12005         local op=$2
12006         local want=${3:-0}
12007         local res
12008
12009         case $facet in
12010         mds*) res=$(do_facet $facet \
12011                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
12012                  ;;
12013         ost*) res=$(do_facet $facet \
12014                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
12015                  ;;
12016         *) error "Wrong facet '$facet'" ;;
12017         esac
12018         [ "$res" ] || error "The counter for $op on $facet was not incremented"
12019         # if the argument $3 is zero, it means any stat increment is ok.
12020         if [[ $want -gt 0 ]]; then
12021                 local count=$(echo $res | awk '{ print $2 }')
12022                 [[ $count -ne $want ]] &&
12023                         error "The $op counter on $facet is $count, not $want"
12024         fi
12025 }
12026
12027 test_133a() {
12028         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12029         remote_ost_nodsh && skip "remote OST with nodsh"
12030         remote_mds_nodsh && skip "remote MDS with nodsh"
12031         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
12032                 skip_env "MDS doesn't support rename stats"
12033
12034         local testdir=$DIR/${tdir}/stats_testdir
12035
12036         mkdir -p $DIR/${tdir}
12037
12038         # clear stats.
12039         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12040         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12041
12042         # verify mdt stats first.
12043         mkdir ${testdir} || error "mkdir failed"
12044         check_stats $SINGLEMDS "mkdir" 1
12045         touch ${testdir}/${tfile} || error "touch failed"
12046         check_stats $SINGLEMDS "open" 1
12047         check_stats $SINGLEMDS "close" 1
12048         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
12049                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
12050                 check_stats $SINGLEMDS "mknod" 2
12051         }
12052         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
12053         check_stats $SINGLEMDS "unlink" 1
12054         rm -f ${testdir}/${tfile} || error "file remove failed"
12055         check_stats $SINGLEMDS "unlink" 2
12056
12057         # remove working dir and check mdt stats again.
12058         rmdir ${testdir} || error "rmdir failed"
12059         check_stats $SINGLEMDS "rmdir" 1
12060
12061         local testdir1=$DIR/${tdir}/stats_testdir1
12062         mkdir -p ${testdir}
12063         mkdir -p ${testdir1}
12064         touch ${testdir1}/test1
12065         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
12066         check_stats $SINGLEMDS "crossdir_rename" 1
12067
12068         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
12069         check_stats $SINGLEMDS "samedir_rename" 1
12070
12071         rm -rf $DIR/${tdir}
12072 }
12073 run_test 133a "Verifying MDT stats ========================================"
12074
12075 test_133b() {
12076         local res
12077
12078         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12079         remote_ost_nodsh && skip "remote OST with nodsh"
12080         remote_mds_nodsh && skip "remote MDS with nodsh"
12081
12082         local testdir=$DIR/${tdir}/stats_testdir
12083
12084         mkdir -p ${testdir} || error "mkdir failed"
12085         touch ${testdir}/${tfile} || error "touch failed"
12086         cancel_lru_locks mdc
12087
12088         # clear stats.
12089         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12090         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12091
12092         # extra mdt stats verification.
12093         chmod 444 ${testdir}/${tfile} || error "chmod failed"
12094         check_stats $SINGLEMDS "setattr" 1
12095         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12096         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
12097         then            # LU-1740
12098                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
12099                 check_stats $SINGLEMDS "getattr" 1
12100         fi
12101         rm -rf $DIR/${tdir}
12102
12103         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
12104         # so the check below is not reliable
12105         [ $MDSCOUNT -eq 1 ] || return 0
12106
12107         # Sleep to avoid a cached response.
12108         #define OBD_STATFS_CACHE_SECONDS 1
12109         sleep 2
12110         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12111         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12112         $LFS df || error "lfs failed"
12113         check_stats $SINGLEMDS "statfs" 1
12114
12115         # check aggregated statfs (LU-10018)
12116         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
12117                 return 0
12118         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
12119                 return 0
12120         sleep 2
12121         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12122         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12123         df $DIR
12124         check_stats $SINGLEMDS "statfs" 1
12125
12126         # We want to check that the client didn't send OST_STATFS to
12127         # ost1 but the MDT also uses OST_STATFS for precreate. So some
12128         # extra care is needed here.
12129         if remote_mds; then
12130                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
12131                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
12132
12133                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
12134                 [ "$res" ] && error "OST got STATFS"
12135         fi
12136
12137         return 0
12138 }
12139 run_test 133b "Verifying extra MDT stats =================================="
12140
12141 test_133c() {
12142         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12143         remote_ost_nodsh && skip "remote OST with nodsh"
12144         remote_mds_nodsh && skip "remote MDS with nodsh"
12145
12146         local testdir=$DIR/$tdir/stats_testdir
12147
12148         test_mkdir -p $testdir
12149
12150         # verify obdfilter stats.
12151         $LFS setstripe -c 1 -i 0 $testdir/$tfile
12152         sync
12153         cancel_lru_locks osc
12154         wait_delete_completed
12155
12156         # clear stats.
12157         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12158         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12159
12160         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
12161                 error "dd failed"
12162         sync
12163         cancel_lru_locks osc
12164         check_stats ost1 "write" 1
12165
12166         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
12167         check_stats ost1 "read" 1
12168
12169         > $testdir/$tfile || error "truncate failed"
12170         check_stats ost1 "punch" 1
12171
12172         rm -f $testdir/$tfile || error "file remove failed"
12173         wait_delete_completed
12174         check_stats ost1 "destroy" 1
12175
12176         rm -rf $DIR/$tdir
12177 }
12178 run_test 133c "Verifying OST stats ========================================"
12179
12180 order_2() {
12181         local value=$1
12182         local orig=$value
12183         local order=1
12184
12185         while [ $value -ge 2 ]; do
12186                 order=$((order*2))
12187                 value=$((value/2))
12188         done
12189
12190         if [ $orig -gt $order ]; then
12191                 order=$((order*2))
12192         fi
12193         echo $order
12194 }
12195
12196 size_in_KMGT() {
12197     local value=$1
12198     local size=('K' 'M' 'G' 'T');
12199     local i=0
12200     local size_string=$value
12201
12202     while [ $value -ge 1024 ]; do
12203         if [ $i -gt 3 ]; then
12204             #T is the biggest unit we get here, if that is bigger,
12205             #just return XXXT
12206             size_string=${value}T
12207             break
12208         fi
12209         value=$((value >> 10))
12210         if [ $value -lt 1024 ]; then
12211             size_string=${value}${size[$i]}
12212             break
12213         fi
12214         i=$((i + 1))
12215     done
12216
12217     echo $size_string
12218 }
12219
12220 get_rename_size() {
12221         local size=$1
12222         local context=${2:-.}
12223         local sample=$(do_facet $SINGLEMDS $LCTL \
12224                 get_param mdt.$FSNAME-MDT0000.rename_stats |
12225                 grep -A1 $context |
12226                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
12227         echo $sample
12228 }
12229
12230 test_133d() {
12231         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12232         remote_ost_nodsh && skip "remote OST with nodsh"
12233         remote_mds_nodsh && skip "remote MDS with nodsh"
12234         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
12235                 skip_env "MDS doesn't support rename stats"
12236
12237         local testdir1=$DIR/${tdir}/stats_testdir1
12238         local testdir2=$DIR/${tdir}/stats_testdir2
12239         mkdir -p $DIR/${tdir}
12240
12241         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
12242
12243         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
12244         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
12245
12246         createmany -o $testdir1/test 512 || error "createmany failed"
12247
12248         # check samedir rename size
12249         mv ${testdir1}/test0 ${testdir1}/test_0
12250
12251         local testdir1_size=$(ls -l $DIR/${tdir} |
12252                 awk '/stats_testdir1/ {print $5}')
12253         local testdir2_size=$(ls -l $DIR/${tdir} |
12254                 awk '/stats_testdir2/ {print $5}')
12255
12256         testdir1_size=$(order_2 $testdir1_size)
12257         testdir2_size=$(order_2 $testdir2_size)
12258
12259         testdir1_size=$(size_in_KMGT $testdir1_size)
12260         testdir2_size=$(size_in_KMGT $testdir2_size)
12261
12262         echo "source rename dir size: ${testdir1_size}"
12263         echo "target rename dir size: ${testdir2_size}"
12264
12265         local cmd="do_facet $SINGLEMDS $LCTL "
12266         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
12267
12268         eval $cmd || error "$cmd failed"
12269         local samedir=$($cmd | grep 'same_dir')
12270         local same_sample=$(get_rename_size $testdir1_size)
12271         [ -z "$samedir" ] && error "samedir_rename_size count error"
12272         [[ $same_sample -eq 1 ]] ||
12273                 error "samedir_rename_size error $same_sample"
12274         echo "Check same dir rename stats success"
12275
12276         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
12277
12278         # check crossdir rename size
12279         mv ${testdir1}/test_0 ${testdir2}/test_0
12280
12281         testdir1_size=$(ls -l $DIR/${tdir} |
12282                 awk '/stats_testdir1/ {print $5}')
12283         testdir2_size=$(ls -l $DIR/${tdir} |
12284                 awk '/stats_testdir2/ {print $5}')
12285
12286         testdir1_size=$(order_2 $testdir1_size)
12287         testdir2_size=$(order_2 $testdir2_size)
12288
12289         testdir1_size=$(size_in_KMGT $testdir1_size)
12290         testdir2_size=$(size_in_KMGT $testdir2_size)
12291
12292         echo "source rename dir size: ${testdir1_size}"
12293         echo "target rename dir size: ${testdir2_size}"
12294
12295         eval $cmd || error "$cmd failed"
12296         local crossdir=$($cmd | grep 'crossdir')
12297         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
12298         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
12299         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
12300         [[ $src_sample -eq 1 ]] ||
12301                 error "crossdir_rename_size error $src_sample"
12302         [[ $tgt_sample -eq 1 ]] ||
12303                 error "crossdir_rename_size error $tgt_sample"
12304         echo "Check cross dir rename stats success"
12305         rm -rf $DIR/${tdir}
12306 }
12307 run_test 133d "Verifying rename_stats ========================================"
12308
12309 test_133e() {
12310         remote_mds_nodsh && skip "remote MDS with nodsh"
12311         remote_ost_nodsh && skip "remote OST with nodsh"
12312         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12313
12314         local testdir=$DIR/${tdir}/stats_testdir
12315         local ctr f0 f1 bs=32768 count=42 sum
12316
12317         mkdir -p ${testdir} || error "mkdir failed"
12318
12319         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
12320
12321         for ctr in {write,read}_bytes; do
12322                 sync
12323                 cancel_lru_locks osc
12324
12325                 do_facet ost1 $LCTL set_param -n \
12326                         "obdfilter.*.exports.clear=clear"
12327
12328                 if [ $ctr = write_bytes ]; then
12329                         f0=/dev/zero
12330                         f1=${testdir}/${tfile}
12331                 else
12332                         f0=${testdir}/${tfile}
12333                         f1=/dev/null
12334                 fi
12335
12336                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
12337                         error "dd failed"
12338                 sync
12339                 cancel_lru_locks osc
12340
12341                 sum=$(do_facet ost1 $LCTL get_param \
12342                         "obdfilter.*.exports.*.stats" |
12343                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
12344                                 $1 == ctr { sum += $7 }
12345                                 END { printf("%0.0f", sum) }')
12346
12347                 if ((sum != bs * count)); then
12348                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
12349                 fi
12350         done
12351
12352         rm -rf $DIR/${tdir}
12353 }
12354 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
12355
12356 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
12357
12358 # Some versions of find (4.5.11, 4.5.14) included in CentOS 7.3-7.5 do
12359 # not honor the -ignore_readdir_race option correctly. So we call
12360 # error_ignore() rather than error() in these cases. See LU-11152.
12361 error_133() {
12362         if (find --version; do_facet mds1 find --version) |
12363                 grep -q '\b4\.5\.1[1-4]\b'; then
12364                 error_ignore LU-11152 "$@"
12365         else
12366                 error "$@"
12367         fi
12368 }
12369
12370 test_133f() {
12371         # First without trusting modes.
12372         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
12373         echo "proc_dirs='$proc_dirs'"
12374         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
12375         find $proc_dirs -exec cat '{}' \; &> /dev/null
12376
12377         # Second verifying readability.
12378         $LCTL get_param -R '*' &> /dev/null
12379
12380         # Verifing writability with badarea_io.
12381         find $proc_dirs \
12382                 -ignore_readdir_race \
12383                 -type f \
12384                 -not -name force_lbug \
12385                 -not -name changelog_mask \
12386                 -exec badarea_io '{}' \; ||
12387                         error_133 "find $proc_dirs failed"
12388 }
12389 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
12390
12391 test_133g() {
12392         remote_mds_nodsh && skip "remote MDS with nodsh"
12393         remote_ost_nodsh && skip "remote OST with nodsh"
12394
12395         # eventually, this can also be replaced with "lctl get_param -R",
12396         # but not until that option is always available on the server
12397         local facet
12398         for facet in mds1 ost1; do
12399                 [ $(lustre_version_code $facet) -le $(version_code 2.5.54) ] &&
12400                         skip_noexit "Too old lustre on $facet"
12401                 local facet_proc_dirs=$(do_facet $facet \
12402                                         \\\ls -d $proc_regexp 2>/dev/null)
12403                 echo "${facet}_proc_dirs='$facet_proc_dirs'"
12404                 [ -z "$facet_proc_dirs" ] && error "no proc_dirs on $facet"
12405                 do_facet $facet find $facet_proc_dirs \
12406                         ! -name req_history \
12407                         -exec cat '{}' \\\; &> /dev/null
12408
12409                 do_facet $facet find $facet_proc_dirs \
12410                         ! -name req_history \
12411                         -type f \
12412                         -exec cat '{}' \\\; &> /dev/null ||
12413                                 error "proc file read failed"
12414
12415                 do_facet $facet find $facet_proc_dirs \
12416                         -ignore_readdir_race \
12417                         -type f \
12418                         -not -name force_lbug \
12419                         -not -name changelog_mask \
12420                         -exec badarea_io '{}' \\\; ||
12421                                 error_133 "$facet find $facet_proc_dirs failed"
12422         done
12423
12424         # remount the FS in case writes/reads /proc break the FS
12425         cleanup || error "failed to unmount"
12426         setup || error "failed to setup"
12427         true
12428 }
12429 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
12430
12431 test_133h() {
12432         remote_mds_nodsh && skip "remote MDS with nodsh"
12433         remote_ost_nodsh && skip "remote OST with nodsh"
12434         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
12435                 skip "Need MDS version at least 2.9.54"
12436
12437         local facet
12438
12439         for facet in client mds1 ost1; do
12440                 local facet_proc_dirs=$(do_facet $facet \
12441                                         \\\ls -d $proc_regexp 2> /dev/null)
12442                 [ -z "$facet_proc_dirs" ] && error "no proc_dirs on $facet"
12443                 echo "${facet}_proc_dirs='$facet_proc_dirs'"
12444                 # Get the list of files that are missing the terminating newline
12445                 local missing=($(do_facet $facet \
12446                         find ${facet_proc_dirs} -type f \|              \
12447                                 while read F\; do                       \
12448                                         awk -v FS='\v' -v RS='\v\v'     \
12449                                         "'END { if(NR>0 &&              \
12450                                         \\\$NF !~ /.*\\\n\$/)           \
12451                                                 print FILENAME}'"       \
12452                                         '\$F'\;                         \
12453                                 done 2>/dev/null))
12454                 [ ${#missing[*]} -eq 0 ] ||
12455                         error "files do not end with newline: ${missing[*]}"
12456         done
12457 }
12458 run_test 133h "Proc files should end with newlines"
12459
12460 test_134a() {
12461         remote_mds_nodsh && skip "remote MDS with nodsh"
12462         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
12463                 skip "Need MDS version at least 2.7.54"
12464
12465         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
12466         cancel_lru_locks mdc
12467
12468         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12469         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12470         [ $unused -eq 0 ] || error "$unused locks are not cleared"
12471
12472         local nr=1000
12473         createmany -o $DIR/$tdir/f $nr ||
12474                 error "failed to create $nr files in $DIR/$tdir"
12475         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12476
12477         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
12478         do_facet mds1 $LCTL set_param fail_loc=0x327
12479         do_facet mds1 $LCTL set_param fail_val=500
12480         touch $DIR/$tdir/m
12481
12482         echo "sleep 10 seconds ..."
12483         sleep 10
12484         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
12485
12486         do_facet mds1 $LCTL set_param fail_loc=0
12487         do_facet mds1 $LCTL set_param fail_val=0
12488         [ $lck_cnt -lt $unused ] ||
12489                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
12490
12491         rm $DIR/$tdir/m
12492         unlinkmany $DIR/$tdir/f $nr
12493 }
12494 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
12495
12496 test_134b() {
12497         remote_mds_nodsh && skip "remote MDS with nodsh"
12498         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
12499                 skip "Need MDS version at least 2.7.54"
12500
12501         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
12502         cancel_lru_locks mdc
12503
12504         local low_wm=$(do_facet mds1 $LCTL get_param -n \
12505                         ldlm.lock_reclaim_threshold_mb)
12506         # disable reclaim temporarily
12507         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
12508
12509         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
12510         do_facet mds1 $LCTL set_param fail_loc=0x328
12511         do_facet mds1 $LCTL set_param fail_val=500
12512
12513         $LCTL set_param debug=+trace
12514
12515         local nr=600
12516         createmany -o $DIR/$tdir/f $nr &
12517         local create_pid=$!
12518
12519         echo "Sleep $TIMEOUT seconds ..."
12520         sleep $TIMEOUT
12521         if ! ps -p $create_pid  > /dev/null 2>&1; then
12522                 do_facet mds1 $LCTL set_param fail_loc=0
12523                 do_facet mds1 $LCTL set_param fail_val=0
12524                 do_facet mds1 $LCTL set_param \
12525                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
12526                 error "createmany finished incorrectly!"
12527         fi
12528         do_facet mds1 $LCTL set_param fail_loc=0
12529         do_facet mds1 $LCTL set_param fail_val=0
12530         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
12531         wait $create_pid || return 1
12532
12533         unlinkmany $DIR/$tdir/f $nr
12534 }
12535 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
12536
12537 test_140() { #bug-17379
12538         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12539
12540         test_mkdir $DIR/$tdir
12541         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
12542         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
12543
12544         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
12545         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
12546         local i=0
12547         while i=$((i + 1)); do
12548                 test_mkdir $i
12549                 cd $i || error "Changing to $i"
12550                 ln -s ../stat stat || error "Creating stat symlink"
12551                 # Read the symlink until ELOOP present,
12552                 # not LBUGing the system is considered success,
12553                 # we didn't overrun the stack.
12554                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
12555                 if [ $ret -ne 0 ]; then
12556                         if [ $ret -eq 40 ]; then
12557                                 break  # -ELOOP
12558                         else
12559                                 error "Open stat symlink"
12560                                         return
12561                         fi
12562                 fi
12563         done
12564         i=$((i - 1))
12565         echo "The symlink depth = $i"
12566         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
12567                 error "Invalid symlink depth"
12568
12569         # Test recursive symlink
12570         ln -s symlink_self symlink_self
12571         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
12572         echo "open symlink_self returns $ret"
12573         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
12574 }
12575 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
12576
12577 test_150() {
12578         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12579
12580         local TF="$TMP/$tfile"
12581
12582         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
12583         cp $TF $DIR/$tfile
12584         cancel_lru_locks $OSC
12585         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
12586         remount_client $MOUNT
12587         df -P $MOUNT
12588         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
12589
12590         $TRUNCATE $TF 6000
12591         $TRUNCATE $DIR/$tfile 6000
12592         cancel_lru_locks $OSC
12593         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
12594
12595         echo "12345" >>$TF
12596         echo "12345" >>$DIR/$tfile
12597         cancel_lru_locks $OSC
12598         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
12599
12600         echo "12345" >>$TF
12601         echo "12345" >>$DIR/$tfile
12602         cancel_lru_locks $OSC
12603         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
12604
12605         rm -f $TF
12606         true
12607 }
12608 run_test 150 "truncate/append tests"
12609
12610 #LU-2902 roc_hit was not able to read all values from lproc
12611 function roc_hit_init() {
12612         local list=$(comma_list $(osts_nodes))
12613         local dir=$DIR/$tdir-check
12614         local file=$dir/$tfile
12615         local BEFORE
12616         local AFTER
12617         local idx
12618
12619         test_mkdir $dir
12620         #use setstripe to do a write to every ost
12621         for i in $(seq 0 $((OSTCOUNT-1))); do
12622                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
12623                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
12624                 idx=$(printf %04x $i)
12625                 BEFORE=$(get_osd_param $list *OST*$idx stats |
12626                         awk '$1 == "cache_access" {sum += $7}
12627                                 END { printf("%0.0f", sum) }')
12628
12629                 cancel_lru_locks osc
12630                 cat $file >/dev/null
12631
12632                 AFTER=$(get_osd_param $list *OST*$idx stats |
12633                         awk '$1 == "cache_access" {sum += $7}
12634                                 END { printf("%0.0f", sum) }')
12635
12636                 echo BEFORE:$BEFORE AFTER:$AFTER
12637                 if ! let "AFTER - BEFORE == 4"; then
12638                         rm -rf $dir
12639                         error "roc_hit is not safe to use"
12640                 fi
12641                 rm $file
12642         done
12643
12644         rm -rf $dir
12645 }
12646
12647 function roc_hit() {
12648         local list=$(comma_list $(osts_nodes))
12649         echo $(get_osd_param $list '' stats |
12650                 awk '$1 == "cache_hit" {sum += $7}
12651                         END { printf("%0.0f", sum) }')
12652 }
12653
12654 function set_cache() {
12655         local on=1
12656
12657         if [ "$2" == "off" ]; then
12658                 on=0;
12659         fi
12660         local list=$(comma_list $(osts_nodes))
12661         set_osd_param $list '' $1_cache_enable $on
12662
12663         cancel_lru_locks osc
12664 }
12665
12666 test_151() {
12667         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12668         remote_ost_nodsh && skip "remote OST with nodsh"
12669
12670         local CPAGES=3
12671         local list=$(comma_list $(osts_nodes))
12672
12673         # check whether obdfilter is cache capable at all
12674         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
12675                 skip "not cache-capable obdfilter"
12676         fi
12677
12678         # check cache is enabled on all obdfilters
12679         if get_osd_param $list '' read_cache_enable | grep 0; then
12680                 skip "oss cache is disabled"
12681         fi
12682
12683         set_osd_param $list '' writethrough_cache_enable 1
12684
12685         # check write cache is enabled on all obdfilters
12686         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
12687                 skip "oss write cache is NOT enabled"
12688         fi
12689
12690         roc_hit_init
12691
12692         #define OBD_FAIL_OBD_NO_LRU  0x609
12693         do_nodes $list $LCTL set_param fail_loc=0x609
12694
12695         # pages should be in the case right after write
12696         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
12697                 error "dd failed"
12698
12699         local BEFORE=$(roc_hit)
12700         cancel_lru_locks osc
12701         cat $DIR/$tfile >/dev/null
12702         local AFTER=$(roc_hit)
12703
12704         do_nodes $list $LCTL set_param fail_loc=0
12705
12706         if ! let "AFTER - BEFORE == CPAGES"; then
12707                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12708         fi
12709
12710         cancel_lru_locks osc
12711         # invalidates OST cache
12712         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
12713         set_osd_param $list '' read_cache_enable 0
12714         cat $DIR/$tfile >/dev/null
12715
12716         # now data shouldn't be found in the cache
12717         BEFORE=$(roc_hit)
12718         cancel_lru_locks osc
12719         cat $DIR/$tfile >/dev/null
12720         AFTER=$(roc_hit)
12721         if let "AFTER - BEFORE != 0"; then
12722                 error "IN CACHE: before: $BEFORE, after: $AFTER"
12723         fi
12724
12725         set_osd_param $list '' read_cache_enable 1
12726         rm -f $DIR/$tfile
12727 }
12728 run_test 151 "test cache on oss and controls ==============================="
12729
12730 test_152() {
12731         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12732
12733         local TF="$TMP/$tfile"
12734
12735         # simulate ENOMEM during write
12736 #define OBD_FAIL_OST_NOMEM      0x226
12737         lctl set_param fail_loc=0x80000226
12738         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
12739         cp $TF $DIR/$tfile
12740         sync || error "sync failed"
12741         lctl set_param fail_loc=0
12742
12743         # discard client's cache
12744         cancel_lru_locks osc
12745
12746         # simulate ENOMEM during read
12747         lctl set_param fail_loc=0x80000226
12748         cmp $TF $DIR/$tfile || error "cmp failed"
12749         lctl set_param fail_loc=0
12750
12751         rm -f $TF
12752 }
12753 run_test 152 "test read/write with enomem ============================"
12754
12755 test_153() {
12756         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
12757 }
12758 run_test 153 "test if fdatasync does not crash ======================="
12759
12760 dot_lustre_fid_permission_check() {
12761         local fid=$1
12762         local ffid=$MOUNT/.lustre/fid/$fid
12763         local test_dir=$2
12764
12765         echo "stat fid $fid"
12766         stat $ffid > /dev/null || error "stat $ffid failed."
12767         echo "touch fid $fid"
12768         touch $ffid || error "touch $ffid failed."
12769         echo "write to fid $fid"
12770         cat /etc/hosts > $ffid || error "write $ffid failed."
12771         echo "read fid $fid"
12772         diff /etc/hosts $ffid || error "read $ffid failed."
12773         echo "append write to fid $fid"
12774         cat /etc/hosts >> $ffid || error "append write $ffid failed."
12775         echo "rename fid $fid"
12776         mv $ffid $test_dir/$tfile.1 &&
12777                 error "rename $ffid to $tfile.1 should fail."
12778         touch $test_dir/$tfile.1
12779         mv $test_dir/$tfile.1 $ffid &&
12780                 error "rename $tfile.1 to $ffid should fail."
12781         rm -f $test_dir/$tfile.1
12782         echo "truncate fid $fid"
12783         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
12784         echo "link fid $fid"
12785         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
12786         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
12787                 echo "setfacl fid $fid"
12788                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
12789                 echo "getfacl fid $fid"
12790                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
12791         fi
12792         echo "unlink fid $fid"
12793         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
12794         echo "mknod fid $fid"
12795         mknod $ffid c 1 3 && error "mknod $ffid should fail."
12796
12797         fid=[0xf00000400:0x1:0x0]
12798         ffid=$MOUNT/.lustre/fid/$fid
12799
12800         echo "stat non-exist fid $fid"
12801         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
12802         echo "write to non-exist fid $fid"
12803         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
12804         echo "link new fid $fid"
12805         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
12806
12807         mkdir -p $test_dir/$tdir
12808         touch $test_dir/$tdir/$tfile
12809         fid=$($LFS path2fid $test_dir/$tdir)
12810         rc=$?
12811         [ $rc -ne 0 ] &&
12812                 error "error: could not get fid for $test_dir/$dir/$tfile."
12813
12814         ffid=$MOUNT/.lustre/fid/$fid
12815
12816         echo "ls $fid"
12817         ls $ffid > /dev/null || error "ls $ffid failed."
12818         echo "touch $fid/$tfile.1"
12819         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
12820
12821         echo "touch $MOUNT/.lustre/fid/$tfile"
12822         touch $MOUNT/.lustre/fid/$tfile && \
12823                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
12824
12825         echo "setxattr to $MOUNT/.lustre/fid"
12826         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
12827
12828         echo "listxattr for $MOUNT/.lustre/fid"
12829         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
12830
12831         echo "delxattr from $MOUNT/.lustre/fid"
12832         setfattr -x trusted.name1 $MOUNT/.lustre/fid
12833
12834         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
12835         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
12836                 error "touch invalid fid should fail."
12837
12838         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
12839         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
12840                 error "touch non-normal fid should fail."
12841
12842         echo "rename $tdir to $MOUNT/.lustre/fid"
12843         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
12844                 error "rename to $MOUNT/.lustre/fid should fail."
12845
12846         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
12847         then            # LU-3547
12848                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
12849                 local new_obf_mode=777
12850
12851                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
12852                 chmod $new_obf_mode $DIR/.lustre/fid ||
12853                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
12854
12855                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
12856                 [ $obf_mode -eq $new_obf_mode ] ||
12857                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
12858
12859                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
12860                 chmod $old_obf_mode $DIR/.lustre/fid ||
12861                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
12862         fi
12863
12864         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
12865         fid=$($LFS path2fid $test_dir/$tfile-2)
12866
12867         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
12868         then # LU-5424
12869                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
12870                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
12871                         error "create lov data thru .lustre failed"
12872         fi
12873         echo "cp /etc/passwd $test_dir/$tfile-2"
12874         cp /etc/passwd $test_dir/$tfile-2 ||
12875                 error "copy to $test_dir/$tfile-2 failed."
12876         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
12877         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
12878                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
12879
12880         rm -rf $test_dir/tfile.lnk
12881         rm -rf $test_dir/$tfile-2
12882 }
12883
12884 test_154A() {
12885         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
12886                 skip "Need MDS version at least 2.4.1"
12887
12888         local tf=$DIR/$tfile
12889         touch $tf
12890
12891         local fid=$($LFS path2fid $tf)
12892         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
12893
12894         # check that we get the same pathname back
12895         local found=$($LFS fid2path $MOUNT "$fid")
12896         [ -z "$found" ] && error "fid2path unable to get '$fid' path"
12897         [ "$found" == "$tf" ] ||
12898                 error "fid2path($fid=path2fid($tf)) = $found != $tf"
12899 }
12900 run_test 154A "lfs path2fid and fid2path basic checks"
12901
12902 test_154B() {
12903         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
12904                 skip "Need MDS version at least 2.4.1"
12905
12906         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
12907         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
12908         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
12909         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
12910
12911         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
12912         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
12913
12914         # check that we get the same pathname
12915         echo "PFID: $PFID, name: $name"
12916         local FOUND=$($LFS fid2path $MOUNT "$PFID")
12917         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
12918         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
12919                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
12920
12921         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
12922 }
12923 run_test 154B "verify the ll_decode_linkea tool"
12924
12925 test_154a() {
12926         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12927         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
12928         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
12929                 skip "Need MDS version at least 2.2.51"
12930         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
12931
12932         cp /etc/hosts $DIR/$tfile
12933
12934         fid=$($LFS path2fid $DIR/$tfile)
12935         rc=$?
12936         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
12937
12938         dot_lustre_fid_permission_check "$fid" $DIR ||
12939                 error "dot lustre permission check $fid failed"
12940
12941         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
12942
12943         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
12944
12945         touch $MOUNT/.lustre/file &&
12946                 error "creation is not allowed under .lustre"
12947
12948         mkdir $MOUNT/.lustre/dir &&
12949                 error "mkdir is not allowed under .lustre"
12950
12951         rm -rf $DIR/$tfile
12952 }
12953 run_test 154a "Open-by-FID"
12954
12955 test_154b() {
12956         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12957         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
12958         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
12959         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
12960                 skip "Need MDS version at least 2.2.51"
12961
12962         local remote_dir=$DIR/$tdir/remote_dir
12963         local MDTIDX=1
12964         local rc=0
12965
12966         mkdir -p $DIR/$tdir
12967         $LFS mkdir -i $MDTIDX $remote_dir ||
12968                 error "create remote directory failed"
12969
12970         cp /etc/hosts $remote_dir/$tfile
12971
12972         fid=$($LFS path2fid $remote_dir/$tfile)
12973         rc=$?
12974         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
12975
12976         dot_lustre_fid_permission_check "$fid" $remote_dir ||
12977                 error "dot lustre permission check $fid failed"
12978         rm -rf $DIR/$tdir
12979 }
12980 run_test 154b "Open-by-FID for remote directory"
12981
12982 test_154c() {
12983         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
12984                 skip "Need MDS version at least 2.4.1"
12985
12986         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
12987         local FID1=$($LFS path2fid $DIR/$tfile.1)
12988         local FID2=$($LFS path2fid $DIR/$tfile.2)
12989         local FID3=$($LFS path2fid $DIR/$tfile.3)
12990
12991         local N=1
12992         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
12993                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
12994                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
12995                 local want=FID$N
12996                 [ "$FID" = "${!want}" ] ||
12997                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
12998                 N=$((N + 1))
12999         done
13000
13001         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
13002         do
13003                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
13004                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
13005                 N=$((N + 1))
13006         done
13007 }
13008 run_test 154c "lfs path2fid and fid2path multiple arguments"
13009
13010 test_154d() {
13011         remote_mds_nodsh && skip "remote MDS with nodsh"
13012         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
13013                 skip "Need MDS version at least 2.5.53"
13014
13015         if remote_mds; then
13016                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
13017         else
13018                 nid="0@lo"
13019         fi
13020         local proc_ofile="mdt.*.exports.'$nid'.open_files"
13021         local fd
13022         local cmd
13023
13024         rm -f $DIR/$tfile
13025         touch $DIR/$tfile
13026
13027         local fid=$($LFS path2fid $DIR/$tfile)
13028         # Open the file
13029         fd=$(free_fd)
13030         cmd="exec $fd<$DIR/$tfile"
13031         eval $cmd
13032         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
13033         echo "$fid_list" | grep "$fid"
13034         rc=$?
13035
13036         cmd="exec $fd>/dev/null"
13037         eval $cmd
13038         if [ $rc -ne 0 ]; then
13039                 error "FID $fid not found in open files list $fid_list"
13040         fi
13041 }
13042 run_test 154d "Verify open file fid"
13043
13044 test_154e()
13045 {
13046         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
13047                 skip "Need MDS version at least 2.6.50"
13048
13049         if ls -a $MOUNT | grep -q '^\.lustre$'; then
13050                 error ".lustre returned by readdir"
13051         fi
13052 }
13053 run_test 154e ".lustre is not returned by readdir"
13054
13055 test_154f() {
13056         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13057
13058         # create parent directory on a single MDT to avoid cross-MDT hardlinks
13059         test_mkdir -p -c1 $DIR/$tdir/d
13060         # test dirs inherit from its stripe
13061         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
13062         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
13063         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
13064         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
13065         touch $DIR/f
13066
13067         # get fid of parents
13068         local FID0=$($LFS path2fid $DIR/$tdir/d)
13069         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
13070         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
13071         local FID3=$($LFS path2fid $DIR)
13072
13073         # check that path2fid --parents returns expected <parent_fid>/name
13074         # 1) test for a directory (single parent)
13075         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
13076         [ "$parent" == "$FID0/foo1" ] ||
13077                 error "expected parent: $FID0/foo1, got: $parent"
13078
13079         # 2) test for a file with nlink > 1 (multiple parents)
13080         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
13081         echo "$parent" | grep -F "$FID1/$tfile" ||
13082                 error "$FID1/$tfile not returned in parent list"
13083         echo "$parent" | grep -F "$FID2/link" ||
13084                 error "$FID2/link not returned in parent list"
13085
13086         # 3) get parent by fid
13087         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
13088         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13089         echo "$parent" | grep -F "$FID1/$tfile" ||
13090                 error "$FID1/$tfile not returned in parent list (by fid)"
13091         echo "$parent" | grep -F "$FID2/link" ||
13092                 error "$FID2/link not returned in parent list (by fid)"
13093
13094         # 4) test for entry in root directory
13095         parent=$($LFS path2fid --parents $DIR/f)
13096         echo "$parent" | grep -F "$FID3/f" ||
13097                 error "$FID3/f not returned in parent list"
13098
13099         # 5) test it on root directory
13100         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
13101                 error "$MOUNT should not have parents"
13102
13103         # enable xattr caching and check that linkea is correctly updated
13104         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
13105         save_lustre_params client "llite.*.xattr_cache" > $save
13106         lctl set_param llite.*.xattr_cache 1
13107
13108         # 6.1) linkea update on rename
13109         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
13110
13111         # get parents by fid
13112         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13113         # foo1 should no longer be returned in parent list
13114         echo "$parent" | grep -F "$FID1" &&
13115                 error "$FID1 should no longer be in parent list"
13116         # the new path should appear
13117         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
13118                 error "$FID2/$tfile.moved is not in parent list"
13119
13120         # 6.2) linkea update on unlink
13121         rm -f $DIR/$tdir/d/foo2/link
13122         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13123         # foo2/link should no longer be returned in parent list
13124         echo "$parent" | grep -F "$FID2/link" &&
13125                 error "$FID2/link should no longer be in parent list"
13126         true
13127
13128         rm -f $DIR/f
13129         restore_lustre_params < $save
13130         rm -f $save
13131 }
13132 run_test 154f "get parent fids by reading link ea"
13133
13134 test_154g()
13135 {
13136         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13137         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
13138            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
13139                 skip "Need MDS version at least 2.6.92"
13140
13141         mkdir -p $DIR/$tdir
13142         llapi_fid_test -d $DIR/$tdir
13143 }
13144 run_test 154g "various llapi FID tests"
13145
13146 test_155_small_load() {
13147     local temp=$TMP/$tfile
13148     local file=$DIR/$tfile
13149
13150     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
13151         error "dd of=$temp bs=6096 count=1 failed"
13152     cp $temp $file
13153     cancel_lru_locks $OSC
13154     cmp $temp $file || error "$temp $file differ"
13155
13156     $TRUNCATE $temp 6000
13157     $TRUNCATE $file 6000
13158     cmp $temp $file || error "$temp $file differ (truncate1)"
13159
13160     echo "12345" >>$temp
13161     echo "12345" >>$file
13162     cmp $temp $file || error "$temp $file differ (append1)"
13163
13164     echo "12345" >>$temp
13165     echo "12345" >>$file
13166     cmp $temp $file || error "$temp $file differ (append2)"
13167
13168     rm -f $temp $file
13169     true
13170 }
13171
13172 test_155_big_load() {
13173         remote_ost_nodsh && skip "remote OST with nodsh"
13174
13175         local temp=$TMP/$tfile
13176         local file=$DIR/$tfile
13177
13178         free_min_max
13179         local cache_size=$(do_facet ost$((MAXI+1)) \
13180                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
13181         local large_file_size=$((cache_size * 2))
13182
13183         echo "OSS cache size: $cache_size KB"
13184         echo "Large file size: $large_file_size KB"
13185
13186         [ $MAXV -le $large_file_size ] &&
13187                 skip_env "max available OST size needs > $large_file_size KB"
13188
13189         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
13190
13191         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
13192                 error "dd of=$temp bs=$large_file_size count=1k failed"
13193         cp $temp $file
13194         ls -lh $temp $file
13195         cancel_lru_locks osc
13196         cmp $temp $file || error "$temp $file differ"
13197
13198         rm -f $temp $file
13199         true
13200 }
13201
13202 save_writethrough() {
13203         local facets=$(get_facets OST)
13204
13205         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
13206 }
13207
13208 test_155a() {
13209         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13210
13211         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13212
13213         save_writethrough $p
13214
13215         set_cache read on
13216         set_cache writethrough on
13217         test_155_small_load
13218         restore_lustre_params < $p
13219         rm -f $p
13220 }
13221 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
13222
13223 test_155b() {
13224         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13225
13226         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13227
13228         save_writethrough $p
13229
13230         set_cache read on
13231         set_cache writethrough off
13232         test_155_small_load
13233         restore_lustre_params < $p
13234         rm -f $p
13235 }
13236 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
13237
13238 test_155c() {
13239         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13240
13241         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13242
13243         save_writethrough $p
13244
13245         set_cache read off
13246         set_cache writethrough on
13247         test_155_small_load
13248         restore_lustre_params < $p
13249         rm -f $p
13250 }
13251 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
13252
13253 test_155d() {
13254         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13255
13256         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13257
13258         save_writethrough $p
13259
13260         set_cache read off
13261         set_cache writethrough off
13262         test_155_small_load
13263         restore_lustre_params < $p
13264         rm -f $p
13265 }
13266 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
13267
13268 test_155e() {
13269         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13270
13271         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13272
13273         save_writethrough $p
13274
13275         set_cache read on
13276         set_cache writethrough on
13277         test_155_big_load
13278         restore_lustre_params < $p
13279         rm -f $p
13280 }
13281 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
13282
13283 test_155f() {
13284         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13285
13286         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13287
13288         save_writethrough $p
13289
13290         set_cache read on
13291         set_cache writethrough off
13292         test_155_big_load
13293         restore_lustre_params < $p
13294         rm -f $p
13295 }
13296 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
13297
13298 test_155g() {
13299         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13300
13301         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13302
13303         save_writethrough $p
13304
13305         set_cache read off
13306         set_cache writethrough on
13307         test_155_big_load
13308         restore_lustre_params < $p
13309         rm -f $p
13310 }
13311 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
13312
13313 test_155h() {
13314         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13315
13316         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13317
13318         save_writethrough $p
13319
13320         set_cache read off
13321         set_cache writethrough off
13322         test_155_big_load
13323         restore_lustre_params < $p
13324         rm -f $p
13325 }
13326 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
13327
13328 test_156() {
13329         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13330         remote_ost_nodsh && skip "remote OST with nodsh"
13331         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
13332                 skip "stats not implemented on old servers"
13333         [ "$ost1_FSTYPE" = "zfs" ] &&
13334                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
13335
13336         local CPAGES=3
13337         local BEFORE
13338         local AFTER
13339         local file="$DIR/$tfile"
13340         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13341
13342         save_writethrough $p
13343         roc_hit_init
13344
13345         log "Turn on read and write cache"
13346         set_cache read on
13347         set_cache writethrough on
13348
13349         log "Write data and read it back."
13350         log "Read should be satisfied from the cache."
13351         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
13352         BEFORE=$(roc_hit)
13353         cancel_lru_locks osc
13354         cat $file >/dev/null
13355         AFTER=$(roc_hit)
13356         if ! let "AFTER - BEFORE == CPAGES"; then
13357                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
13358         else
13359                 log "cache hits: before: $BEFORE, after: $AFTER"
13360         fi
13361
13362         log "Read again; it should be satisfied from the cache."
13363         BEFORE=$AFTER
13364         cancel_lru_locks osc
13365         cat $file >/dev/null
13366         AFTER=$(roc_hit)
13367         if ! let "AFTER - BEFORE == CPAGES"; then
13368                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
13369         else
13370                 log "cache hits:: before: $BEFORE, after: $AFTER"
13371         fi
13372
13373         log "Turn off the read cache and turn on the write cache"
13374         set_cache read off
13375         set_cache writethrough on
13376
13377         log "Read again; it should be satisfied from the cache."
13378         BEFORE=$(roc_hit)
13379         cancel_lru_locks osc
13380         cat $file >/dev/null
13381         AFTER=$(roc_hit)
13382         if ! let "AFTER - BEFORE == CPAGES"; then
13383                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
13384         else
13385                 log "cache hits:: before: $BEFORE, after: $AFTER"
13386         fi
13387
13388         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
13389                 # > 2.12.56 uses pagecache if cached
13390                 log "Read again; it should not be satisfied from the cache."
13391                 BEFORE=$AFTER
13392                 cancel_lru_locks osc
13393                 cat $file >/dev/null
13394                 AFTER=$(roc_hit)
13395                 if ! let "AFTER - BEFORE == 0"; then
13396                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
13397                 else
13398                         log "cache hits:: before: $BEFORE, after: $AFTER"
13399                 fi
13400         fi
13401
13402         log "Write data and read it back."
13403         log "Read should be satisfied from the cache."
13404         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
13405         BEFORE=$(roc_hit)
13406         cancel_lru_locks osc
13407         cat $file >/dev/null
13408         AFTER=$(roc_hit)
13409         if ! let "AFTER - BEFORE == CPAGES"; then
13410                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
13411         else
13412                 log "cache hits:: before: $BEFORE, after: $AFTER"
13413         fi
13414
13415         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
13416                 # > 2.12.56 uses pagecache if cached
13417                 log "Read again; it should not be satisfied from the cache."
13418                 BEFORE=$AFTER
13419                 cancel_lru_locks osc
13420                 cat $file >/dev/null
13421                 AFTER=$(roc_hit)
13422                 if ! let "AFTER - BEFORE == 0"; then
13423                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
13424                 else
13425                         log "cache hits:: before: $BEFORE, after: $AFTER"
13426                 fi
13427         fi
13428
13429         log "Turn off read and write cache"
13430         set_cache read off
13431         set_cache writethrough off
13432
13433         log "Write data and read it back"
13434         log "It should not be satisfied from the cache."
13435         rm -f $file
13436         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
13437         cancel_lru_locks osc
13438         BEFORE=$(roc_hit)
13439         cat $file >/dev/null
13440         AFTER=$(roc_hit)
13441         if ! let "AFTER - BEFORE == 0"; then
13442                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
13443         else
13444                 log "cache hits:: before: $BEFORE, after: $AFTER"
13445         fi
13446
13447         log "Turn on the read cache and turn off the write cache"
13448         set_cache read on
13449         set_cache writethrough off
13450
13451         log "Write data and read it back"
13452         log "It should not be satisfied from the cache."
13453         rm -f $file
13454         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
13455         BEFORE=$(roc_hit)
13456         cancel_lru_locks osc
13457         cat $file >/dev/null
13458         AFTER=$(roc_hit)
13459         if ! let "AFTER - BEFORE == 0"; then
13460                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
13461         else
13462                 log "cache hits:: before: $BEFORE, after: $AFTER"
13463         fi
13464
13465         log "Read again; it should be satisfied from the cache."
13466         BEFORE=$(roc_hit)
13467         cancel_lru_locks osc
13468         cat $file >/dev/null
13469         AFTER=$(roc_hit)
13470         if ! let "AFTER - BEFORE == CPAGES"; then
13471                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
13472         else
13473                 log "cache hits:: before: $BEFORE, after: $AFTER"
13474         fi
13475
13476         restore_lustre_params < $p
13477         rm -f $p $file
13478 }
13479 run_test 156 "Verification of tunables"
13480
13481 test_160a() {
13482         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13483         remote_mds_nodsh && skip "remote MDS with nodsh"
13484         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
13485                 skip "Need MDS version at least 2.2.0"
13486
13487         changelog_register || error "changelog_register failed"
13488         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
13489         changelog_users $SINGLEMDS | grep -q $cl_user ||
13490                 error "User $cl_user not found in changelog_users"
13491
13492         # change something
13493         test_mkdir -p $DIR/$tdir/pics/2008/zachy
13494         changelog_clear 0 || error "changelog_clear failed"
13495         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
13496         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
13497         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
13498         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
13499         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
13500         rm $DIR/$tdir/pics/desktop.jpg
13501
13502         changelog_dump | tail -10
13503
13504         echo "verifying changelog mask"
13505         changelog_chmask "-MKDIR"
13506         changelog_chmask "-CLOSE"
13507
13508         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
13509         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
13510
13511         changelog_chmask "+MKDIR"
13512         changelog_chmask "+CLOSE"
13513
13514         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
13515         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
13516
13517         changelog_dump | tail -10
13518         MKDIRS=$(changelog_dump | grep -c "MKDIR")
13519         CLOSES=$(changelog_dump | grep -c "CLOSE")
13520         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
13521         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
13522
13523         # verify contents
13524         echo "verifying target fid"
13525         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
13526         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
13527         [ "$fidc" == "$fidf" ] ||
13528                 error "changelog '$tfile' fid $fidc != file fid $fidf"
13529         echo "verifying parent fid"
13530         # The FID returned from the Changelog may be the directory shard on
13531         # a different MDT, and not the FID returned by path2fid on the parent.
13532         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
13533         # since this is what will matter when recreating this file in the tree.
13534         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
13535         local pathp=$($LFS fid2path $MOUNT "$fidp")
13536         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
13537                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
13538
13539         echo "getting records for $cl_user"
13540         changelog_users $SINGLEMDS
13541         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
13542         local nclr=3
13543         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
13544                 error "changelog_clear failed"
13545         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
13546         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
13547         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
13548                 error "user index expect $user_rec1 + $nclr != $user_rec2"
13549
13550         local min0_rec=$(changelog_users $SINGLEMDS |
13551                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
13552         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
13553                           awk '{ print $1; exit; }')
13554
13555         changelog_dump | tail -n 5
13556         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
13557         [ $first_rec == $((min0_rec + 1)) ] ||
13558                 error "first index should be $min0_rec + 1 not $first_rec"
13559
13560         # LU-3446 changelog index reset on MDT restart
13561         local cur_rec1=$(changelog_users $SINGLEMDS |
13562                          awk '/^current.index:/ { print $NF }')
13563         changelog_clear 0 ||
13564                 error "clear all changelog records for $cl_user failed"
13565         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
13566         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
13567                 error "Fail to start $SINGLEMDS"
13568         local cur_rec2=$(changelog_users $SINGLEMDS |
13569                          awk '/^current.index:/ { print $NF }')
13570         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
13571         [ $cur_rec1 == $cur_rec2 ] ||
13572                 error "current index should be $cur_rec1 not $cur_rec2"
13573
13574         echo "verifying users from this test are deregistered"
13575         changelog_deregister || error "changelog_deregister failed"
13576         changelog_users $SINGLEMDS | grep -q $cl_user &&
13577                 error "User '$cl_user' still in changelog_users"
13578
13579         # lctl get_param -n mdd.*.changelog_users
13580         # current index: 144
13581         # ID    index (idle seconds)
13582         # cl3   144 (2)
13583         if ! changelog_users $SINGLEMDS | grep "^cl"; then
13584                 # this is the normal case where all users were deregistered
13585                 # make sure no new records are added when no users are present
13586                 local last_rec1=$(changelog_users $SINGLEMDS |
13587                                   awk '/^current.index:/ { print $NF }')
13588                 touch $DIR/$tdir/chloe
13589                 local last_rec2=$(changelog_users $SINGLEMDS |
13590                                   awk '/^current.index:/ { print $NF }')
13591                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
13592                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
13593         else
13594                 # any changelog users must be leftovers from a previous test
13595                 changelog_users $SINGLEMDS
13596                 echo "other changelog users; can't verify off"
13597         fi
13598 }
13599 run_test 160a "changelog sanity"
13600
13601 test_160b() { # LU-3587
13602         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13603         remote_mds_nodsh && skip "remote MDS with nodsh"
13604         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
13605                 skip "Need MDS version at least 2.2.0"
13606
13607         changelog_register || error "changelog_register failed"
13608         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
13609         changelog_users $SINGLEMDS | grep -q $cl_user ||
13610                 error "User '$cl_user' not found in changelog_users"
13611
13612         local longname1=$(str_repeat a 255)
13613         local longname2=$(str_repeat b 255)
13614
13615         cd $DIR
13616         echo "creating very long named file"
13617         touch $longname1 || error "create of '$longname1' failed"
13618         echo "renaming very long named file"
13619         mv $longname1 $longname2
13620
13621         changelog_dump | grep RENME | tail -n 5
13622         rm -f $longname2
13623 }
13624 run_test 160b "Verify that very long rename doesn't crash in changelog"
13625
13626 test_160c() {
13627         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13628         remote_mds_nodsh && skip "remote MDS with nodsh"
13629
13630         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
13631                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
13632                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
13633                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
13634
13635         local rc=0
13636
13637         # Registration step
13638         changelog_register || error "changelog_register failed"
13639
13640         rm -rf $DIR/$tdir
13641         mkdir -p $DIR/$tdir
13642         $MCREATE $DIR/$tdir/foo_160c
13643         changelog_chmask "-TRUNC"
13644         $TRUNCATE $DIR/$tdir/foo_160c 200
13645         changelog_chmask "+TRUNC"
13646         $TRUNCATE $DIR/$tdir/foo_160c 199
13647         changelog_dump | tail -n 5
13648         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
13649         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
13650 }
13651 run_test 160c "verify that changelog log catch the truncate event"
13652
13653 test_160d() {
13654         remote_mds_nodsh && skip "remote MDS with nodsh"
13655         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13656         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13657         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
13658                 skip "Need MDS version at least 2.7.60"
13659
13660         # Registration step
13661         changelog_register || error "changelog_register failed"
13662
13663         mkdir -p $DIR/$tdir/migrate_dir
13664         changelog_clear 0 || error "changelog_clear failed"
13665
13666         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
13667         changelog_dump | tail -n 5
13668         local migrates=$(changelog_dump | grep -c "MIGRT")
13669         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
13670 }
13671 run_test 160d "verify that changelog log catch the migrate event"
13672
13673 test_160e() {
13674         remote_mds_nodsh && skip "remote MDS with nodsh"
13675
13676         # Create a user
13677         changelog_register || error "changelog_register failed"
13678
13679         # Delete a future user (expect fail)
13680         local MDT0=$(facet_svc $SINGLEMDS)
13681         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
13682         local rc=$?
13683
13684         if [ $rc -eq 0 ]; then
13685                 error "Deleted non-existant user cl77"
13686         elif [ $rc -ne 2 ]; then
13687                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
13688         fi
13689
13690         # Clear to a bad index (1 billion should be safe)
13691         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
13692         rc=$?
13693
13694         if [ $rc -eq 0 ]; then
13695                 error "Successfully cleared to invalid CL index"
13696         elif [ $rc -ne 22 ]; then
13697                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
13698         fi
13699 }
13700 run_test 160e "changelog negative testing (should return errors)"
13701
13702 test_160f() {
13703         remote_mds_nodsh && skip "remote MDS with nodsh" && return
13704         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
13705                 skip "Need MDS version at least 2.10.56"
13706
13707         local mdts=$(comma_list $(mdts_nodes))
13708
13709         # Create a user
13710         changelog_register || error "first changelog_register failed"
13711         changelog_register || error "second changelog_register failed"
13712         local cl_users
13713         declare -A cl_user1
13714         declare -A cl_user2
13715         local user_rec1
13716         local user_rec2
13717         local i
13718
13719         # generate some changelog records to accumulate on each MDT
13720         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "test_mkdir $tdir failed"
13721         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13722                 error "create $DIR/$tdir/$tfile failed"
13723
13724         # check changelogs have been generated
13725         local nbcl=$(changelog_dump | wc -l)
13726         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13727
13728         for param in "changelog_max_idle_time=10" \
13729                      "changelog_gc=1" \
13730                      "changelog_min_gc_interval=2" \
13731                      "changelog_min_free_cat_entries=3"; do
13732                 local MDT0=$(facet_svc $SINGLEMDS)
13733                 local var="${param%=*}"
13734                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
13735
13736                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
13737                 do_nodes $mdts $LCTL set_param mdd.*.$param
13738         done
13739
13740         # force cl_user2 to be idle (1st part)
13741         sleep 9
13742
13743         # simulate changelog catalog almost full
13744         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
13745         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
13746
13747         for i in $(seq $MDSCOUNT); do
13748                 cl_users=(${CL_USERS[mds$i]})
13749                 cl_user1[mds$i]="${cl_users[0]}"
13750                 cl_user2[mds$i]="${cl_users[1]}"
13751
13752                 [ -n "${cl_user1[mds$i]}" ] ||
13753                         error "mds$i: no user registered"
13754                 [ -n "${cl_user2[mds$i]}" ] ||
13755                         error "mds$i: only ${cl_user2[mds$i]} is registered"
13756
13757                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13758                 [ -n "$user_rec1" ] ||
13759                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13760                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
13761                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13762                 [ -n "$user_rec2" ] ||
13763                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13764                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
13765                      "$user_rec1 + 2 == $user_rec2"
13766                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
13767                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
13768                               "$user_rec1 + 2, but is $user_rec2"
13769                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
13770                 [ -n "$user_rec2" ] ||
13771                         error "mds$i: User ${cl_user2[mds$i]} not registered"
13772                 [ $user_rec1 == $user_rec2 ] ||
13773                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
13774                               "$user_rec1, but is $user_rec2"
13775         done
13776
13777         # force cl_user2 to be idle (2nd part) and to reach
13778         # changelog_max_idle_time
13779         sleep 2
13780
13781         # generate one more changelog to trigger fail_loc
13782         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13783                 error "create $DIR/$tdir/${tfile}bis failed"
13784
13785         # ensure gc thread is done
13786         for i in $(mdts_nodes); do
13787                 wait_update $i \
13788                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
13789                         error "$i: GC-thread not done"
13790         done
13791
13792         local first_rec
13793         for i in $(seq $MDSCOUNT); do
13794                 # check cl_user1 still registered
13795                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
13796                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13797                 # check cl_user2 unregistered
13798                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
13799                         error "mds$i: User ${cl_user2[mds$i]} still registered"
13800
13801                 # check changelogs are present and starting at $user_rec1 + 1
13802                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13803                 [ -n "$user_rec1" ] ||
13804                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13805                 first_rec=$($LFS changelog $(facet_svc mds$i) |
13806                             awk '{ print $1; exit; }')
13807
13808                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
13809                 [ $((user_rec1 + 1)) == $first_rec ] ||
13810                         error "mds$i: first index should be $user_rec1 + 1, " \
13811                               "but is $first_rec"
13812         done
13813 }
13814 run_test 160f "changelog garbage collect (timestamped users)"
13815
13816 test_160g() {
13817         remote_mds_nodsh && skip "remote MDS with nodsh"
13818         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
13819                 skip "Need MDS version at least 2.10.56"
13820
13821         local mdts=$(comma_list $(mdts_nodes))
13822
13823         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
13824         do_nodes $mdts $LCTL set_param fail_loc=0x1314
13825
13826         # Create a user
13827         changelog_register || error "first changelog_register failed"
13828         changelog_register || error "second changelog_register failed"
13829         local cl_users
13830         declare -A cl_user1
13831         declare -A cl_user2
13832         local user_rec1
13833         local user_rec2
13834         local i
13835
13836         # generate some changelog records to accumulate on each MDT
13837         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
13838         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13839                 error "create $DIR/$tdir/$tfile failed"
13840
13841         # check changelogs have been generated
13842         local nbcl=$(changelog_dump | wc -l)
13843         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13844
13845         # reduce the max_idle_indexes value to make sure we exceed it
13846         max_ndx=$((nbcl / 2 - 1))
13847
13848         for param in "changelog_max_idle_indexes=$max_ndx" \
13849                      "changelog_gc=1" \
13850                      "changelog_min_gc_interval=2" \
13851                      "changelog_min_free_cat_entries=3"; do
13852                 local MDT0=$(facet_svc $SINGLEMDS)
13853                 local var="${param%=*}"
13854                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
13855
13856                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
13857                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
13858                         error "unable to set mdd.*.$param"
13859         done
13860
13861         # simulate changelog catalog almost full
13862         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
13863         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
13864
13865         for i in $(seq $MDSCOUNT); do
13866                 cl_users=(${CL_USERS[mds$i]})
13867                 cl_user1[mds$i]="${cl_users[0]}"
13868                 cl_user2[mds$i]="${cl_users[1]}"
13869
13870                 [ -n "${cl_user1[mds$i]}" ] ||
13871                         error "mds$i: no user registered"
13872                 [ -n "${cl_user2[mds$i]}" ] ||
13873                         error "mds$i: only ${cl_user1[mds$i]} is registered"
13874
13875                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13876                 [ -n "$user_rec1" ] ||
13877                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13878                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
13879                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13880                 [ -n "$user_rec2" ] ||
13881                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13882                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
13883                      "$user_rec1 + 2 == $user_rec2"
13884                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
13885                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
13886                               "$user_rec1 + 2, but is $user_rec2"
13887                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
13888                 [ -n "$user_rec2" ] ||
13889                         error "mds$i: User ${cl_user2[mds$i]} not registered"
13890                 [ $user_rec1 == $user_rec2 ] ||
13891                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
13892                               "$user_rec1, but is $user_rec2"
13893         done
13894
13895         # ensure we are past the previous changelog_min_gc_interval set above
13896         sleep 2
13897
13898         # generate one more changelog to trigger fail_loc
13899         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13900                 error "create $DIR/$tdir/${tfile}bis failed"
13901
13902         # ensure gc thread is done
13903         for i in $(mdts_nodes); do
13904                 wait_update $i \
13905                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
13906                         error "$i: GC-thread not done"
13907         done
13908
13909         local first_rec
13910         for i in $(seq $MDSCOUNT); do
13911                 # check cl_user1 still registered
13912                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
13913                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13914                 # check cl_user2 unregistered
13915                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
13916                         error "mds$i: User ${cl_user2[mds$i]} still registered"
13917
13918                 # check changelogs are present and starting at $user_rec1 + 1
13919                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13920                 [ -n "$user_rec1" ] ||
13921                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13922                 first_rec=$($LFS changelog $(facet_svc mds$i) |
13923                             awk '{ print $1; exit; }')
13924
13925                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
13926                 [ $((user_rec1 + 1)) == $first_rec ] ||
13927                         error "mds$i: first index should be $user_rec1 + 1, " \
13928                               "but is $first_rec"
13929         done
13930 }
13931 run_test 160g "changelog garbage collect (old users)"
13932
13933 test_160h() {
13934         remote_mds_nodsh && skip "remote MDS with nodsh" && return
13935         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
13936                 skip "Need MDS version at least 2.10.56"
13937
13938         local mdts=$(comma_list $(mdts_nodes))
13939
13940         # Create a user
13941         changelog_register || error "first changelog_register failed"
13942         changelog_register || error "second changelog_register failed"
13943         local cl_users
13944         declare -A cl_user1
13945         declare -A cl_user2
13946         local user_rec1
13947         local user_rec2
13948         local i
13949
13950         # generate some changelog records to accumulate on each MDT
13951         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "test_mkdir $tdir failed"
13952         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13953                 error "create $DIR/$tdir/$tfile failed"
13954
13955         # check changelogs have been generated
13956         local nbcl=$(changelog_dump | wc -l)
13957         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13958
13959         for param in "changelog_max_idle_time=10" \
13960                      "changelog_gc=1" \
13961                      "changelog_min_gc_interval=2"; do
13962                 local MDT0=$(facet_svc $SINGLEMDS)
13963                 local var="${param%=*}"
13964                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
13965
13966                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
13967                 do_nodes $mdts $LCTL set_param mdd.*.$param
13968         done
13969
13970         # force cl_user2 to be idle (1st part)
13971         sleep 9
13972
13973         for i in $(seq $MDSCOUNT); do
13974                 cl_users=(${CL_USERS[mds$i]})
13975                 cl_user1[mds$i]="${cl_users[0]}"
13976                 cl_user2[mds$i]="${cl_users[1]}"
13977
13978                 [ -n "${cl_user1[mds$i]}" ] ||
13979                         error "mds$i: no user registered"
13980                 [ -n "${cl_user2[mds$i]}" ] ||
13981                         error "mds$i: only ${cl_user2[mds$i]} is registered"
13982
13983                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13984                 [ -n "$user_rec1" ] ||
13985                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13986                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
13987                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13988                 [ -n "$user_rec2" ] ||
13989                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13990                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
13991                      "$user_rec1 + 2 == $user_rec2"
13992                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
13993                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
13994                               "$user_rec1 + 2, but is $user_rec2"
13995                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
13996                 [ -n "$user_rec2" ] ||
13997                         error "mds$i: User ${cl_user2[mds$i]} not registered"
13998                 [ $user_rec1 == $user_rec2 ] ||
13999                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14000                               "$user_rec1, but is $user_rec2"
14001         done
14002
14003         # force cl_user2 to be idle (2nd part) and to reach
14004         # changelog_max_idle_time
14005         sleep 2
14006
14007         # force each GC-thread start and block then
14008         # one per MDT/MDD, set fail_val accordingly
14009         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
14010         do_nodes $mdts $LCTL set_param fail_loc=0x1316
14011
14012         # generate more changelogs to trigger fail_loc
14013         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14014                 error "create $DIR/$tdir/${tfile}bis failed"
14015
14016         # stop MDT to stop GC-thread, should be done in back-ground as it will
14017         # block waiting for the thread to be released and exit
14018         declare -A stop_pids
14019         for i in $(seq $MDSCOUNT); do
14020                 stop mds$i &
14021                 stop_pids[mds$i]=$!
14022         done
14023
14024         for i in $(mdts_nodes); do
14025                 local facet
14026                 local nb=0
14027                 local facets=$(facets_up_on_host $i)
14028
14029                 for facet in ${facets//,/ }; do
14030                         if [[ $facet == mds* ]]; then
14031                                 nb=$((nb + 1))
14032                         fi
14033                 done
14034                 # ensure each MDS's gc threads are still present and all in "R"
14035                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
14036                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
14037                         error "$i: expected $nb GC-thread"
14038                 wait_update $i \
14039                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
14040                         "R" 20 ||
14041                         error "$i: GC-thread not found in R-state"
14042                 # check umounts of each MDT on MDS have reached kthread_stop()
14043                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
14044                         error "$i: expected $nb umount"
14045                 wait_update $i \
14046                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
14047                         error "$i: umount not found in D-state"
14048         done
14049
14050         # release all GC-threads
14051         do_nodes $mdts $LCTL set_param fail_loc=0
14052
14053         # wait for MDT stop to complete
14054         for i in $(seq $MDSCOUNT); do
14055                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
14056         done
14057
14058         # XXX
14059         # may try to check if any orphan changelog records are present
14060         # via ldiskfs/zfs and llog_reader...
14061
14062         # re-start/mount MDTs
14063         for i in $(seq $MDSCOUNT); do
14064                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
14065                         error "Fail to start mds$i"
14066         done
14067
14068         local first_rec
14069         for i in $(seq $MDSCOUNT); do
14070                 # check cl_user1 still registered
14071                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14072                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14073                 # check cl_user2 unregistered
14074                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14075                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14076
14077                 # check changelogs are present and starting at $user_rec1 + 1
14078                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14079                 [ -n "$user_rec1" ] ||
14080                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14081                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14082                             awk '{ print $1; exit; }')
14083
14084                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14085                 [ $((user_rec1 + 1)) == $first_rec ] ||
14086                         error "mds$i: first index should be $user_rec1 + 1, " \
14087                               "but is $first_rec"
14088         done
14089 }
14090 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
14091               "during mount"
14092
14093 test_160i() {
14094
14095         local mdts=$(comma_list $(mdts_nodes))
14096
14097         changelog_register || error "first changelog_register failed"
14098
14099         # generate some changelog records to accumulate on each MDT
14100         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
14101         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14102                 error "create $DIR/$tdir/$tfile failed"
14103
14104         # check changelogs have been generated
14105         local nbcl=$(changelog_dump | wc -l)
14106         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14107
14108         # simulate race between register and unregister
14109         # XXX as fail_loc is set per-MDS, with DNE configs the race
14110         # simulation will only occur for one MDT per MDS and for the
14111         # others the normal race scenario will take place
14112         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
14113         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
14114         do_nodes $mdts $LCTL set_param fail_val=1
14115
14116         # unregister 1st user
14117         changelog_deregister &
14118         local pid1=$!
14119         # wait some time for deregister work to reach race rdv
14120         sleep 2
14121         # register 2nd user
14122         changelog_register || error "2nd user register failed"
14123
14124         wait $pid1 || error "1st user deregister failed"
14125
14126         local i
14127         local last_rec
14128         declare -A LAST_REC
14129         for i in $(seq $MDSCOUNT); do
14130                 if changelog_users mds$i | grep "^cl"; then
14131                         # make sure new records are added with one user present
14132                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
14133                                           awk '/^current.index:/ { print $NF }')
14134                 else
14135                         error "mds$i has no user registered"
14136                 fi
14137         done
14138
14139         # generate more changelog records to accumulate on each MDT
14140         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14141                 error "create $DIR/$tdir/${tfile}bis failed"
14142
14143         for i in $(seq $MDSCOUNT); do
14144                 last_rec=$(changelog_users $SINGLEMDS |
14145                            awk '/^current.index:/ { print $NF }')
14146                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
14147                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
14148                         error "changelogs are off on mds$i"
14149         done
14150 }
14151 run_test 160i "changelog user register/unregister race"
14152
14153 test_160j() {
14154         remote_mds_nodsh && skip "remote MDS with nodsh"
14155         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
14156                 skip "Need MDS version at least 2.12.56"
14157
14158         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
14159
14160         changelog_register || error "first changelog_register failed"
14161
14162         # generate some changelog
14163         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
14164         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14165                 error "create $DIR/$tdir/${tfile}bis failed"
14166
14167         # open the changelog device
14168         exec 3>/dev/changelog-$FSNAME-MDT0000
14169         exec 4</dev/changelog-$FSNAME-MDT0000
14170
14171         # umount the first lustre mount
14172         umount $MOUNT
14173
14174         # read changelog
14175         cat <&4 >/dev/null || error "read changelog failed"
14176
14177         # clear changelog
14178         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14179         changelog_users $SINGLEMDS | grep -q $cl_user ||
14180                 error "User $cl_user not found in changelog_users"
14181
14182         printf 'clear:'$cl_user':0' >&3
14183
14184         # close
14185         exec 3>&-
14186         exec 4<&-
14187
14188         # cleanup
14189         changelog_deregister || error "changelog_deregister failed"
14190
14191         umount $MOUNT2
14192         mount_client $MOUNT || error "mount_client on $MOUNT failed"
14193 }
14194 run_test 160j "client can be umounted  while its chanangelog is being used"
14195
14196 test_160k() {
14197         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14198         remote_mds_nodsh && skip "remote MDS with nodsh"
14199
14200         mkdir -p $DIR/$tdir/1/1
14201
14202         changelog_register || error "changelog_register failed"
14203         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14204
14205         changelog_users $SINGLEMDS | grep -q $cl_user ||
14206                 error "User '$cl_user' not found in changelog_users"
14207 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
14208         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
14209         rmdir $DIR/$tdir/1/1 & sleep 1
14210         mkdir $DIR/$tdir/2
14211         touch $DIR/$tdir/2/2
14212         rm -rf $DIR/$tdir/2
14213
14214         wait
14215         sleep 4
14216
14217         changelog_dump | grep rmdir || error "rmdir not recorded"
14218
14219         rm -rf $DIR/$tdir
14220         changelog_deregister
14221 }
14222 run_test 160k "Verify that changelog records are not lost"
14223
14224 test_161a() {
14225         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14226
14227         test_mkdir -c1 $DIR/$tdir
14228         cp /etc/hosts $DIR/$tdir/$tfile
14229         test_mkdir -c1 $DIR/$tdir/foo1
14230         test_mkdir -c1 $DIR/$tdir/foo2
14231         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
14232         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
14233         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
14234         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
14235         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
14236         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
14237                 $LFS fid2path $DIR $FID
14238                 error "bad link ea"
14239         fi
14240         # middle
14241         rm $DIR/$tdir/foo2/zachary
14242         # last
14243         rm $DIR/$tdir/foo2/thor
14244         # first
14245         rm $DIR/$tdir/$tfile
14246         # rename
14247         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
14248         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
14249                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
14250         rm $DIR/$tdir/foo2/maggie
14251
14252         # overflow the EA
14253         local longname=$tfile.avg_len_is_thirty_two_
14254         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
14255                 error_noexit 'failed to unlink many hardlinks'" EXIT
14256         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
14257                 error "failed to hardlink many files"
14258         links=$($LFS fid2path $DIR $FID | wc -l)
14259         echo -n "${links}/1000 links in link EA"
14260         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
14261 }
14262 run_test 161a "link ea sanity"
14263
14264 test_161b() {
14265         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14266         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
14267
14268         local MDTIDX=1
14269         local remote_dir=$DIR/$tdir/remote_dir
14270
14271         mkdir -p $DIR/$tdir
14272         $LFS mkdir -i $MDTIDX $remote_dir ||
14273                 error "create remote directory failed"
14274
14275         cp /etc/hosts $remote_dir/$tfile
14276         mkdir -p $remote_dir/foo1
14277         mkdir -p $remote_dir/foo2
14278         ln $remote_dir/$tfile $remote_dir/foo1/sofia
14279         ln $remote_dir/$tfile $remote_dir/foo2/zachary
14280         ln $remote_dir/$tfile $remote_dir/foo1/luna
14281         ln $remote_dir/$tfile $remote_dir/foo2/thor
14282
14283         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
14284                      tr -d ']')
14285         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
14286                 $LFS fid2path $DIR $FID
14287                 error "bad link ea"
14288         fi
14289         # middle
14290         rm $remote_dir/foo2/zachary
14291         # last
14292         rm $remote_dir/foo2/thor
14293         # first
14294         rm $remote_dir/$tfile
14295         # rename
14296         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
14297         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
14298         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
14299                 $LFS fid2path $DIR $FID
14300                 error "bad link rename"
14301         fi
14302         rm $remote_dir/foo2/maggie
14303
14304         # overflow the EA
14305         local longname=filename_avg_len_is_thirty_two_
14306         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
14307                 error "failed to hardlink many files"
14308         links=$($LFS fid2path $DIR $FID | wc -l)
14309         echo -n "${links}/1000 links in link EA"
14310         [[ ${links} -gt 60 ]] ||
14311                 error "expected at least 60 links in link EA"
14312         unlinkmany $remote_dir/foo2/$longname 1000 ||
14313         error "failed to unlink many hardlinks"
14314 }
14315 run_test 161b "link ea sanity under remote directory"
14316
14317 test_161c() {
14318         remote_mds_nodsh && skip "remote MDS with nodsh"
14319         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14320         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
14321                 skip "Need MDS version at least 2.1.5"
14322
14323         # define CLF_RENAME_LAST 0x0001
14324         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
14325         changelog_register || error "changelog_register failed"
14326
14327         rm -rf $DIR/$tdir
14328         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
14329         touch $DIR/$tdir/foo_161c
14330         touch $DIR/$tdir/bar_161c
14331         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
14332         changelog_dump | grep RENME | tail -n 5
14333         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
14334         changelog_clear 0 || error "changelog_clear failed"
14335         if [ x$flags != "x0x1" ]; then
14336                 error "flag $flags is not 0x1"
14337         fi
14338
14339         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
14340         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
14341         touch $DIR/$tdir/foo_161c
14342         touch $DIR/$tdir/bar_161c
14343         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
14344         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
14345         changelog_dump | grep RENME | tail -n 5
14346         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
14347         changelog_clear 0 || error "changelog_clear failed"
14348         if [ x$flags != "x0x0" ]; then
14349                 error "flag $flags is not 0x0"
14350         fi
14351         echo "rename overwrite a target having nlink > 1," \
14352                 "changelog record has flags of $flags"
14353
14354         # rename doesn't overwrite a target (changelog flag 0x0)
14355         touch $DIR/$tdir/foo_161c
14356         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
14357         changelog_dump | grep RENME | tail -n 5
14358         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
14359         changelog_clear 0 || error "changelog_clear failed"
14360         if [ x$flags != "x0x0" ]; then
14361                 error "flag $flags is not 0x0"
14362         fi
14363         echo "rename doesn't overwrite a target," \
14364                 "changelog record has flags of $flags"
14365
14366         # define CLF_UNLINK_LAST 0x0001
14367         # unlink a file having nlink = 1 (changelog flag 0x1)
14368         rm -f $DIR/$tdir/foo2_161c
14369         changelog_dump | grep UNLNK | tail -n 5
14370         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
14371         changelog_clear 0 || error "changelog_clear failed"
14372         if [ x$flags != "x0x1" ]; then
14373                 error "flag $flags is not 0x1"
14374         fi
14375         echo "unlink a file having nlink = 1," \
14376                 "changelog record has flags of $flags"
14377
14378         # unlink a file having nlink > 1 (changelog flag 0x0)
14379         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
14380         rm -f $DIR/$tdir/foobar_161c
14381         changelog_dump | grep UNLNK | tail -n 5
14382         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
14383         changelog_clear 0 || error "changelog_clear failed"
14384         if [ x$flags != "x0x0" ]; then
14385                 error "flag $flags is not 0x0"
14386         fi
14387         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
14388 }
14389 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
14390
14391 test_161d() {
14392         remote_mds_nodsh && skip "remote MDS with nodsh"
14393         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
14394
14395         local pid
14396         local fid
14397
14398         changelog_register || error "changelog_register failed"
14399
14400         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
14401         # interfer with $MOUNT/.lustre/fid/ access
14402         mkdir $DIR/$tdir
14403         [[ $? -eq 0 ]] || error "mkdir failed"
14404
14405         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
14406         $LCTL set_param fail_loc=0x8000140c
14407         # 5s pause
14408         $LCTL set_param fail_val=5
14409
14410         # create file
14411         echo foofoo > $DIR/$tdir/$tfile &
14412         pid=$!
14413
14414         # wait for create to be delayed
14415         sleep 2
14416
14417         ps -p $pid
14418         [[ $? -eq 0 ]] || error "create should be blocked"
14419
14420         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
14421         stack_trap "rm -f $tempfile"
14422         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
14423         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
14424         # some delay may occur during ChangeLog publishing and file read just
14425         # above, that could allow file write to happen finally
14426         [[ -s $tempfile ]] && echo "file should be empty"
14427
14428         $LCTL set_param fail_loc=0
14429
14430         wait $pid
14431         [[ $? -eq 0 ]] || error "create failed"
14432 }
14433 run_test 161d "create with concurrent .lustre/fid access"
14434
14435 check_path() {
14436         local expected="$1"
14437         shift
14438         local fid="$2"
14439
14440         local path
14441         path=$($LFS fid2path "$@")
14442         local rc=$?
14443
14444         if [ $rc -ne 0 ]; then
14445                 error "path looked up of '$expected' failed: rc=$rc"
14446         elif [ "$path" != "$expected" ]; then
14447                 error "path looked up '$path' instead of '$expected'"
14448         else
14449                 echo "FID '$fid' resolves to path '$path' as expected"
14450         fi
14451 }
14452
14453 test_162a() { # was test_162
14454         test_mkdir -p -c1 $DIR/$tdir/d2
14455         touch $DIR/$tdir/d2/$tfile
14456         touch $DIR/$tdir/d2/x1
14457         touch $DIR/$tdir/d2/x2
14458         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
14459         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
14460         # regular file
14461         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
14462         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
14463
14464         # softlink
14465         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
14466         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
14467         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
14468
14469         # softlink to wrong file
14470         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
14471         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
14472         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
14473
14474         # hardlink
14475         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
14476         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
14477         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
14478         # fid2path dir/fsname should both work
14479         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
14480         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
14481
14482         # hardlink count: check that there are 2 links
14483         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
14484         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
14485
14486         # hardlink indexing: remove the first link
14487         rm $DIR/$tdir/d2/p/q/r/hlink
14488         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
14489 }
14490 run_test 162a "path lookup sanity"
14491
14492 test_162b() {
14493         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14494         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14495
14496         mkdir $DIR/$tdir
14497         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
14498                                 error "create striped dir failed"
14499
14500         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
14501                                         tail -n 1 | awk '{print $2}')
14502         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
14503
14504         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
14505         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
14506
14507         # regular file
14508         for ((i=0;i<5;i++)); do
14509                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
14510                         error "get fid for f$i failed"
14511                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
14512
14513                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
14514                         error "get fid for d$i failed"
14515                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
14516         done
14517
14518         return 0
14519 }
14520 run_test 162b "striped directory path lookup sanity"
14521
14522 # LU-4239: Verify fid2path works with paths 100 or more directories deep
14523 test_162c() {
14524         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
14525                 skip "Need MDS version at least 2.7.51"
14526
14527         local lpath=$tdir.local
14528         local rpath=$tdir.remote
14529
14530         test_mkdir $DIR/$lpath
14531         test_mkdir $DIR/$rpath
14532
14533         for ((i = 0; i <= 101; i++)); do
14534                 lpath="$lpath/$i"
14535                 mkdir $DIR/$lpath
14536                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
14537                         error "get fid for local directory $DIR/$lpath failed"
14538                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
14539
14540                 rpath="$rpath/$i"
14541                 test_mkdir $DIR/$rpath
14542                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
14543                         error "get fid for remote directory $DIR/$rpath failed"
14544                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
14545         done
14546
14547         return 0
14548 }
14549 run_test 162c "fid2path works with paths 100 or more directories deep"
14550
14551 test_169() {
14552         # do directio so as not to populate the page cache
14553         log "creating a 10 Mb file"
14554         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
14555         log "starting reads"
14556         dd if=$DIR/$tfile of=/dev/null bs=4096 &
14557         log "truncating the file"
14558         $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
14559         log "killing dd"
14560         kill %+ || true # reads might have finished
14561         echo "wait until dd is finished"
14562         wait
14563         log "removing the temporary file"
14564         rm -rf $DIR/$tfile || error "tmp file removal failed"
14565 }
14566 run_test 169 "parallel read and truncate should not deadlock"
14567
14568 test_170() {
14569         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14570
14571         $LCTL clear     # bug 18514
14572         $LCTL debug_daemon start $TMP/${tfile}_log_good
14573         touch $DIR/$tfile
14574         $LCTL debug_daemon stop
14575         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
14576                 error "sed failed to read log_good"
14577
14578         $LCTL debug_daemon start $TMP/${tfile}_log_good
14579         rm -rf $DIR/$tfile
14580         $LCTL debug_daemon stop
14581
14582         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
14583                error "lctl df log_bad failed"
14584
14585         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
14586         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
14587
14588         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
14589         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
14590
14591         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
14592                 error "bad_line good_line1 good_line2 are empty"
14593
14594         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
14595         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
14596         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
14597
14598         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
14599         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
14600         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
14601
14602         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
14603                 error "bad_line_new good_line_new are empty"
14604
14605         local expected_good=$((good_line1 + good_line2*2))
14606
14607         rm -f $TMP/${tfile}*
14608         # LU-231, short malformed line may not be counted into bad lines
14609         if [ $bad_line -ne $bad_line_new ] &&
14610                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
14611                 error "expected $bad_line bad lines, but got $bad_line_new"
14612                 return 1
14613         fi
14614
14615         if [ $expected_good -ne $good_line_new ]; then
14616                 error "expected $expected_good good lines, but got $good_line_new"
14617                 return 2
14618         fi
14619         true
14620 }
14621 run_test 170 "test lctl df to handle corrupted log ====================="
14622
14623 test_171() { # bug20592
14624         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14625
14626         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
14627         $LCTL set_param fail_loc=0x50e
14628         $LCTL set_param fail_val=3000
14629         multiop_bg_pause $DIR/$tfile O_s || true
14630         local MULTIPID=$!
14631         kill -USR1 $MULTIPID
14632         # cause log dump
14633         sleep 3
14634         wait $MULTIPID
14635         if dmesg | grep "recursive fault"; then
14636                 error "caught a recursive fault"
14637         fi
14638         $LCTL set_param fail_loc=0
14639         true
14640 }
14641 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
14642
14643 # it would be good to share it with obdfilter-survey/iokit-libecho code
14644 setup_obdecho_osc () {
14645         local rc=0
14646         local ost_nid=$1
14647         local obdfilter_name=$2
14648         echo "Creating new osc for $obdfilter_name on $ost_nid"
14649         # make sure we can find loopback nid
14650         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
14651
14652         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
14653                            ${obdfilter_name}_osc_UUID || rc=2; }
14654         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
14655                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
14656         return $rc
14657 }
14658
14659 cleanup_obdecho_osc () {
14660         local obdfilter_name=$1
14661         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
14662         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
14663         return 0
14664 }
14665
14666 obdecho_test() {
14667         local OBD=$1
14668         local node=$2
14669         local pages=${3:-64}
14670         local rc=0
14671         local id
14672
14673         local count=10
14674         local obd_size=$(get_obd_size $node $OBD)
14675         local page_size=$(get_page_size $node)
14676         if [[ -n "$obd_size" ]]; then
14677                 local new_count=$((obd_size / (pages * page_size / 1024)))
14678                 [[ $new_count -ge $count ]] || count=$new_count
14679         fi
14680
14681         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
14682         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
14683                            rc=2; }
14684         if [ $rc -eq 0 ]; then
14685             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
14686             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
14687         fi
14688         echo "New object id is $id"
14689         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
14690                            rc=4; }
14691         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
14692                            "test_brw $count w v $pages $id" || rc=4; }
14693         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
14694                            rc=4; }
14695         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
14696                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
14697         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
14698                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
14699         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
14700         return $rc
14701 }
14702
14703 test_180a() {
14704         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14705
14706         if ! module_loaded obdecho; then
14707                 load_module obdecho/obdecho &&
14708                         stack_trap "rmmod obdecho" EXIT ||
14709                         error "unable to load obdecho on client"
14710         fi
14711
14712         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
14713         local host=$($LCTL get_param -n osc.$osc.import |
14714                      awk '/current_connection:/ { print $2 }' )
14715         local target=$($LCTL get_param -n osc.$osc.import |
14716                        awk '/target:/ { print $2 }' )
14717         target=${target%_UUID}
14718
14719         if [ -n "$target" ]; then
14720                 setup_obdecho_osc $host $target &&
14721                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
14722                         { error "obdecho setup failed with $?"; return; }
14723
14724                 obdecho_test ${target}_osc client ||
14725                         error "obdecho_test failed on ${target}_osc"
14726         else
14727                 $LCTL get_param osc.$osc.import
14728                 error "there is no osc.$osc.import target"
14729         fi
14730 }
14731 run_test 180a "test obdecho on osc"
14732
14733 test_180b() {
14734         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14735         remote_ost_nodsh && skip "remote OST with nodsh"
14736
14737         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
14738                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
14739                 error "failed to load module obdecho"
14740
14741         local target=$(do_facet ost1 $LCTL dl |
14742                        awk '/obdfilter/ { print $4; exit; }')
14743
14744         if [ -n "$target" ]; then
14745                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
14746         else
14747                 do_facet ost1 $LCTL dl
14748                 error "there is no obdfilter target on ost1"
14749         fi
14750 }
14751 run_test 180b "test obdecho directly on obdfilter"
14752
14753 test_180c() { # LU-2598
14754         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14755         remote_ost_nodsh && skip "remote OST with nodsh"
14756         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
14757                 skip "Need MDS version at least 2.4.0"
14758
14759         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
14760                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
14761                 error "failed to load module obdecho"
14762
14763         local target=$(do_facet ost1 $LCTL dl |
14764                        awk '/obdfilter/ { print $4; exit; }')
14765
14766         if [ -n "$target" ]; then
14767                 local pages=16384 # 64MB bulk I/O RPC size
14768
14769                 obdecho_test "$target" ost1 "$pages" ||
14770                         error "obdecho_test with pages=$pages failed with $?"
14771         else
14772                 do_facet ost1 $LCTL dl
14773                 error "there is no obdfilter target on ost1"
14774         fi
14775 }
14776 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
14777
14778 test_181() { # bug 22177
14779         test_mkdir $DIR/$tdir
14780         # create enough files to index the directory
14781         createmany -o $DIR/$tdir/foobar 4000
14782         # print attributes for debug purpose
14783         lsattr -d .
14784         # open dir
14785         multiop_bg_pause $DIR/$tdir D_Sc || return 1
14786         MULTIPID=$!
14787         # remove the files & current working dir
14788         unlinkmany $DIR/$tdir/foobar 4000
14789         rmdir $DIR/$tdir
14790         kill -USR1 $MULTIPID
14791         wait $MULTIPID
14792         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
14793         return 0
14794 }
14795 run_test 181 "Test open-unlinked dir ========================"
14796
14797 test_182() {
14798         local fcount=1000
14799         local tcount=10
14800
14801         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
14802
14803         $LCTL set_param mdc.*.rpc_stats=clear
14804
14805         for (( i = 0; i < $tcount; i++ )) ; do
14806                 mkdir $DIR/$tdir/$i
14807         done
14808
14809         for (( i = 0; i < $tcount; i++ )) ; do
14810                 createmany -o $DIR/$tdir/$i/f- $fcount &
14811         done
14812         wait
14813
14814         for (( i = 0; i < $tcount; i++ )) ; do
14815                 unlinkmany $DIR/$tdir/$i/f- $fcount &
14816         done
14817         wait
14818
14819         $LCTL get_param mdc.*.rpc_stats
14820
14821         rm -rf $DIR/$tdir
14822 }
14823 run_test 182 "Test parallel modify metadata operations ================"
14824
14825 test_183() { # LU-2275
14826         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14827         remote_mds_nodsh && skip "remote MDS with nodsh"
14828         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
14829                 skip "Need MDS version at least 2.3.56"
14830
14831         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
14832         echo aaa > $DIR/$tdir/$tfile
14833
14834 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
14835         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
14836
14837         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
14838         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
14839
14840         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
14841
14842         # Flush negative dentry cache
14843         touch $DIR/$tdir/$tfile
14844
14845         # We are not checking for any leaked references here, they'll
14846         # become evident next time we do cleanup with module unload.
14847         rm -rf $DIR/$tdir
14848 }
14849 run_test 183 "No crash or request leak in case of strange dispositions ========"
14850
14851 # test suite 184 is for LU-2016, LU-2017
14852 test_184a() {
14853         check_swap_layouts_support
14854
14855         dir0=$DIR/$tdir/$testnum
14856         test_mkdir -p -c1 $dir0
14857         ref1=/etc/passwd
14858         ref2=/etc/group
14859         file1=$dir0/f1
14860         file2=$dir0/f2
14861         $LFS setstripe -c1 $file1
14862         cp $ref1 $file1
14863         $LFS setstripe -c2 $file2
14864         cp $ref2 $file2
14865         gen1=$($LFS getstripe -g $file1)
14866         gen2=$($LFS getstripe -g $file2)
14867
14868         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
14869         gen=$($LFS getstripe -g $file1)
14870         [[ $gen1 != $gen ]] ||
14871                 "Layout generation on $file1 does not change"
14872         gen=$($LFS getstripe -g $file2)
14873         [[ $gen2 != $gen ]] ||
14874                 "Layout generation on $file2 does not change"
14875
14876         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
14877         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
14878
14879         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
14880 }
14881 run_test 184a "Basic layout swap"
14882
14883 test_184b() {
14884         check_swap_layouts_support
14885
14886         dir0=$DIR/$tdir/$testnum
14887         mkdir -p $dir0 || error "creating dir $dir0"
14888         file1=$dir0/f1
14889         file2=$dir0/f2
14890         file3=$dir0/f3
14891         dir1=$dir0/d1
14892         dir2=$dir0/d2
14893         mkdir $dir1 $dir2
14894         $LFS setstripe -c1 $file1
14895         $LFS setstripe -c2 $file2
14896         $LFS setstripe -c1 $file3
14897         chown $RUNAS_ID $file3
14898         gen1=$($LFS getstripe -g $file1)
14899         gen2=$($LFS getstripe -g $file2)
14900
14901         $LFS swap_layouts $dir1 $dir2 &&
14902                 error "swap of directories layouts should fail"
14903         $LFS swap_layouts $dir1 $file1 &&
14904                 error "swap of directory and file layouts should fail"
14905         $RUNAS $LFS swap_layouts $file1 $file2 &&
14906                 error "swap of file we cannot write should fail"
14907         $LFS swap_layouts $file1 $file3 &&
14908                 error "swap of file with different owner should fail"
14909         /bin/true # to clear error code
14910 }
14911 run_test 184b "Forbidden layout swap (will generate errors)"
14912
14913 test_184c() {
14914         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
14915         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
14916         check_swap_layouts_support
14917
14918         local dir0=$DIR/$tdir/$testnum
14919         mkdir -p $dir0 || error "creating dir $dir0"
14920
14921         local ref1=$dir0/ref1
14922         local ref2=$dir0/ref2
14923         local file1=$dir0/file1
14924         local file2=$dir0/file2
14925         # create a file large enough for the concurrent test
14926         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
14927         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
14928         echo "ref file size: ref1($(stat -c %s $ref1))," \
14929              "ref2($(stat -c %s $ref2))"
14930
14931         cp $ref2 $file2
14932         dd if=$ref1 of=$file1 bs=16k &
14933         local DD_PID=$!
14934
14935         # Make sure dd starts to copy file
14936         while [ ! -f $file1 ]; do sleep 0.1; done
14937
14938         $LFS swap_layouts $file1 $file2
14939         local rc=$?
14940         wait $DD_PID
14941         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
14942         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
14943
14944         # how many bytes copied before swapping layout
14945         local copied=$(stat -c %s $file2)
14946         local remaining=$(stat -c %s $ref1)
14947         remaining=$((remaining - copied))
14948         echo "Copied $copied bytes before swapping layout..."
14949
14950         cmp -n $copied $file1 $ref2 | grep differ &&
14951                 error "Content mismatch [0, $copied) of ref2 and file1"
14952         cmp -n $copied $file2 $ref1 ||
14953                 error "Content mismatch [0, $copied) of ref1 and file2"
14954         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
14955                 error "Content mismatch [$copied, EOF) of ref1 and file1"
14956
14957         # clean up
14958         rm -f $ref1 $ref2 $file1 $file2
14959 }
14960 run_test 184c "Concurrent write and layout swap"
14961
14962 test_184d() {
14963         check_swap_layouts_support
14964         [ -z "$(which getfattr 2>/dev/null)" ] &&
14965                 skip_env "no getfattr command"
14966
14967         local file1=$DIR/$tdir/$tfile-1
14968         local file2=$DIR/$tdir/$tfile-2
14969         local file3=$DIR/$tdir/$tfile-3
14970         local lovea1
14971         local lovea2
14972
14973         mkdir -p $DIR/$tdir
14974         touch $file1 || error "create $file1 failed"
14975         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
14976                 error "create $file2 failed"
14977         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
14978                 error "create $file3 failed"
14979         lovea1=$(get_layout_param $file1)
14980
14981         $LFS swap_layouts $file2 $file3 ||
14982                 error "swap $file2 $file3 layouts failed"
14983         $LFS swap_layouts $file1 $file2 ||
14984                 error "swap $file1 $file2 layouts failed"
14985
14986         lovea2=$(get_layout_param $file2)
14987         echo "$lovea1"
14988         echo "$lovea2"
14989         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
14990
14991         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
14992         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
14993 }
14994 run_test 184d "allow stripeless layouts swap"
14995
14996 test_184e() {
14997         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
14998                 skip "Need MDS version at least 2.6.94"
14999         check_swap_layouts_support
15000         [ -z "$(which getfattr 2>/dev/null)" ] &&
15001                 skip_env "no getfattr command"
15002
15003         local file1=$DIR/$tdir/$tfile-1
15004         local file2=$DIR/$tdir/$tfile-2
15005         local file3=$DIR/$tdir/$tfile-3
15006         local lovea
15007
15008         mkdir -p $DIR/$tdir
15009         touch $file1 || error "create $file1 failed"
15010         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
15011                 error "create $file2 failed"
15012         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
15013                 error "create $file3 failed"
15014
15015         $LFS swap_layouts $file1 $file2 ||
15016                 error "swap $file1 $file2 layouts failed"
15017
15018         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
15019         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
15020
15021         echo 123 > $file1 || error "Should be able to write into $file1"
15022
15023         $LFS swap_layouts $file1 $file3 ||
15024                 error "swap $file1 $file3 layouts failed"
15025
15026         echo 123 > $file1 || error "Should be able to write into $file1"
15027
15028         rm -rf $file1 $file2 $file3
15029 }
15030 run_test 184e "Recreate layout after stripeless layout swaps"
15031
15032 test_184f() {
15033         # Create a file with name longer than sizeof(struct stat) ==
15034         # 144 to see if we can get chars from the file name to appear
15035         # in the returned striping. Note that 'f' == 0x66.
15036         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
15037
15038         mkdir -p $DIR/$tdir
15039         mcreate $DIR/$tdir/$file
15040         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
15041                 error "IOC_MDC_GETFILEINFO returned garbage striping"
15042         fi
15043 }
15044 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
15045
15046 test_185() { # LU-2441
15047         # LU-3553 - no volatile file support in old servers
15048         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
15049                 skip "Need MDS version at least 2.3.60"
15050
15051         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
15052         touch $DIR/$tdir/spoo
15053         local mtime1=$(stat -c "%Y" $DIR/$tdir)
15054         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
15055                 error "cannot create/write a volatile file"
15056         [ "$FILESET" == "" ] &&
15057         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
15058                 error "FID is still valid after close"
15059
15060         multiop_bg_pause $DIR/$tdir vVw4096_c
15061         local multi_pid=$!
15062
15063         local OLD_IFS=$IFS
15064         IFS=":"
15065         local fidv=($fid)
15066         IFS=$OLD_IFS
15067         # assume that the next FID for this client is sequential, since stdout
15068         # is unfortunately eaten by multiop_bg_pause
15069         local n=$((${fidv[1]} + 1))
15070         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
15071         if [ "$FILESET" == "" ]; then
15072                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
15073                         error "FID is missing before close"
15074         fi
15075         kill -USR1 $multi_pid
15076         # 1 second delay, so if mtime change we will see it
15077         sleep 1
15078         local mtime2=$(stat -c "%Y" $DIR/$tdir)
15079         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
15080 }
15081 run_test 185 "Volatile file support"
15082
15083 function create_check_volatile() {
15084         local idx=$1
15085         local tgt
15086
15087         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
15088         local PID=$!
15089         sleep 1
15090         local FID=$(cat /tmp/${tfile}.fid)
15091         [ "$FID" == "" ] && error "can't get FID for volatile"
15092         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
15093         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
15094         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
15095         kill -USR1 $PID
15096         wait
15097         sleep 1
15098         cancel_lru_locks mdc # flush opencache
15099         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
15100         return 0
15101 }
15102
15103 test_185a(){
15104         # LU-12516 - volatile creation via .lustre
15105         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
15106                 skip "Need MDS version at least 2.3.55"
15107
15108         create_check_volatile 0
15109         [ $MDSCOUNT -lt 2 ] && return 0
15110
15111         # DNE case
15112         create_check_volatile 1
15113
15114         return 0
15115 }
15116 run_test 185a "Volatile file creation in .lustre/fid/"
15117
15118 test_187a() {
15119         remote_mds_nodsh && skip "remote MDS with nodsh"
15120         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
15121                 skip "Need MDS version at least 2.3.0"
15122
15123         local dir0=$DIR/$tdir/$testnum
15124         mkdir -p $dir0 || error "creating dir $dir0"
15125
15126         local file=$dir0/file1
15127         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
15128         local dv1=$($LFS data_version $file)
15129         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
15130         local dv2=$($LFS data_version $file)
15131         [[ $dv1 != $dv2 ]] ||
15132                 error "data version did not change on write $dv1 == $dv2"
15133
15134         # clean up
15135         rm -f $file1
15136 }
15137 run_test 187a "Test data version change"
15138
15139 test_187b() {
15140         remote_mds_nodsh && skip "remote MDS with nodsh"
15141         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
15142                 skip "Need MDS version at least 2.3.0"
15143
15144         local dir0=$DIR/$tdir/$testnum
15145         mkdir -p $dir0 || error "creating dir $dir0"
15146
15147         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
15148         [[ ${DV[0]} != ${DV[1]} ]] ||
15149                 error "data version did not change on write"\
15150                       " ${DV[0]} == ${DV[1]}"
15151
15152         # clean up
15153         rm -f $file1
15154 }
15155 run_test 187b "Test data version change on volatile file"
15156
15157 test_200() {
15158         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15159         remote_mgs_nodsh && skip "remote MGS with nodsh"
15160         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15161
15162         local POOL=${POOL:-cea1}
15163         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
15164         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
15165         # Pool OST targets
15166         local first_ost=0
15167         local last_ost=$(($OSTCOUNT - 1))
15168         local ost_step=2
15169         local ost_list=$(seq $first_ost $ost_step $last_ost)
15170         local ost_range="$first_ost $last_ost $ost_step"
15171         local test_path=$POOL_ROOT/$POOL_DIR_NAME
15172         local file_dir=$POOL_ROOT/file_tst
15173         local subdir=$test_path/subdir
15174         local rc=0
15175
15176         while : ; do
15177                 # former test_200a test_200b
15178                 pool_add $POOL                          || { rc=$? ; break; }
15179                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
15180                 # former test_200c test_200d
15181                 mkdir -p $test_path
15182                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
15183                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
15184                 mkdir -p $subdir
15185                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
15186                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
15187                                                         || { rc=$? ; break; }
15188                 # former test_200e test_200f
15189                 local files=$((OSTCOUNT*3))
15190                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
15191                                                         || { rc=$? ; break; }
15192                 pool_create_files $POOL $file_dir $files "$ost_list" \
15193                                                         || { rc=$? ; break; }
15194                 # former test_200g test_200h
15195                 pool_lfs_df $POOL                       || { rc=$? ; break; }
15196                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
15197
15198                 # former test_201a test_201b test_201c
15199                 pool_remove_first_target $POOL          || { rc=$? ; break; }
15200
15201                 local f=$test_path/$tfile
15202                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
15203                 pool_remove $POOL $f                    || { rc=$? ; break; }
15204                 break
15205         done
15206
15207         destroy_test_pools
15208
15209         return $rc
15210 }
15211 run_test 200 "OST pools"
15212
15213 # usage: default_attr <count | size | offset>
15214 default_attr() {
15215         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
15216 }
15217
15218 # usage: check_default_stripe_attr
15219 check_default_stripe_attr() {
15220         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
15221         case $1 in
15222         --stripe-count|-c)
15223                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
15224         --stripe-size|-S)
15225                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
15226         --stripe-index|-i)
15227                 EXPECTED=-1;;
15228         *)
15229                 error "unknown getstripe attr '$1'"
15230         esac
15231
15232         [ $ACTUAL == $EXPECTED ] ||
15233                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
15234 }
15235
15236 test_204a() {
15237         test_mkdir $DIR/$tdir
15238         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
15239
15240         check_default_stripe_attr --stripe-count
15241         check_default_stripe_attr --stripe-size
15242         check_default_stripe_attr --stripe-index
15243 }
15244 run_test 204a "Print default stripe attributes"
15245
15246 test_204b() {
15247         test_mkdir $DIR/$tdir
15248         $LFS setstripe --stripe-count 1 $DIR/$tdir
15249
15250         check_default_stripe_attr --stripe-size
15251         check_default_stripe_attr --stripe-index
15252 }
15253 run_test 204b "Print default stripe size and offset"
15254
15255 test_204c() {
15256         test_mkdir $DIR/$tdir
15257         $LFS setstripe --stripe-size 65536 $DIR/$tdir
15258
15259         check_default_stripe_attr --stripe-count
15260         check_default_stripe_attr --stripe-index
15261 }
15262 run_test 204c "Print default stripe count and offset"
15263
15264 test_204d() {
15265         test_mkdir $DIR/$tdir
15266         $LFS setstripe --stripe-index 0 $DIR/$tdir
15267
15268         check_default_stripe_attr --stripe-count
15269         check_default_stripe_attr --stripe-size
15270 }
15271 run_test 204d "Print default stripe count and size"
15272
15273 test_204e() {
15274         test_mkdir $DIR/$tdir
15275         $LFS setstripe -d $DIR/$tdir
15276
15277         check_default_stripe_attr --stripe-count --raw
15278         check_default_stripe_attr --stripe-size --raw
15279         check_default_stripe_attr --stripe-index --raw
15280 }
15281 run_test 204e "Print raw stripe attributes"
15282
15283 test_204f() {
15284         test_mkdir $DIR/$tdir
15285         $LFS setstripe --stripe-count 1 $DIR/$tdir
15286
15287         check_default_stripe_attr --stripe-size --raw
15288         check_default_stripe_attr --stripe-index --raw
15289 }
15290 run_test 204f "Print raw stripe size and offset"
15291
15292 test_204g() {
15293         test_mkdir $DIR/$tdir
15294         $LFS setstripe --stripe-size 65536 $DIR/$tdir
15295
15296         check_default_stripe_attr --stripe-count --raw
15297         check_default_stripe_attr --stripe-index --raw
15298 }
15299 run_test 204g "Print raw stripe count and offset"
15300
15301 test_204h() {
15302         test_mkdir $DIR/$tdir
15303         $LFS setstripe --stripe-index 0 $DIR/$tdir
15304
15305         check_default_stripe_attr --stripe-count --raw
15306         check_default_stripe_attr --stripe-size --raw
15307 }
15308 run_test 204h "Print raw stripe count and size"
15309
15310 # Figure out which job scheduler is being used, if any,
15311 # or use a fake one
15312 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
15313         JOBENV=SLURM_JOB_ID
15314 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
15315         JOBENV=LSB_JOBID
15316 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
15317         JOBENV=PBS_JOBID
15318 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
15319         JOBENV=LOADL_STEP_ID
15320 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
15321         JOBENV=JOB_ID
15322 else
15323         $LCTL list_param jobid_name > /dev/null 2>&1
15324         if [ $? -eq 0 ]; then
15325                 JOBENV=nodelocal
15326         else
15327                 JOBENV=FAKE_JOBID
15328         fi
15329 fi
15330 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
15331
15332 verify_jobstats() {
15333         local cmd=($1)
15334         shift
15335         local facets="$@"
15336
15337 # we don't really need to clear the stats for this test to work, since each
15338 # command has a unique jobid, but it makes debugging easier if needed.
15339 #       for facet in $facets; do
15340 #               local dev=$(convert_facet2label $facet)
15341 #               # clear old jobstats
15342 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
15343 #       done
15344
15345         # use a new JobID for each test, or we might see an old one
15346         [ "$JOBENV" = "FAKE_JOBID" ] &&
15347                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
15348
15349         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
15350
15351         [ "$JOBENV" = "nodelocal" ] && {
15352                 FAKE_JOBID=id.$testnum.%e.$RANDOM
15353                 $LCTL set_param jobid_name=$FAKE_JOBID
15354                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
15355         }
15356
15357         log "Test: ${cmd[*]}"
15358         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
15359
15360         if [ $JOBENV = "FAKE_JOBID" ]; then
15361                 FAKE_JOBID=$JOBVAL ${cmd[*]}
15362         else
15363                 ${cmd[*]}
15364         fi
15365
15366         # all files are created on OST0000
15367         for facet in $facets; do
15368                 local stats="*.$(convert_facet2label $facet).job_stats"
15369
15370                 # strip out libtool wrappers for in-tree executables
15371                 if [ $(do_facet $facet lctl get_param $stats |
15372                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
15373                         do_facet $facet lctl get_param $stats
15374                         error "No jobstats for $JOBVAL found on $facet::$stats"
15375                 fi
15376         done
15377 }
15378
15379 jobstats_set() {
15380         local new_jobenv=$1
15381
15382         set_persistent_param_and_check client "jobid_var" \
15383                 "$FSNAME.sys.jobid_var" $new_jobenv
15384 }
15385
15386 test_205() { # Job stats
15387         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15388         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
15389                 skip "Need MDS version with at least 2.7.1"
15390         remote_mgs_nodsh && skip "remote MGS with nodsh"
15391         remote_mds_nodsh && skip "remote MDS with nodsh"
15392         remote_ost_nodsh && skip "remote OST with nodsh"
15393         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
15394                 skip "Server doesn't support jobstats"
15395         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
15396
15397         local old_jobenv=$($LCTL get_param -n jobid_var)
15398         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
15399
15400         if [[ $PERM_CMD == *"set_param -P"* ]]; then
15401                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
15402         else
15403                 stack_trap "do_facet mgs $PERM_CMD \
15404                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
15405         fi
15406         changelog_register
15407
15408         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
15409                                 mdt.*.job_cleanup_interval | head -n 1)
15410         local new_interval=5
15411         do_facet $SINGLEMDS \
15412                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
15413         stack_trap "do_facet $SINGLEMDS \
15414                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
15415         local start=$SECONDS
15416
15417         local cmd
15418         # mkdir
15419         cmd="mkdir $DIR/$tdir"
15420         verify_jobstats "$cmd" "$SINGLEMDS"
15421         # rmdir
15422         cmd="rmdir $DIR/$tdir"
15423         verify_jobstats "$cmd" "$SINGLEMDS"
15424         # mkdir on secondary MDT
15425         if [ $MDSCOUNT -gt 1 ]; then
15426                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
15427                 verify_jobstats "$cmd" "mds2"
15428         fi
15429         # mknod
15430         cmd="mknod $DIR/$tfile c 1 3"
15431         verify_jobstats "$cmd" "$SINGLEMDS"
15432         # unlink
15433         cmd="rm -f $DIR/$tfile"
15434         verify_jobstats "$cmd" "$SINGLEMDS"
15435         # create all files on OST0000 so verify_jobstats can find OST stats
15436         # open & close
15437         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
15438         verify_jobstats "$cmd" "$SINGLEMDS"
15439         # setattr
15440         cmd="touch $DIR/$tfile"
15441         verify_jobstats "$cmd" "$SINGLEMDS ost1"
15442         # write
15443         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
15444         verify_jobstats "$cmd" "ost1"
15445         # read
15446         cancel_lru_locks osc
15447         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
15448         verify_jobstats "$cmd" "ost1"
15449         # truncate
15450         cmd="$TRUNCATE $DIR/$tfile 0"
15451         verify_jobstats "$cmd" "$SINGLEMDS ost1"
15452         # rename
15453         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
15454         verify_jobstats "$cmd" "$SINGLEMDS"
15455         # jobstats expiry - sleep until old stats should be expired
15456         local left=$((new_interval + 5 - (SECONDS - start)))
15457         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
15458                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
15459                         "0" $left
15460         cmd="mkdir $DIR/$tdir.expire"
15461         verify_jobstats "$cmd" "$SINGLEMDS"
15462         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
15463             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
15464
15465         # Ensure that jobid are present in changelog (if supported by MDS)
15466         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
15467                 changelog_dump | tail -10
15468                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
15469                 [ $jobids -eq 9 ] ||
15470                         error "Wrong changelog jobid count $jobids != 9"
15471
15472                 # LU-5862
15473                 JOBENV="disable"
15474                 jobstats_set $JOBENV
15475                 touch $DIR/$tfile
15476                 changelog_dump | grep $tfile
15477                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
15478                 [ $jobids -eq 0 ] ||
15479                         error "Unexpected jobids when jobid_var=$JOBENV"
15480         fi
15481
15482         lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"
15483         JOBENV="JOBCOMPLEX"
15484         JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
15485
15486         verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
15487 }
15488 run_test 205 "Verify job stats"
15489
15490 # LU-1480, LU-1773 and LU-1657
15491 test_206() {
15492         mkdir -p $DIR/$tdir
15493         $LFS setstripe -c -1 $DIR/$tdir
15494 #define OBD_FAIL_LOV_INIT 0x1403
15495         $LCTL set_param fail_loc=0xa0001403
15496         $LCTL set_param fail_val=1
15497         touch $DIR/$tdir/$tfile || true
15498 }
15499 run_test 206 "fail lov_init_raid0() doesn't lbug"
15500
15501 test_207a() {
15502         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
15503         local fsz=`stat -c %s $DIR/$tfile`
15504         cancel_lru_locks mdc
15505
15506         # do not return layout in getattr intent
15507 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
15508         $LCTL set_param fail_loc=0x170
15509         local sz=`stat -c %s $DIR/$tfile`
15510
15511         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
15512
15513         rm -rf $DIR/$tfile
15514 }
15515 run_test 207a "can refresh layout at glimpse"
15516
15517 test_207b() {
15518         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
15519         local cksum=`md5sum $DIR/$tfile`
15520         local fsz=`stat -c %s $DIR/$tfile`
15521         cancel_lru_locks mdc
15522         cancel_lru_locks osc
15523
15524         # do not return layout in getattr intent
15525 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
15526         $LCTL set_param fail_loc=0x171
15527
15528         # it will refresh layout after the file is opened but before read issues
15529         echo checksum is "$cksum"
15530         echo "$cksum" |md5sum -c --quiet || error "file differs"
15531
15532         rm -rf $DIR/$tfile
15533 }
15534 run_test 207b "can refresh layout at open"
15535
15536 test_208() {
15537         # FIXME: in this test suite, only RD lease is used. This is okay
15538         # for now as only exclusive open is supported. After generic lease
15539         # is done, this test suite should be revised. - Jinshan
15540
15541         remote_mds_nodsh && skip "remote MDS with nodsh"
15542         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
15543                 skip "Need MDS version at least 2.4.52"
15544
15545         echo "==== test 1: verify get lease work"
15546         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
15547
15548         echo "==== test 2: verify lease can be broken by upcoming open"
15549         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
15550         local PID=$!
15551         sleep 1
15552
15553         $MULTIOP $DIR/$tfile oO_RDONLY:c
15554         kill -USR1 $PID && wait $PID || error "break lease error"
15555
15556         echo "==== test 3: verify lease can't be granted if an open already exists"
15557         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
15558         local PID=$!
15559         sleep 1
15560
15561         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
15562         kill -USR1 $PID && wait $PID || error "open file error"
15563
15564         echo "==== test 4: lease can sustain over recovery"
15565         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
15566         PID=$!
15567         sleep 1
15568
15569         fail mds1
15570
15571         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
15572
15573         echo "==== test 5: lease broken can't be regained by replay"
15574         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
15575         PID=$!
15576         sleep 1
15577
15578         # open file to break lease and then recovery
15579         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
15580         fail mds1
15581
15582         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
15583
15584         rm -f $DIR/$tfile
15585 }
15586 run_test 208 "Exclusive open"
15587
15588 test_209() {
15589         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
15590                 skip_env "must have disp_stripe"
15591
15592         touch $DIR/$tfile
15593         sync; sleep 5; sync;
15594
15595         echo 3 > /proc/sys/vm/drop_caches
15596         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
15597
15598         # open/close 500 times
15599         for i in $(seq 500); do
15600                 cat $DIR/$tfile
15601         done
15602
15603         echo 3 > /proc/sys/vm/drop_caches
15604         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
15605
15606         echo "before: $req_before, after: $req_after"
15607         [ $((req_after - req_before)) -ge 300 ] &&
15608                 error "open/close requests are not freed"
15609         return 0
15610 }
15611 run_test 209 "read-only open/close requests should be freed promptly"
15612
15613 test_212() {
15614         size=`date +%s`
15615         size=$((size % 8192 + 1))
15616         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
15617         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
15618         rm -f $DIR/f212 $DIR/f212.xyz
15619 }
15620 run_test 212 "Sendfile test ============================================"
15621
15622 test_213() {
15623         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
15624         cancel_lru_locks osc
15625         lctl set_param fail_loc=0x8000040f
15626         # generate a read lock
15627         cat $DIR/$tfile > /dev/null
15628         # write to the file, it will try to cancel the above read lock.
15629         cat /etc/hosts >> $DIR/$tfile
15630 }
15631 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
15632
15633 test_214() { # for bug 20133
15634         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
15635         for (( i=0; i < 340; i++ )) ; do
15636                 touch $DIR/$tdir/d214c/a$i
15637         done
15638
15639         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
15640         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
15641         ls $DIR/d214c || error "ls $DIR/d214c failed"
15642         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
15643         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
15644 }
15645 run_test 214 "hash-indexed directory test - bug 20133"
15646
15647 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
15648 create_lnet_proc_files() {
15649         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
15650 }
15651
15652 # counterpart of create_lnet_proc_files
15653 remove_lnet_proc_files() {
15654         rm -f $TMP/lnet_$1.sys
15655 }
15656
15657 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
15658 # 3rd arg as regexp for body
15659 check_lnet_proc_stats() {
15660         local l=$(cat "$TMP/lnet_$1" |wc -l)
15661         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
15662
15663         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
15664 }
15665
15666 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
15667 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
15668 # optional and can be regexp for 2nd line (lnet.routes case)
15669 check_lnet_proc_entry() {
15670         local blp=2          # blp stands for 'position of 1st line of body'
15671         [ -z "$5" ] || blp=3 # lnet.routes case
15672
15673         local l=$(cat "$TMP/lnet_$1" |wc -l)
15674         # subtracting one from $blp because the body can be empty
15675         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
15676
15677         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
15678                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
15679
15680         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
15681                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
15682
15683         # bail out if any unexpected line happened
15684         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
15685         [ "$?" != 0 ] || error "$2 misformatted"
15686 }
15687
15688 test_215() { # for bugs 18102, 21079, 21517
15689         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15690
15691         local N='(0|[1-9][0-9]*)'       # non-negative numeric
15692         local P='[1-9][0-9]*'           # positive numeric
15693         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
15694         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
15695         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
15696         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
15697
15698         local L1 # regexp for 1st line
15699         local L2 # regexp for 2nd line (optional)
15700         local BR # regexp for the rest (body)
15701
15702         # lnet.stats should look as 11 space-separated non-negative numerics
15703         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
15704         create_lnet_proc_files "stats"
15705         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
15706         remove_lnet_proc_files "stats"
15707
15708         # lnet.routes should look like this:
15709         # Routing disabled/enabled
15710         # net hops priority state router
15711         # where net is a string like tcp0, hops > 0, priority >= 0,
15712         # state is up/down,
15713         # router is a string like 192.168.1.1@tcp2
15714         L1="^Routing (disabled|enabled)$"
15715         L2="^net +hops +priority +state +router$"
15716         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
15717         create_lnet_proc_files "routes"
15718         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
15719         remove_lnet_proc_files "routes"
15720
15721         # lnet.routers should look like this:
15722         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
15723         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
15724         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
15725         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
15726         L1="^ref +rtr_ref +alive +router$"
15727         BR="^$P +$P +(up|down) +$NID$"
15728         create_lnet_proc_files "routers"
15729         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
15730         remove_lnet_proc_files "routers"
15731
15732         # lnet.peers should look like this:
15733         # nid refs state last max rtr min tx min queue
15734         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
15735         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
15736         # numeric (0 or >0 or <0), queue >= 0.
15737         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
15738         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
15739         create_lnet_proc_files "peers"
15740         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
15741         remove_lnet_proc_files "peers"
15742
15743         # lnet.buffers  should look like this:
15744         # pages count credits min
15745         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
15746         L1="^pages +count +credits +min$"
15747         BR="^ +$N +$N +$I +$I$"
15748         create_lnet_proc_files "buffers"
15749         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
15750         remove_lnet_proc_files "buffers"
15751
15752         # lnet.nis should look like this:
15753         # nid status alive refs peer rtr max tx min
15754         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
15755         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
15756         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
15757         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
15758         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
15759         create_lnet_proc_files "nis"
15760         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
15761         remove_lnet_proc_files "nis"
15762
15763         # can we successfully write to lnet.stats?
15764         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
15765 }
15766 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
15767
15768 test_216() { # bug 20317
15769         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15770         remote_ost_nodsh && skip "remote OST with nodsh"
15771
15772         local node
15773         local facets=$(get_facets OST)
15774         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15775
15776         save_lustre_params client "osc.*.contention_seconds" > $p
15777         save_lustre_params $facets \
15778                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
15779         save_lustre_params $facets \
15780                 "ldlm.namespaces.filter-*.contended_locks" >> $p
15781         save_lustre_params $facets \
15782                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
15783         clear_stats osc.*.osc_stats
15784
15785         # agressive lockless i/o settings
15786         do_nodes $(comma_list $(osts_nodes)) \
15787                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
15788                         ldlm.namespaces.filter-*.contended_locks=0 \
15789                         ldlm.namespaces.filter-*.contention_seconds=60"
15790         lctl set_param -n osc.*.contention_seconds=60
15791
15792         $DIRECTIO write $DIR/$tfile 0 10 4096
15793         $CHECKSTAT -s 40960 $DIR/$tfile
15794
15795         # disable lockless i/o
15796         do_nodes $(comma_list $(osts_nodes)) \
15797                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
15798                         ldlm.namespaces.filter-*.contended_locks=32 \
15799                         ldlm.namespaces.filter-*.contention_seconds=0"
15800         lctl set_param -n osc.*.contention_seconds=0
15801         clear_stats osc.*.osc_stats
15802
15803         dd if=/dev/zero of=$DIR/$tfile count=0
15804         $CHECKSTAT -s 0 $DIR/$tfile
15805
15806         restore_lustre_params <$p
15807         rm -f $p
15808         rm $DIR/$tfile
15809 }
15810 run_test 216 "check lockless direct write updates file size and kms correctly"
15811
15812 test_217() { # bug 22430
15813         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15814
15815         local node
15816         local nid
15817
15818         for node in $(nodes_list); do
15819                 nid=$(host_nids_address $node $NETTYPE)
15820                 if [[ $nid = *-* ]] ; then
15821                         echo "lctl ping $(h2nettype $nid)"
15822                         lctl ping $(h2nettype $nid)
15823                 else
15824                         echo "skipping $node (no hyphen detected)"
15825                 fi
15826         done
15827 }
15828 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
15829
15830 test_218() {
15831        # do directio so as not to populate the page cache
15832        log "creating a 10 Mb file"
15833        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
15834        log "starting reads"
15835        dd if=$DIR/$tfile of=/dev/null bs=4096 &
15836        log "truncating the file"
15837        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
15838        log "killing dd"
15839        kill %+ || true # reads might have finished
15840        echo "wait until dd is finished"
15841        wait
15842        log "removing the temporary file"
15843        rm -rf $DIR/$tfile || error "tmp file removal failed"
15844 }
15845 run_test 218 "parallel read and truncate should not deadlock"
15846
15847 test_219() {
15848         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15849
15850         # write one partial page
15851         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
15852         # set no grant so vvp_io_commit_write will do sync write
15853         $LCTL set_param fail_loc=0x411
15854         # write a full page at the end of file
15855         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
15856
15857         $LCTL set_param fail_loc=0
15858         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
15859         $LCTL set_param fail_loc=0x411
15860         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
15861
15862         # LU-4201
15863         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
15864         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
15865 }
15866 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
15867
15868 test_220() { #LU-325
15869         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15870         remote_ost_nodsh && skip "remote OST with nodsh"
15871         remote_mds_nodsh && skip "remote MDS with nodsh"
15872         remote_mgs_nodsh && skip "remote MGS with nodsh"
15873
15874         local OSTIDX=0
15875
15876         # create on MDT0000 so the last_id and next_id are correct
15877         mkdir $DIR/$tdir
15878         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
15879         OST=${OST%_UUID}
15880
15881         # on the mdt's osc
15882         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
15883         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
15884                         osp.$mdtosc_proc1.prealloc_last_id)
15885         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
15886                         osp.$mdtosc_proc1.prealloc_next_id)
15887
15888         $LFS df -i
15889
15890         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
15891         #define OBD_FAIL_OST_ENOINO              0x229
15892         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
15893         create_pool $FSNAME.$TESTNAME || return 1
15894         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
15895
15896         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
15897
15898         MDSOBJS=$((last_id - next_id))
15899         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
15900
15901         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
15902         echo "OST still has $count kbytes free"
15903
15904         echo "create $MDSOBJS files @next_id..."
15905         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
15906
15907         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
15908                         osp.$mdtosc_proc1.prealloc_last_id)
15909         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
15910                         osp.$mdtosc_proc1.prealloc_next_id)
15911
15912         echo "after creation, last_id=$last_id2, next_id=$next_id2"
15913         $LFS df -i
15914
15915         echo "cleanup..."
15916
15917         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
15918         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
15919
15920         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
15921                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
15922         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
15923                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
15924         echo "unlink $MDSOBJS files @$next_id..."
15925         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
15926 }
15927 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
15928
15929 test_221() {
15930         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15931
15932         dd if=`which date` of=$MOUNT/date oflag=sync
15933         chmod +x $MOUNT/date
15934
15935         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
15936         $LCTL set_param fail_loc=0x80001401
15937
15938         $MOUNT/date > /dev/null
15939         rm -f $MOUNT/date
15940 }
15941 run_test 221 "make sure fault and truncate race to not cause OOM"
15942
15943 test_222a () {
15944         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15945
15946         rm -rf $DIR/$tdir
15947         test_mkdir $DIR/$tdir
15948         $LFS setstripe -c 1 -i 0 $DIR/$tdir
15949         createmany -o $DIR/$tdir/$tfile 10
15950         cancel_lru_locks mdc
15951         cancel_lru_locks osc
15952         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
15953         $LCTL set_param fail_loc=0x31a
15954         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
15955         $LCTL set_param fail_loc=0
15956         rm -r $DIR/$tdir
15957 }
15958 run_test 222a "AGL for ls should not trigger CLIO lock failure"
15959
15960 test_222b () {
15961         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15962
15963         rm -rf $DIR/$tdir
15964         test_mkdir $DIR/$tdir
15965         $LFS setstripe -c 1 -i 0 $DIR/$tdir
15966         createmany -o $DIR/$tdir/$tfile 10
15967         cancel_lru_locks mdc
15968         cancel_lru_locks osc
15969         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
15970         $LCTL set_param fail_loc=0x31a
15971         rm -r $DIR/$tdir || error "AGL for rmdir failed"
15972         $LCTL set_param fail_loc=0
15973 }
15974 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
15975
15976 test_223 () {
15977         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15978
15979         rm -rf $DIR/$tdir
15980         test_mkdir $DIR/$tdir
15981         $LFS setstripe -c 1 -i 0 $DIR/$tdir
15982         createmany -o $DIR/$tdir/$tfile 10
15983         cancel_lru_locks mdc
15984         cancel_lru_locks osc
15985         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
15986         $LCTL set_param fail_loc=0x31b
15987         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
15988         $LCTL set_param fail_loc=0
15989         rm -r $DIR/$tdir
15990 }
15991 run_test 223 "osc reenqueue if without AGL lock granted ======================="
15992
15993 test_224a() { # LU-1039, MRP-303
15994         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15995
15996         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
15997         $LCTL set_param fail_loc=0x508
15998         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
15999         $LCTL set_param fail_loc=0
16000         df $DIR
16001 }
16002 run_test 224a "Don't panic on bulk IO failure"
16003
16004 test_224b() { # LU-1039, MRP-303
16005         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16006
16007         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
16008         cancel_lru_locks osc
16009         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
16010         $LCTL set_param fail_loc=0x515
16011         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
16012         $LCTL set_param fail_loc=0
16013         df $DIR
16014 }
16015 run_test 224b "Don't panic on bulk IO failure"
16016
16017 test_224c() { # LU-6441
16018         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16019         remote_mds_nodsh && skip "remote MDS with nodsh"
16020
16021         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16022         save_writethrough $p
16023         set_cache writethrough on
16024
16025         local pages_per_rpc=$($LCTL get_param \
16026                                 osc.*.max_pages_per_rpc)
16027         local at_max=$($LCTL get_param -n at_max)
16028         local timeout=$($LCTL get_param -n timeout)
16029         local test_at="at_max"
16030         local param_at="$FSNAME.sys.at_max"
16031         local test_timeout="timeout"
16032         local param_timeout="$FSNAME.sys.timeout"
16033
16034         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
16035
16036         set_persistent_param_and_check client "$test_at" "$param_at" 0
16037         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
16038
16039         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
16040         do_facet ost1 "$LCTL set_param fail_loc=0x520"
16041         $LFS setstripe -c 1 -i 0 $DIR/$tfile
16042         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
16043         sync
16044         do_facet ost1 "$LCTL set_param fail_loc=0"
16045
16046         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
16047         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
16048                 $timeout
16049
16050         $LCTL set_param -n $pages_per_rpc
16051         restore_lustre_params < $p
16052         rm -f $p
16053 }
16054 run_test 224c "Don't hang if one of md lost during large bulk RPC"
16055
16056 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
16057 test_225a () {
16058         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16059         if [ -z ${MDSSURVEY} ]; then
16060                 skip_env "mds-survey not found"
16061         fi
16062         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
16063                 skip "Need MDS version at least 2.2.51"
16064
16065         local mds=$(facet_host $SINGLEMDS)
16066         local target=$(do_nodes $mds 'lctl dl' |
16067                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
16068
16069         local cmd1="file_count=1000 thrhi=4"
16070         local cmd2="dir_count=2 layer=mdd stripe_count=0"
16071         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
16072         local cmd="$cmd1 $cmd2 $cmd3"
16073
16074         rm -f ${TMP}/mds_survey*
16075         echo + $cmd
16076         eval $cmd || error "mds-survey with zero-stripe failed"
16077         cat ${TMP}/mds_survey*
16078         rm -f ${TMP}/mds_survey*
16079 }
16080 run_test 225a "Metadata survey sanity with zero-stripe"
16081
16082 test_225b () {
16083         if [ -z ${MDSSURVEY} ]; then
16084                 skip_env "mds-survey not found"
16085         fi
16086         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
16087                 skip "Need MDS version at least 2.2.51"
16088         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16089         remote_mds_nodsh && skip "remote MDS with nodsh"
16090         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
16091                 skip_env "Need to mount OST to test"
16092         fi
16093
16094         local mds=$(facet_host $SINGLEMDS)
16095         local target=$(do_nodes $mds 'lctl dl' |
16096                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
16097
16098         local cmd1="file_count=1000 thrhi=4"
16099         local cmd2="dir_count=2 layer=mdd stripe_count=1"
16100         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
16101         local cmd="$cmd1 $cmd2 $cmd3"
16102
16103         rm -f ${TMP}/mds_survey*
16104         echo + $cmd
16105         eval $cmd || error "mds-survey with stripe_count failed"
16106         cat ${TMP}/mds_survey*
16107         rm -f ${TMP}/mds_survey*
16108 }
16109 run_test 225b "Metadata survey sanity with stripe_count = 1"
16110
16111 mcreate_path2fid () {
16112         local mode=$1
16113         local major=$2
16114         local minor=$3
16115         local name=$4
16116         local desc=$5
16117         local path=$DIR/$tdir/$name
16118         local fid
16119         local rc
16120         local fid_path
16121
16122         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
16123                 error "cannot create $desc"
16124
16125         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
16126         rc=$?
16127         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
16128
16129         fid_path=$($LFS fid2path $MOUNT $fid)
16130         rc=$?
16131         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
16132
16133         [ "$path" == "$fid_path" ] ||
16134                 error "fid2path returned $fid_path, expected $path"
16135
16136         echo "pass with $path and $fid"
16137 }
16138
16139 test_226a () {
16140         rm -rf $DIR/$tdir
16141         mkdir -p $DIR/$tdir
16142
16143         mcreate_path2fid 0010666 0 0 fifo "FIFO"
16144         mcreate_path2fid 0020666 1 3 null "character special file (null)"
16145         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
16146         mcreate_path2fid 0040666 0 0 dir "directory"
16147         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
16148         mcreate_path2fid 0100666 0 0 file "regular file"
16149         mcreate_path2fid 0120666 0 0 link "symbolic link"
16150         mcreate_path2fid 0140666 0 0 sock "socket"
16151 }
16152 run_test 226a "call path2fid and fid2path on files of all type"
16153
16154 test_226b () {
16155         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16156
16157         local MDTIDX=1
16158
16159         rm -rf $DIR/$tdir
16160         mkdir -p $DIR/$tdir
16161         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
16162                 error "create remote directory failed"
16163         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
16164         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
16165                                 "character special file (null)"
16166         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
16167                                 "character special file (no device)"
16168         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
16169         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
16170                                 "block special file (loop)"
16171         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
16172         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
16173         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
16174 }
16175 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
16176
16177 # LU-1299 Executing or running ldd on a truncated executable does not
16178 # cause an out-of-memory condition.
16179 test_227() {
16180         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16181         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
16182
16183         dd if=$(which date) of=$MOUNT/date bs=1k count=1
16184         chmod +x $MOUNT/date
16185
16186         $MOUNT/date > /dev/null
16187         ldd $MOUNT/date > /dev/null
16188         rm -f $MOUNT/date
16189 }
16190 run_test 227 "running truncated executable does not cause OOM"
16191
16192 # LU-1512 try to reuse idle OI blocks
16193 test_228a() {
16194         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16195         remote_mds_nodsh && skip "remote MDS with nodsh"
16196         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
16197
16198         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
16199         local myDIR=$DIR/$tdir
16200
16201         mkdir -p $myDIR
16202         #define OBD_FAIL_SEQ_EXHAUST             0x1002
16203         $LCTL set_param fail_loc=0x80001002
16204         createmany -o $myDIR/t- 10000
16205         $LCTL set_param fail_loc=0
16206         # The guard is current the largest FID holder
16207         touch $myDIR/guard
16208         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
16209                     tr -d '[')
16210         local IDX=$(($SEQ % 64))
16211
16212         do_facet $SINGLEMDS sync
16213         # Make sure journal flushed.
16214         sleep 6
16215         local blk1=$(do_facet $SINGLEMDS \
16216                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16217                      grep Blockcount | awk '{print $4}')
16218
16219         # Remove old files, some OI blocks will become idle.
16220         unlinkmany $myDIR/t- 10000
16221         # Create new files, idle OI blocks should be reused.
16222         createmany -o $myDIR/t- 2000
16223         do_facet $SINGLEMDS sync
16224         # Make sure journal flushed.
16225         sleep 6
16226         local blk2=$(do_facet $SINGLEMDS \
16227                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16228                      grep Blockcount | awk '{print $4}')
16229
16230         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
16231 }
16232 run_test 228a "try to reuse idle OI blocks"
16233
16234 test_228b() {
16235         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16236         remote_mds_nodsh && skip "remote MDS with nodsh"
16237         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
16238
16239         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
16240         local myDIR=$DIR/$tdir
16241
16242         mkdir -p $myDIR
16243         #define OBD_FAIL_SEQ_EXHAUST             0x1002
16244         $LCTL set_param fail_loc=0x80001002
16245         createmany -o $myDIR/t- 10000
16246         $LCTL set_param fail_loc=0
16247         # The guard is current the largest FID holder
16248         touch $myDIR/guard
16249         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
16250                     tr -d '[')
16251         local IDX=$(($SEQ % 64))
16252
16253         do_facet $SINGLEMDS sync
16254         # Make sure journal flushed.
16255         sleep 6
16256         local blk1=$(do_facet $SINGLEMDS \
16257                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16258                      grep Blockcount | awk '{print $4}')
16259
16260         # Remove old files, some OI blocks will become idle.
16261         unlinkmany $myDIR/t- 10000
16262
16263         # stop the MDT
16264         stop $SINGLEMDS || error "Fail to stop MDT."
16265         # remount the MDT
16266         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
16267
16268         df $MOUNT || error "Fail to df."
16269         # Create new files, idle OI blocks should be reused.
16270         createmany -o $myDIR/t- 2000
16271         do_facet $SINGLEMDS sync
16272         # Make sure journal flushed.
16273         sleep 6
16274         local blk2=$(do_facet $SINGLEMDS \
16275                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16276                      grep Blockcount | awk '{print $4}')
16277
16278         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
16279 }
16280 run_test 228b "idle OI blocks can be reused after MDT restart"
16281
16282 #LU-1881
16283 test_228c() {
16284         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16285         remote_mds_nodsh && skip "remote MDS with nodsh"
16286         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
16287
16288         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
16289         local myDIR=$DIR/$tdir
16290
16291         mkdir -p $myDIR
16292         #define OBD_FAIL_SEQ_EXHAUST             0x1002
16293         $LCTL set_param fail_loc=0x80001002
16294         # 20000 files can guarantee there are index nodes in the OI file
16295         createmany -o $myDIR/t- 20000
16296         $LCTL set_param fail_loc=0
16297         # The guard is current the largest FID holder
16298         touch $myDIR/guard
16299         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
16300                     tr -d '[')
16301         local IDX=$(($SEQ % 64))
16302
16303         do_facet $SINGLEMDS sync
16304         # Make sure journal flushed.
16305         sleep 6
16306         local blk1=$(do_facet $SINGLEMDS \
16307                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16308                      grep Blockcount | awk '{print $4}')
16309
16310         # Remove old files, some OI blocks will become idle.
16311         unlinkmany $myDIR/t- 20000
16312         rm -f $myDIR/guard
16313         # The OI file should become empty now
16314
16315         # Create new files, idle OI blocks should be reused.
16316         createmany -o $myDIR/t- 2000
16317         do_facet $SINGLEMDS sync
16318         # Make sure journal flushed.
16319         sleep 6
16320         local blk2=$(do_facet $SINGLEMDS \
16321                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16322                      grep Blockcount | awk '{print $4}')
16323
16324         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
16325 }
16326 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
16327
16328 test_229() { # LU-2482, LU-3448
16329         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16330         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
16331         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
16332                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
16333
16334         rm -f $DIR/$tfile
16335
16336         # Create a file with a released layout and stripe count 2.
16337         $MULTIOP $DIR/$tfile H2c ||
16338                 error "failed to create file with released layout"
16339
16340         $LFS getstripe -v $DIR/$tfile
16341
16342         local pattern=$($LFS getstripe -L $DIR/$tfile)
16343         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
16344
16345         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
16346                 error "getstripe"
16347         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
16348         stat $DIR/$tfile || error "failed to stat released file"
16349
16350         chown $RUNAS_ID $DIR/$tfile ||
16351                 error "chown $RUNAS_ID $DIR/$tfile failed"
16352
16353         chgrp $RUNAS_ID $DIR/$tfile ||
16354                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
16355
16356         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
16357         rm $DIR/$tfile || error "failed to remove released file"
16358 }
16359 run_test 229 "getstripe/stat/rm/attr changes work on released files"
16360
16361 test_230a() {
16362         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16363         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16364         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16365                 skip "Need MDS version at least 2.11.52"
16366
16367         local MDTIDX=1
16368
16369         test_mkdir $DIR/$tdir
16370         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
16371         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
16372         [ $mdt_idx -ne 0 ] &&
16373                 error "create local directory on wrong MDT $mdt_idx"
16374
16375         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
16376                         error "create remote directory failed"
16377         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
16378         [ $mdt_idx -ne $MDTIDX ] &&
16379                 error "create remote directory on wrong MDT $mdt_idx"
16380
16381         createmany -o $DIR/$tdir/test_230/t- 10 ||
16382                 error "create files on remote directory failed"
16383         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
16384         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
16385         rm -r $DIR/$tdir || error "unlink remote directory failed"
16386 }
16387 run_test 230a "Create remote directory and files under the remote directory"
16388
16389 test_230b() {
16390         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16391         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16392         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16393                 skip "Need MDS version at least 2.11.52"
16394
16395         local MDTIDX=1
16396         local mdt_index
16397         local i
16398         local file
16399         local pid
16400         local stripe_count
16401         local migrate_dir=$DIR/$tdir/migrate_dir
16402         local other_dir=$DIR/$tdir/other_dir
16403
16404         test_mkdir $DIR/$tdir
16405         test_mkdir -i0 -c1 $migrate_dir
16406         test_mkdir -i0 -c1 $other_dir
16407         for ((i=0; i<10; i++)); do
16408                 mkdir -p $migrate_dir/dir_${i}
16409                 createmany -o $migrate_dir/dir_${i}/f 10 ||
16410                         error "create files under remote dir failed $i"
16411         done
16412
16413         cp /etc/passwd $migrate_dir/$tfile
16414         cp /etc/passwd $other_dir/$tfile
16415         chattr +SAD $migrate_dir
16416         chattr +SAD $migrate_dir/$tfile
16417
16418         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
16419         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
16420         local old_dir_mode=$(stat -c%f $migrate_dir)
16421         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
16422
16423         mkdir -p $migrate_dir/dir_default_stripe2
16424         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
16425         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
16426
16427         mkdir -p $other_dir
16428         ln $migrate_dir/$tfile $other_dir/luna
16429         ln $migrate_dir/$tfile $migrate_dir/sofia
16430         ln $other_dir/$tfile $migrate_dir/david
16431         ln -s $migrate_dir/$tfile $other_dir/zachary
16432         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
16433         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
16434
16435         $LFS migrate -m $MDTIDX $migrate_dir ||
16436                 error "fails on migrating remote dir to MDT1"
16437
16438         echo "migratate to MDT1, then checking.."
16439         for ((i = 0; i < 10; i++)); do
16440                 for file in $(find $migrate_dir/dir_${i}); do
16441                         mdt_index=$($LFS getstripe -m $file)
16442                         [ $mdt_index == $MDTIDX ] ||
16443                                 error "$file is not on MDT${MDTIDX}"
16444                 done
16445         done
16446
16447         # the multiple link file should still in MDT0
16448         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
16449         [ $mdt_index == 0 ] ||
16450                 error "$file is not on MDT${MDTIDX}"
16451
16452         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
16453         [ "$old_dir_flag" = "$new_dir_flag" ] ||
16454                 error " expect $old_dir_flag get $new_dir_flag"
16455
16456         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
16457         [ "$old_file_flag" = "$new_file_flag" ] ||
16458                 error " expect $old_file_flag get $new_file_flag"
16459
16460         local new_dir_mode=$(stat -c%f $migrate_dir)
16461         [ "$old_dir_mode" = "$new_dir_mode" ] ||
16462                 error "expect mode $old_dir_mode get $new_dir_mode"
16463
16464         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
16465         [ "$old_file_mode" = "$new_file_mode" ] ||
16466                 error "expect mode $old_file_mode get $new_file_mode"
16467
16468         diff /etc/passwd $migrate_dir/$tfile ||
16469                 error "$tfile different after migration"
16470
16471         diff /etc/passwd $other_dir/luna ||
16472                 error "luna different after migration"
16473
16474         diff /etc/passwd $migrate_dir/sofia ||
16475                 error "sofia different after migration"
16476
16477         diff /etc/passwd $migrate_dir/david ||
16478                 error "david different after migration"
16479
16480         diff /etc/passwd $other_dir/zachary ||
16481                 error "zachary different after migration"
16482
16483         diff /etc/passwd $migrate_dir/${tfile}_ln ||
16484                 error "${tfile}_ln different after migration"
16485
16486         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
16487                 error "${tfile}_ln_other different after migration"
16488
16489         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
16490         [ $stripe_count = 2 ] ||
16491                 error "dir strpe_count $d != 2 after migration."
16492
16493         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
16494         [ $stripe_count = 2 ] ||
16495                 error "file strpe_count $d != 2 after migration."
16496
16497         #migrate back to MDT0
16498         MDTIDX=0
16499
16500         $LFS migrate -m $MDTIDX $migrate_dir ||
16501                 error "fails on migrating remote dir to MDT0"
16502
16503         echo "migrate back to MDT0, checking.."
16504         for file in $(find $migrate_dir); do
16505                 mdt_index=$($LFS getstripe -m $file)
16506                 [ $mdt_index == $MDTIDX ] ||
16507                         error "$file is not on MDT${MDTIDX}"
16508         done
16509
16510         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
16511         [ "$old_dir_flag" = "$new_dir_flag" ] ||
16512                 error " expect $old_dir_flag get $new_dir_flag"
16513
16514         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
16515         [ "$old_file_flag" = "$new_file_flag" ] ||
16516                 error " expect $old_file_flag get $new_file_flag"
16517
16518         local new_dir_mode=$(stat -c%f $migrate_dir)
16519         [ "$old_dir_mode" = "$new_dir_mode" ] ||
16520                 error "expect mode $old_dir_mode get $new_dir_mode"
16521
16522         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
16523         [ "$old_file_mode" = "$new_file_mode" ] ||
16524                 error "expect mode $old_file_mode get $new_file_mode"
16525
16526         diff /etc/passwd ${migrate_dir}/$tfile ||
16527                 error "$tfile different after migration"
16528
16529         diff /etc/passwd ${other_dir}/luna ||
16530                 error "luna different after migration"
16531
16532         diff /etc/passwd ${migrate_dir}/sofia ||
16533                 error "sofia different after migration"
16534
16535         diff /etc/passwd ${other_dir}/zachary ||
16536                 error "zachary different after migration"
16537
16538         diff /etc/passwd $migrate_dir/${tfile}_ln ||
16539                 error "${tfile}_ln different after migration"
16540
16541         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
16542                 error "${tfile}_ln_other different after migration"
16543
16544         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
16545         [ $stripe_count = 2 ] ||
16546                 error "dir strpe_count $d != 2 after migration."
16547
16548         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
16549         [ $stripe_count = 2 ] ||
16550                 error "file strpe_count $d != 2 after migration."
16551
16552         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16553 }
16554 run_test 230b "migrate directory"
16555
16556 test_230c() {
16557         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16558         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16559         remote_mds_nodsh && skip "remote MDS with nodsh"
16560         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16561                 skip "Need MDS version at least 2.11.52"
16562
16563         local MDTIDX=1
16564         local total=3
16565         local mdt_index
16566         local file
16567         local migrate_dir=$DIR/$tdir/migrate_dir
16568
16569         #If migrating directory fails in the middle, all entries of
16570         #the directory is still accessiable.
16571         test_mkdir $DIR/$tdir
16572         test_mkdir -i0 -c1 $migrate_dir
16573         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
16574         stat $migrate_dir
16575         createmany -o $migrate_dir/f $total ||
16576                 error "create files under ${migrate_dir} failed"
16577
16578         # fail after migrating top dir, and this will fail only once, so the
16579         # first sub file migration will fail (currently f3), others succeed.
16580         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
16581         do_facet mds1 lctl set_param fail_loc=0x1801
16582         local t=$(ls $migrate_dir | wc -l)
16583         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
16584                 error "migrate should fail"
16585         local u=$(ls $migrate_dir | wc -l)
16586         [ "$u" == "$t" ] || error "$u != $t during migration"
16587
16588         # add new dir/file should succeed
16589         mkdir $migrate_dir/dir ||
16590                 error "mkdir failed under migrating directory"
16591         touch $migrate_dir/file ||
16592                 error "create file failed under migrating directory"
16593
16594         # add file with existing name should fail
16595         for file in $migrate_dir/f*; do
16596                 stat $file > /dev/null || error "stat $file failed"
16597                 $OPENFILE -f O_CREAT:O_EXCL $file &&
16598                         error "open(O_CREAT|O_EXCL) $file should fail"
16599                 $MULTIOP $file m && error "create $file should fail"
16600                 touch $DIR/$tdir/remote_dir/$tfile ||
16601                         error "touch $tfile failed"
16602                 ln $DIR/$tdir/remote_dir/$tfile $file &&
16603                         error "link $file should fail"
16604                 mdt_index=$($LFS getstripe -m $file)
16605                 if [ $mdt_index == 0 ]; then
16606                         # file failed to migrate is not allowed to rename to
16607                         mv $DIR/$tdir/remote_dir/$tfile $file &&
16608                                 error "rename to $file should fail"
16609                 else
16610                         mv $DIR/$tdir/remote_dir/$tfile $file ||
16611                                 error "rename to $file failed"
16612                 fi
16613                 echo hello >> $file || error "write $file failed"
16614         done
16615
16616         # resume migration with different options should fail
16617         $LFS migrate -m 0 $migrate_dir &&
16618                 error "migrate -m 0 $migrate_dir should fail"
16619
16620         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
16621                 error "migrate -c 2 $migrate_dir should fail"
16622
16623         # resume migration should succeed
16624         $LFS migrate -m $MDTIDX $migrate_dir ||
16625                 error "migrate $migrate_dir failed"
16626
16627         echo "Finish migration, then checking.."
16628         for file in $(find $migrate_dir); do
16629                 mdt_index=$($LFS getstripe -m $file)
16630                 [ $mdt_index == $MDTIDX ] ||
16631                         error "$file is not on MDT${MDTIDX}"
16632         done
16633
16634         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16635 }
16636 run_test 230c "check directory accessiblity if migration failed"
16637
16638 test_230d() {
16639         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16640         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16641         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16642                 skip "Need MDS version at least 2.11.52"
16643         # LU-11235
16644         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
16645
16646         local migrate_dir=$DIR/$tdir/migrate_dir
16647         local old_index
16648         local new_index
16649         local old_count
16650         local new_count
16651         local new_hash
16652         local mdt_index
16653         local i
16654         local j
16655
16656         old_index=$((RANDOM % MDSCOUNT))
16657         old_count=$((MDSCOUNT - old_index))
16658         new_index=$((RANDOM % MDSCOUNT))
16659         new_count=$((MDSCOUNT - new_index))
16660         new_hash="all_char"
16661
16662         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
16663         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
16664
16665         test_mkdir $DIR/$tdir
16666         test_mkdir -i $old_index -c $old_count $migrate_dir
16667
16668         for ((i=0; i<100; i++)); do
16669                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
16670                 createmany -o $migrate_dir/dir_${i}/f 100 ||
16671                         error "create files under remote dir failed $i"
16672         done
16673
16674         echo -n "Migrate from MDT$old_index "
16675         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
16676         echo -n "to MDT$new_index"
16677         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
16678         echo
16679
16680         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
16681         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
16682                 error "migrate remote dir error"
16683
16684         echo "Finish migration, then checking.."
16685         for file in $(find $migrate_dir); do
16686                 mdt_index=$($LFS getstripe -m $file)
16687                 if [ $mdt_index -lt $new_index ] ||
16688                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
16689                         error "$file is on MDT$mdt_index"
16690                 fi
16691         done
16692
16693         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16694 }
16695 run_test 230d "check migrate big directory"
16696
16697 test_230e() {
16698         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16699         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16700         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16701                 skip "Need MDS version at least 2.11.52"
16702
16703         local i
16704         local j
16705         local a_fid
16706         local b_fid
16707
16708         mkdir -p $DIR/$tdir
16709         mkdir $DIR/$tdir/migrate_dir
16710         mkdir $DIR/$tdir/other_dir
16711         touch $DIR/$tdir/migrate_dir/a
16712         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
16713         ls $DIR/$tdir/other_dir
16714
16715         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
16716                 error "migrate dir fails"
16717
16718         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
16719         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
16720
16721         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16722         [ $mdt_index == 0 ] || error "a is not on MDT0"
16723
16724         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
16725                 error "migrate dir fails"
16726
16727         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
16728         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
16729
16730         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16731         [ $mdt_index == 1 ] || error "a is not on MDT1"
16732
16733         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
16734         [ $mdt_index == 1 ] || error "b is not on MDT1"
16735
16736         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
16737         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
16738
16739         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
16740
16741         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16742 }
16743 run_test 230e "migrate mulitple local link files"
16744
16745 test_230f() {
16746         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16747         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16748         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16749                 skip "Need MDS version at least 2.11.52"
16750
16751         local a_fid
16752         local ln_fid
16753
16754         mkdir -p $DIR/$tdir
16755         mkdir $DIR/$tdir/migrate_dir
16756         $LFS mkdir -i1 $DIR/$tdir/other_dir
16757         touch $DIR/$tdir/migrate_dir/a
16758         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
16759         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
16760         ls $DIR/$tdir/other_dir
16761
16762         # a should be migrated to MDT1, since no other links on MDT0
16763         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
16764                 error "#1 migrate dir fails"
16765         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
16766         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
16767         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16768         [ $mdt_index == 1 ] || error "a is not on MDT1"
16769
16770         # a should stay on MDT1, because it is a mulitple link file
16771         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
16772                 error "#2 migrate dir fails"
16773         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16774         [ $mdt_index == 1 ] || error "a is not on MDT1"
16775
16776         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
16777                 error "#3 migrate dir fails"
16778
16779         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
16780         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
16781         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
16782
16783         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
16784         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
16785
16786         # a should be migrated to MDT0, since no other links on MDT1
16787         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
16788                 error "#4 migrate dir fails"
16789         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16790         [ $mdt_index == 0 ] || error "a is not on MDT0"
16791
16792         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16793 }
16794 run_test 230f "migrate mulitple remote link files"
16795
16796 test_230g() {
16797         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16798         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16799         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16800                 skip "Need MDS version at least 2.11.52"
16801
16802         mkdir -p $DIR/$tdir/migrate_dir
16803
16804         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
16805                 error "migrating dir to non-exist MDT succeeds"
16806         true
16807 }
16808 run_test 230g "migrate dir to non-exist MDT"
16809
16810 test_230h() {
16811         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16812         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16813         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16814                 skip "Need MDS version at least 2.11.52"
16815
16816         local mdt_index
16817
16818         mkdir -p $DIR/$tdir/migrate_dir
16819
16820         $LFS migrate -m1 $DIR &&
16821                 error "migrating mountpoint1 should fail"
16822
16823         $LFS migrate -m1 $DIR/$tdir/.. &&
16824                 error "migrating mountpoint2 should fail"
16825
16826         # same as mv
16827         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
16828                 error "migrating $tdir/migrate_dir/.. should fail"
16829
16830         true
16831 }
16832 run_test 230h "migrate .. and root"
16833
16834 test_230i() {
16835         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16836         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16837         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16838                 skip "Need MDS version at least 2.11.52"
16839
16840         mkdir -p $DIR/$tdir/migrate_dir
16841
16842         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
16843                 error "migration fails with a tailing slash"
16844
16845         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
16846                 error "migration fails with two tailing slashes"
16847 }
16848 run_test 230i "lfs migrate -m tolerates trailing slashes"
16849
16850 test_230j() {
16851         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
16852         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16853                 skip "Need MDS version at least 2.11.52"
16854
16855         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
16856         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
16857                 error "create $tfile failed"
16858         cat /etc/passwd > $DIR/$tdir/$tfile
16859
16860         $LFS migrate -m 1 $DIR/$tdir
16861
16862         cmp /etc/passwd $DIR/$tdir/$tfile ||
16863                 error "DoM file mismatch after migration"
16864 }
16865 run_test 230j "DoM file data not changed after dir migration"
16866
16867 test_230k() {
16868         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
16869         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
16870                 skip "Need MDS version at least 2.11.56"
16871
16872         local total=20
16873         local files_on_starting_mdt=0
16874
16875         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
16876         $LFS getdirstripe $DIR/$tdir
16877         for i in $(seq $total); do
16878                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
16879                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
16880                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
16881         done
16882
16883         echo "$files_on_starting_mdt files on MDT0"
16884
16885         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
16886         $LFS getdirstripe $DIR/$tdir
16887
16888         files_on_starting_mdt=0
16889         for i in $(seq $total); do
16890                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
16891                         error "file $tfile.$i mismatch after migration"
16892                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
16893                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
16894         done
16895
16896         echo "$files_on_starting_mdt files on MDT1 after migration"
16897         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
16898
16899         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
16900         $LFS getdirstripe $DIR/$tdir
16901
16902         files_on_starting_mdt=0
16903         for i in $(seq $total); do
16904                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
16905                         error "file $tfile.$i mismatch after 2nd migration"
16906                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
16907                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
16908         done
16909
16910         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
16911         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
16912
16913         true
16914 }
16915 run_test 230k "file data not changed after dir migration"
16916
16917 test_230l() {
16918         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
16919         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
16920                 skip "Need MDS version at least 2.11.56"
16921
16922         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
16923         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
16924                 error "create files under remote dir failed $i"
16925         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
16926 }
16927 run_test 230l "readdir between MDTs won't crash"
16928
16929 test_230m() {
16930         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
16931         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
16932                 skip "Need MDS version at least 2.11.56"
16933
16934         local MDTIDX=1
16935         local mig_dir=$DIR/$tdir/migrate_dir
16936         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
16937         local shortstr="b"
16938         local val
16939
16940         echo "Creating files and dirs with xattrs"
16941         test_mkdir $DIR/$tdir
16942         test_mkdir -i0 -c1 $mig_dir
16943         mkdir $mig_dir/dir
16944         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
16945                 error "cannot set xattr attr1 on dir"
16946         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
16947                 error "cannot set xattr attr2 on dir"
16948         touch $mig_dir/dir/f0
16949         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
16950                 error "cannot set xattr attr1 on file"
16951         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
16952                 error "cannot set xattr attr2 on file"
16953         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
16954         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
16955         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
16956         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
16957         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
16958         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
16959         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
16960         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
16961         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
16962
16963         echo "Migrating to MDT1"
16964         $LFS migrate -m $MDTIDX $mig_dir ||
16965                 error "fails on migrating dir to MDT1"
16966
16967         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
16968         echo "Checking xattrs"
16969         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
16970         [ "$val" = $longstr ] ||
16971                 error "expecting xattr1 $longstr on dir, found $val"
16972         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
16973         [ "$val" = $shortstr ] ||
16974                 error "expecting xattr2 $shortstr on dir, found $val"
16975         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
16976         [ "$val" = $longstr ] ||
16977                 error "expecting xattr1 $longstr on file, found $val"
16978         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
16979         [ "$val" = $shortstr ] ||
16980                 error "expecting xattr2 $shortstr on file, found $val"
16981 }
16982 run_test 230m "xattrs not changed after dir migration"
16983
16984 test_231a()
16985 {
16986         # For simplicity this test assumes that max_pages_per_rpc
16987         # is the same across all OSCs
16988         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
16989         local bulk_size=$((max_pages * PAGE_SIZE))
16990         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
16991                                        head -n 1)
16992
16993         mkdir -p $DIR/$tdir
16994         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
16995                 error "failed to set stripe with -S ${brw_size}M option"
16996
16997         # clear the OSC stats
16998         $LCTL set_param osc.*.stats=0 &>/dev/null
16999         stop_writeback
17000
17001         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
17002         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
17003                 oflag=direct &>/dev/null || error "dd failed"
17004
17005         sync; sleep 1; sync # just to be safe
17006         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
17007         if [ x$nrpcs != "x1" ]; then
17008                 $LCTL get_param osc.*.stats
17009                 error "found $nrpcs ost_write RPCs, not 1 as expected"
17010         fi
17011
17012         start_writeback
17013         # Drop the OSC cache, otherwise we will read from it
17014         cancel_lru_locks osc
17015
17016         # clear the OSC stats
17017         $LCTL set_param osc.*.stats=0 &>/dev/null
17018
17019         # Client reads $bulk_size.
17020         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
17021                 iflag=direct &>/dev/null || error "dd failed"
17022
17023         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
17024         if [ x$nrpcs != "x1" ]; then
17025                 $LCTL get_param osc.*.stats
17026                 error "found $nrpcs ost_read RPCs, not 1 as expected"
17027         fi
17028 }
17029 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
17030
17031 test_231b() {
17032         mkdir -p $DIR/$tdir
17033         local i
17034         for i in {0..1023}; do
17035                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
17036                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
17037                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
17038         done
17039         sync
17040 }
17041 run_test 231b "must not assert on fully utilized OST request buffer"
17042
17043 test_232a() {
17044         mkdir -p $DIR/$tdir
17045         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
17046
17047         #define OBD_FAIL_LDLM_OST_LVB            0x31c
17048         do_facet ost1 $LCTL set_param fail_loc=0x31c
17049
17050         # ignore dd failure
17051         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
17052
17053         do_facet ost1 $LCTL set_param fail_loc=0
17054         umount_client $MOUNT || error "umount failed"
17055         mount_client $MOUNT || error "mount failed"
17056         stop ost1 || error "cannot stop ost1"
17057         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
17058 }
17059 run_test 232a "failed lock should not block umount"
17060
17061 test_232b() {
17062         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
17063                 skip "Need MDS version at least 2.10.58"
17064
17065         mkdir -p $DIR/$tdir
17066         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
17067         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
17068         sync
17069         cancel_lru_locks osc
17070
17071         #define OBD_FAIL_LDLM_OST_LVB            0x31c
17072         do_facet ost1 $LCTL set_param fail_loc=0x31c
17073
17074         # ignore failure
17075         $LFS data_version $DIR/$tdir/$tfile || true
17076
17077         do_facet ost1 $LCTL set_param fail_loc=0
17078         umount_client $MOUNT || error "umount failed"
17079         mount_client $MOUNT || error "mount failed"
17080         stop ost1 || error "cannot stop ost1"
17081         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
17082 }
17083 run_test 232b "failed data version lock should not block umount"
17084
17085 test_233a() {
17086         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
17087                 skip "Need MDS version at least 2.3.64"
17088         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
17089
17090         local fid=$($LFS path2fid $MOUNT)
17091
17092         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
17093                 error "cannot access $MOUNT using its FID '$fid'"
17094 }
17095 run_test 233a "checking that OBF of the FS root succeeds"
17096
17097 test_233b() {
17098         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
17099                 skip "Need MDS version at least 2.5.90"
17100         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
17101
17102         local fid=$($LFS path2fid $MOUNT/.lustre)
17103
17104         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
17105                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
17106
17107         fid=$($LFS path2fid $MOUNT/.lustre/fid)
17108         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
17109                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
17110 }
17111 run_test 233b "checking that OBF of the FS .lustre succeeds"
17112
17113 test_234() {
17114         local p="$TMP/sanityN-$TESTNAME.parameters"
17115         save_lustre_params client "llite.*.xattr_cache" > $p
17116         lctl set_param llite.*.xattr_cache 1 ||
17117                 skip_env "xattr cache is not supported"
17118
17119         mkdir -p $DIR/$tdir || error "mkdir failed"
17120         touch $DIR/$tdir/$tfile || error "touch failed"
17121         # OBD_FAIL_LLITE_XATTR_ENOMEM
17122         $LCTL set_param fail_loc=0x1405
17123         getfattr -n user.attr $DIR/$tdir/$tfile &&
17124                 error "getfattr should have failed with ENOMEM"
17125         $LCTL set_param fail_loc=0x0
17126         rm -rf $DIR/$tdir
17127
17128         restore_lustre_params < $p
17129         rm -f $p
17130 }
17131 run_test 234 "xattr cache should not crash on ENOMEM"
17132
17133 test_235() {
17134         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
17135                 skip "Need MDS version at least 2.4.52"
17136
17137         flock_deadlock $DIR/$tfile
17138         local RC=$?
17139         case $RC in
17140                 0)
17141                 ;;
17142                 124) error "process hangs on a deadlock"
17143                 ;;
17144                 *) error "error executing flock_deadlock $DIR/$tfile"
17145                 ;;
17146         esac
17147 }
17148 run_test 235 "LU-1715: flock deadlock detection does not work properly"
17149
17150 #LU-2935
17151 test_236() {
17152         check_swap_layouts_support
17153
17154         local ref1=/etc/passwd
17155         local ref2=/etc/group
17156         local file1=$DIR/$tdir/f1
17157         local file2=$DIR/$tdir/f2
17158
17159         test_mkdir -c1 $DIR/$tdir
17160         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
17161         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
17162         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
17163         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
17164         local fd=$(free_fd)
17165         local cmd="exec $fd<>$file2"
17166         eval $cmd
17167         rm $file2
17168         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
17169                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
17170         cmd="exec $fd>&-"
17171         eval $cmd
17172         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
17173
17174         #cleanup
17175         rm -rf $DIR/$tdir
17176 }
17177 run_test 236 "Layout swap on open unlinked file"
17178
17179 # LU-4659 linkea consistency
17180 test_238() {
17181         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
17182                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
17183                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
17184                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
17185
17186         touch $DIR/$tfile
17187         ln $DIR/$tfile $DIR/$tfile.lnk
17188         touch $DIR/$tfile.new
17189         mv $DIR/$tfile.new $DIR/$tfile
17190         local fid1=$($LFS path2fid $DIR/$tfile)
17191         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
17192         local path1=$($LFS fid2path $FSNAME "$fid1")
17193         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
17194         local path2=$($LFS fid2path $FSNAME "$fid2")
17195         [ $tfile.lnk == $path2 ] ||
17196                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
17197         rm -f $DIR/$tfile*
17198 }
17199 run_test 238 "Verify linkea consistency"
17200
17201 test_239A() { # was test_239
17202         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
17203                 skip "Need MDS version at least 2.5.60"
17204
17205         local list=$(comma_list $(mdts_nodes))
17206
17207         mkdir -p $DIR/$tdir
17208         createmany -o $DIR/$tdir/f- 5000
17209         unlinkmany $DIR/$tdir/f- 5000
17210         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
17211                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
17212         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
17213                         osp.*MDT*.sync_in_flight" | calc_sum)
17214         [ "$changes" -eq 0 ] || error "$changes not synced"
17215 }
17216 run_test 239A "osp_sync test"
17217
17218 test_239a() { #LU-5297
17219         remote_mds_nodsh && skip "remote MDS with nodsh"
17220
17221         touch $DIR/$tfile
17222         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
17223         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
17224         chgrp $RUNAS_GID $DIR/$tfile
17225         wait_delete_completed
17226 }
17227 run_test 239a "process invalid osp sync record correctly"
17228
17229 test_239b() { #LU-5297
17230         remote_mds_nodsh && skip "remote MDS with nodsh"
17231
17232         touch $DIR/$tfile1
17233         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
17234         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
17235         chgrp $RUNAS_GID $DIR/$tfile1
17236         wait_delete_completed
17237         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
17238         touch $DIR/$tfile2
17239         chgrp $RUNAS_GID $DIR/$tfile2
17240         wait_delete_completed
17241 }
17242 run_test 239b "process osp sync record with ENOMEM error correctly"
17243
17244 test_240() {
17245         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17246         remote_mds_nodsh && skip "remote MDS with nodsh"
17247
17248         mkdir -p $DIR/$tdir
17249
17250         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
17251                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
17252         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
17253                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
17254
17255         umount_client $MOUNT || error "umount failed"
17256         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
17257         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
17258         mount_client $MOUNT || error "failed to mount client"
17259
17260         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
17261         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
17262 }
17263 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
17264
17265 test_241_bio() {
17266         local count=$1
17267         local bsize=$2
17268
17269         for LOOP in $(seq $count); do
17270                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
17271                 cancel_lru_locks $OSC || true
17272         done
17273 }
17274
17275 test_241_dio() {
17276         local count=$1
17277         local bsize=$2
17278
17279         for LOOP in $(seq $1); do
17280                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
17281                         2>/dev/null
17282         done
17283 }
17284
17285 test_241a() { # was test_241
17286         local bsize=$PAGE_SIZE
17287
17288         (( bsize < 40960 )) && bsize=40960
17289         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
17290         ls -la $DIR/$tfile
17291         cancel_lru_locks $OSC
17292         test_241_bio 1000 $bsize &
17293         PID=$!
17294         test_241_dio 1000 $bsize
17295         wait $PID
17296 }
17297 run_test 241a "bio vs dio"
17298
17299 test_241b() {
17300         local bsize=$PAGE_SIZE
17301
17302         (( bsize < 40960 )) && bsize=40960
17303         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
17304         ls -la $DIR/$tfile
17305         test_241_dio 1000 $bsize &
17306         PID=$!
17307         test_241_dio 1000 $bsize
17308         wait $PID
17309 }
17310 run_test 241b "dio vs dio"
17311
17312 test_242() {
17313         remote_mds_nodsh && skip "remote MDS with nodsh"
17314
17315         mkdir -p $DIR/$tdir
17316         touch $DIR/$tdir/$tfile
17317
17318         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
17319         do_facet mds1 lctl set_param fail_loc=0x105
17320         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
17321
17322         do_facet mds1 lctl set_param fail_loc=0
17323         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
17324 }
17325 run_test 242 "mdt_readpage failure should not cause directory unreadable"
17326
17327 test_243()
17328 {
17329         test_mkdir $DIR/$tdir
17330         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
17331 }
17332 run_test 243 "various group lock tests"
17333
17334 test_244a()
17335 {
17336         test_mkdir $DIR/$tdir
17337         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
17338         sendfile_grouplock $DIR/$tdir/$tfile || \
17339                 error "sendfile+grouplock failed"
17340         rm -rf $DIR/$tdir
17341 }
17342 run_test 244a "sendfile with group lock tests"
17343
17344 test_244b()
17345 {
17346         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
17347
17348         local threads=50
17349         local size=$((1024*1024))
17350
17351         test_mkdir $DIR/$tdir
17352         for i in $(seq 1 $threads); do
17353                 local file=$DIR/$tdir/file_$((i / 10))
17354                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
17355                 local pids[$i]=$!
17356         done
17357         for i in $(seq 1 $threads); do
17358                 wait ${pids[$i]}
17359         done
17360 }
17361 run_test 244b "multi-threaded write with group lock"
17362
17363 test_245() {
17364         local flagname="multi_mod_rpcs"
17365         local connect_data_name="max_mod_rpcs"
17366         local out
17367
17368         # check if multiple modify RPCs flag is set
17369         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
17370                 grep "connect_flags:")
17371         echo "$out"
17372
17373         echo "$out" | grep -qw $flagname
17374         if [ $? -ne 0 ]; then
17375                 echo "connect flag $flagname is not set"
17376                 return
17377         fi
17378
17379         # check if multiple modify RPCs data is set
17380         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
17381         echo "$out"
17382
17383         echo "$out" | grep -qw $connect_data_name ||
17384                 error "import should have connect data $connect_data_name"
17385 }
17386 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
17387
17388 cleanup_247() {
17389         local submount=$1
17390
17391         trap 0
17392         umount_client $submount
17393         rmdir $submount
17394 }
17395
17396 test_247a() {
17397         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
17398                 grep -q subtree ||
17399                 skip_env "Fileset feature is not supported"
17400
17401         local submount=${MOUNT}_$tdir
17402
17403         mkdir $MOUNT/$tdir
17404         mkdir -p $submount || error "mkdir $submount failed"
17405         FILESET="$FILESET/$tdir" mount_client $submount ||
17406                 error "mount $submount failed"
17407         trap "cleanup_247 $submount" EXIT
17408         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
17409         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
17410                 error "read $MOUNT/$tdir/$tfile failed"
17411         cleanup_247 $submount
17412 }
17413 run_test 247a "mount subdir as fileset"
17414
17415 test_247b() {
17416         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
17417                 skip_env "Fileset feature is not supported"
17418
17419         local submount=${MOUNT}_$tdir
17420
17421         rm -rf $MOUNT/$tdir
17422         mkdir -p $submount || error "mkdir $submount failed"
17423         SKIP_FILESET=1
17424         FILESET="$FILESET/$tdir" mount_client $submount &&
17425                 error "mount $submount should fail"
17426         rmdir $submount
17427 }
17428 run_test 247b "mount subdir that dose not exist"
17429
17430 test_247c() {
17431         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
17432                 skip_env "Fileset feature is not supported"
17433
17434         local submount=${MOUNT}_$tdir
17435
17436         mkdir -p $MOUNT/$tdir/dir1
17437         mkdir -p $submount || error "mkdir $submount failed"
17438         trap "cleanup_247 $submount" EXIT
17439         FILESET="$FILESET/$tdir" mount_client $submount ||
17440                 error "mount $submount failed"
17441         local fid=$($LFS path2fid $MOUNT/)
17442         $LFS fid2path $submount $fid && error "fid2path should fail"
17443         cleanup_247 $submount
17444 }
17445 run_test 247c "running fid2path outside root"
17446
17447 test_247d() {
17448         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
17449                 skip "Fileset feature is not supported"
17450
17451         local submount=${MOUNT}_$tdir
17452
17453         mkdir -p $MOUNT/$tdir/dir1
17454         mkdir -p $submount || error "mkdir $submount failed"
17455         FILESET="$FILESET/$tdir" mount_client $submount ||
17456                 error "mount $submount failed"
17457         trap "cleanup_247 $submount" EXIT
17458         local fid=$($LFS path2fid $submount/dir1)
17459         $LFS fid2path $submount $fid || error "fid2path should succeed"
17460         cleanup_247 $submount
17461 }
17462 run_test 247d "running fid2path inside root"
17463
17464 # LU-8037
17465 test_247e() {
17466         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
17467                 grep -q subtree ||
17468                 skip "Fileset feature is not supported"
17469
17470         local submount=${MOUNT}_$tdir
17471
17472         mkdir $MOUNT/$tdir
17473         mkdir -p $submount || error "mkdir $submount failed"
17474         FILESET="$FILESET/.." mount_client $submount &&
17475                 error "mount $submount should fail"
17476         rmdir $submount
17477 }
17478 run_test 247e "mount .. as fileset"
17479
17480 test_248a() {
17481         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
17482         [ -z "$fast_read_sav" ] && skip "no fast read support"
17483
17484         # create a large file for fast read verification
17485         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
17486
17487         # make sure the file is created correctly
17488         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
17489                 { rm -f $DIR/$tfile; skip "file creation error"; }
17490
17491         echo "Test 1: verify that fast read is 4 times faster on cache read"
17492
17493         # small read with fast read enabled
17494         $LCTL set_param -n llite.*.fast_read=1
17495         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
17496                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
17497                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
17498         # small read with fast read disabled
17499         $LCTL set_param -n llite.*.fast_read=0
17500         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
17501                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
17502                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
17503
17504         # verify that fast read is 4 times faster for cache read
17505         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
17506                 error_not_in_vm "fast read was not 4 times faster: " \
17507                            "$t_fast vs $t_slow"
17508
17509         echo "Test 2: verify the performance between big and small read"
17510         $LCTL set_param -n llite.*.fast_read=1
17511
17512         # 1k non-cache read
17513         cancel_lru_locks osc
17514         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
17515                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
17516                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
17517
17518         # 1M non-cache read
17519         cancel_lru_locks osc
17520         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
17521                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
17522                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
17523
17524         # verify that big IO is not 4 times faster than small IO
17525         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
17526                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
17527
17528         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
17529         rm -f $DIR/$tfile
17530 }
17531 run_test 248a "fast read verification"
17532
17533 test_248b() {
17534         # Default short_io_bytes=16384, try both smaller and larger sizes.
17535         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
17536         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
17537         echo "bs=53248 count=113 normal buffered write"
17538         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
17539                 error "dd of initial data file failed"
17540         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
17541
17542         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
17543         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
17544                 error "dd with sync normal writes failed"
17545         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
17546
17547         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
17548         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
17549                 error "dd with sync small writes failed"
17550         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
17551
17552         cancel_lru_locks osc
17553
17554         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
17555         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
17556         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
17557         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
17558                 iflag=direct || error "dd with O_DIRECT small read failed"
17559         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
17560         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
17561                 error "compare $TMP/$tfile.1 failed"
17562
17563         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
17564         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
17565
17566         # just to see what the maximum tunable value is, and test parsing
17567         echo "test invalid parameter 2MB"
17568         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
17569                 error "too-large short_io_bytes allowed"
17570         echo "test maximum parameter 512KB"
17571         # if we can set a larger short_io_bytes, run test regardless of version
17572         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
17573                 # older clients may not allow setting it this large, that's OK
17574                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
17575                         skip "Need at least client version 2.13.50"
17576                 error "medium short_io_bytes failed"
17577         fi
17578         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
17579         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
17580
17581         echo "test large parameter 64KB"
17582         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
17583         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
17584
17585         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
17586         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
17587                 error "dd with sync large writes failed"
17588         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
17589
17590         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
17591         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
17592         num=$((113 * 4096 / PAGE_SIZE))
17593         echo "bs=$size count=$num oflag=direct large write $tfile.3"
17594         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
17595                 error "dd with O_DIRECT large writes failed"
17596         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
17597                 error "compare $DIR/$tfile.3 failed"
17598
17599         cancel_lru_locks osc
17600
17601         echo "bs=$size count=$num iflag=direct large read $tfile.2"
17602         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
17603                 error "dd with O_DIRECT large read failed"
17604         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
17605                 error "compare $TMP/$tfile.2 failed"
17606
17607         echo "bs=$size count=$num iflag=direct large read $tfile.3"
17608         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
17609                 error "dd with O_DIRECT large read failed"
17610         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
17611                 error "compare $TMP/$tfile.3 failed"
17612 }
17613 run_test 248b "test short_io read and write for both small and large sizes"
17614
17615 test_249() { # LU-7890
17616         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
17617                 skip "Need at least version 2.8.54"
17618
17619         rm -f $DIR/$tfile
17620         $LFS setstripe -c 1 $DIR/$tfile
17621         # Offset 2T == 4k * 512M
17622         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
17623                 error "dd to 2T offset failed"
17624 }
17625 run_test 249 "Write above 2T file size"
17626
17627 test_250() {
17628         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
17629          && skip "no 16TB file size limit on ZFS"
17630
17631         $LFS setstripe -c 1 $DIR/$tfile
17632         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
17633         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
17634         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
17635         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
17636                 conv=notrunc,fsync && error "append succeeded"
17637         return 0
17638 }
17639 run_test 250 "Write above 16T limit"
17640
17641 test_251() {
17642         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
17643
17644         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
17645         #Skip once - writing the first stripe will succeed
17646         $LCTL set_param fail_loc=0xa0001407 fail_val=1
17647         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
17648                 error "short write happened"
17649
17650         $LCTL set_param fail_loc=0xa0001407 fail_val=1
17651         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
17652                 error "short read happened"
17653
17654         rm -f $DIR/$tfile
17655 }
17656 run_test 251 "Handling short read and write correctly"
17657
17658 test_252() {
17659         remote_mds_nodsh && skip "remote MDS with nodsh"
17660         remote_ost_nodsh && skip "remote OST with nodsh"
17661         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
17662                 skip_env "ldiskfs only test"
17663         fi
17664
17665         local tgt
17666         local dev
17667         local out
17668         local uuid
17669         local num
17670         local gen
17671
17672         # check lr_reader on OST0000
17673         tgt=ost1
17674         dev=$(facet_device $tgt)
17675         out=$(do_facet $tgt $LR_READER $dev)
17676         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
17677         echo "$out"
17678         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
17679         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
17680                 error "Invalid uuid returned by $LR_READER on target $tgt"
17681         echo -e "uuid returned by $LR_READER is '$uuid'\n"
17682
17683         # check lr_reader -c on MDT0000
17684         tgt=mds1
17685         dev=$(facet_device $tgt)
17686         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
17687                 skip "$LR_READER does not support additional options"
17688         fi
17689         out=$(do_facet $tgt $LR_READER -c $dev)
17690         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
17691         echo "$out"
17692         num=$(echo "$out" | grep -c "mdtlov")
17693         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
17694                 error "Invalid number of mdtlov clients returned by $LR_READER"
17695         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
17696
17697         # check lr_reader -cr on MDT0000
17698         out=$(do_facet $tgt $LR_READER -cr $dev)
17699         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
17700         echo "$out"
17701         echo "$out" | grep -q "^reply_data:$" ||
17702                 error "$LR_READER should have returned 'reply_data' section"
17703         num=$(echo "$out" | grep -c "client_generation")
17704         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
17705 }
17706 run_test 252 "check lr_reader tool"
17707
17708 test_253() {
17709         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17710         remote_mds_nodsh && skip "remote MDS with nodsh"
17711         remote_mgs_nodsh && skip "remote MGS with nodsh"
17712
17713         local ostidx=0
17714         local rc=0
17715         local ost_name=$(ostname_from_index $ostidx)
17716
17717         # on the mdt's osc
17718         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
17719         do_facet $SINGLEMDS $LCTL get_param -n \
17720                 osp.$mdtosc_proc1.reserved_mb_high ||
17721                 skip  "remote MDS does not support reserved_mb_high"
17722
17723         rm -rf $DIR/$tdir
17724         wait_mds_ost_sync
17725         wait_delete_completed
17726         mkdir $DIR/$tdir
17727
17728         pool_add $TESTNAME || error "Pool creation failed"
17729         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
17730
17731         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
17732                 error "Setstripe failed"
17733
17734         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
17735
17736         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
17737                     grep "watermarks")
17738         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
17739
17740         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
17741                         osp.$mdtosc_proc1.prealloc_status)
17742         echo "prealloc_status $oa_status"
17743
17744         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
17745                 error "File creation should fail"
17746
17747         #object allocation was stopped, but we still able to append files
17748         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
17749                 oflag=append || error "Append failed"
17750
17751         rm -f $DIR/$tdir/$tfile.0
17752
17753         # For this test, we want to delete the files we created to go out of
17754         # space but leave the watermark, so we remain nearly out of space
17755         ost_watermarks_enospc_delete_files $tfile $ostidx
17756
17757         wait_delete_completed
17758
17759         sleep_maxage
17760
17761         for i in $(seq 10 12); do
17762                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
17763                         2>/dev/null || error "File creation failed after rm"
17764         done
17765
17766         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
17767                         osp.$mdtosc_proc1.prealloc_status)
17768         echo "prealloc_status $oa_status"
17769
17770         if (( oa_status != 0 )); then
17771                 error "Object allocation still disable after rm"
17772         fi
17773 }
17774 run_test 253 "Check object allocation limit"
17775
17776 test_254() {
17777         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17778         remote_mds_nodsh && skip "remote MDS with nodsh"
17779         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
17780                 skip "MDS does not support changelog_size"
17781
17782         local cl_user
17783         local MDT0=$(facet_svc $SINGLEMDS)
17784
17785         changelog_register || error "changelog_register failed"
17786
17787         changelog_clear 0 || error "changelog_clear failed"
17788
17789         local size1=$(do_facet $SINGLEMDS \
17790                       $LCTL get_param -n mdd.$MDT0.changelog_size)
17791         echo "Changelog size $size1"
17792
17793         rm -rf $DIR/$tdir
17794         $LFS mkdir -i 0 $DIR/$tdir
17795         # change something
17796         mkdir -p $DIR/$tdir/pics/2008/zachy
17797         touch $DIR/$tdir/pics/2008/zachy/timestamp
17798         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
17799         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
17800         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
17801         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
17802         rm $DIR/$tdir/pics/desktop.jpg
17803
17804         local size2=$(do_facet $SINGLEMDS \
17805                       $LCTL get_param -n mdd.$MDT0.changelog_size)
17806         echo "Changelog size after work $size2"
17807
17808         (( $size2 > $size1 )) ||
17809                 error "new Changelog size=$size2 less than old size=$size1"
17810 }
17811 run_test 254 "Check changelog size"
17812
17813 ladvise_no_type()
17814 {
17815         local type=$1
17816         local file=$2
17817
17818         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
17819                 awk -F: '{print $2}' | grep $type > /dev/null
17820         if [ $? -ne 0 ]; then
17821                 return 0
17822         fi
17823         return 1
17824 }
17825
17826 ladvise_no_ioctl()
17827 {
17828         local file=$1
17829
17830         lfs ladvise -a willread $file > /dev/null 2>&1
17831         if [ $? -eq 0 ]; then
17832                 return 1
17833         fi
17834
17835         lfs ladvise -a willread $file 2>&1 |
17836                 grep "Inappropriate ioctl for device" > /dev/null
17837         if [ $? -eq 0 ]; then
17838                 return 0
17839         fi
17840         return 1
17841 }
17842
17843 percent() {
17844         bc <<<"scale=2; ($1 - $2) * 100 / $2"
17845 }
17846
17847 # run a random read IO workload
17848 # usage: random_read_iops <filename> <filesize> <iosize>
17849 random_read_iops() {
17850         local file=$1
17851         local fsize=$2
17852         local iosize=${3:-4096}
17853
17854         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
17855                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
17856 }
17857
17858 drop_file_oss_cache() {
17859         local file="$1"
17860         local nodes="$2"
17861
17862         $LFS ladvise -a dontneed $file 2>/dev/null ||
17863                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
17864 }
17865
17866 ladvise_willread_performance()
17867 {
17868         local repeat=10
17869         local average_origin=0
17870         local average_cache=0
17871         local average_ladvise=0
17872
17873         for ((i = 1; i <= $repeat; i++)); do
17874                 echo "Iter $i/$repeat: reading without willread hint"
17875                 cancel_lru_locks osc
17876                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
17877                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
17878                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
17879                 average_origin=$(bc <<<"$average_origin + $speed_origin")
17880
17881                 cancel_lru_locks osc
17882                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
17883                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
17884                 average_cache=$(bc <<<"$average_cache + $speed_cache")
17885
17886                 cancel_lru_locks osc
17887                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
17888                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
17889                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
17890                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
17891                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
17892         done
17893         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
17894         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
17895         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
17896
17897         speedup_cache=$(percent $average_cache $average_origin)
17898         speedup_ladvise=$(percent $average_ladvise $average_origin)
17899
17900         echo "Average uncached read: $average_origin"
17901         echo "Average speedup with OSS cached read: " \
17902                 "$average_cache = +$speedup_cache%"
17903         echo "Average speedup with ladvise willread: " \
17904                 "$average_ladvise = +$speedup_ladvise%"
17905
17906         local lowest_speedup=20
17907         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
17908                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
17909                         "got $average_cache%. Skipping ladvise willread check."
17910                 return 0
17911         fi
17912
17913         # the test won't work on ZFS until it supports 'ladvise dontneed', but
17914         # it is still good to run until then to exercise 'ladvise willread'
17915         ! $LFS ladvise -a dontneed $DIR/$tfile &&
17916                 [ "$ost1_FSTYPE" = "zfs" ] &&
17917                 echo "osd-zfs does not support dontneed or drop_caches" &&
17918                 return 0
17919
17920         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
17921         [ ${average_ladvise%.*} -gt $lowest_speedup ] ||
17922                 error_not_in_vm "Speedup with willread is less than " \
17923                         "$lowest_speedup%, got $average_ladvise%"
17924 }
17925
17926 test_255a() {
17927         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
17928                 skip "lustre < 2.8.54 does not support ladvise "
17929         remote_ost_nodsh && skip "remote OST with nodsh"
17930
17931         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
17932
17933         ladvise_no_type willread $DIR/$tfile &&
17934                 skip "willread ladvise is not supported"
17935
17936         ladvise_no_ioctl $DIR/$tfile &&
17937                 skip "ladvise ioctl is not supported"
17938
17939         local size_mb=100
17940         local size=$((size_mb * 1048576))
17941         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
17942                 error "dd to $DIR/$tfile failed"
17943
17944         lfs ladvise -a willread $DIR/$tfile ||
17945                 error "Ladvise failed with no range argument"
17946
17947         lfs ladvise -a willread -s 0 $DIR/$tfile ||
17948                 error "Ladvise failed with no -l or -e argument"
17949
17950         lfs ladvise -a willread -e 1 $DIR/$tfile ||
17951                 error "Ladvise failed with only -e argument"
17952
17953         lfs ladvise -a willread -l 1 $DIR/$tfile ||
17954                 error "Ladvise failed with only -l argument"
17955
17956         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
17957                 error "End offset should not be smaller than start offset"
17958
17959         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
17960                 error "End offset should not be equal to start offset"
17961
17962         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
17963                 error "Ladvise failed with overflowing -s argument"
17964
17965         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
17966                 error "Ladvise failed with overflowing -e argument"
17967
17968         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
17969                 error "Ladvise failed with overflowing -l argument"
17970
17971         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
17972                 error "Ladvise succeeded with conflicting -l and -e arguments"
17973
17974         echo "Synchronous ladvise should wait"
17975         local delay=4
17976 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
17977         do_nodes $(comma_list $(osts_nodes)) \
17978                 $LCTL set_param fail_val=$delay fail_loc=0x237
17979
17980         local start_ts=$SECONDS
17981         lfs ladvise -a willread $DIR/$tfile ||
17982                 error "Ladvise failed with no range argument"
17983         local end_ts=$SECONDS
17984         local inteval_ts=$((end_ts - start_ts))
17985
17986         if [ $inteval_ts -lt $(($delay - 1)) ]; then
17987                 error "Synchronous advice didn't wait reply"
17988         fi
17989
17990         echo "Asynchronous ladvise shouldn't wait"
17991         local start_ts=$SECONDS
17992         lfs ladvise -a willread -b $DIR/$tfile ||
17993                 error "Ladvise failed with no range argument"
17994         local end_ts=$SECONDS
17995         local inteval_ts=$((end_ts - start_ts))
17996
17997         if [ $inteval_ts -gt $(($delay / 2)) ]; then
17998                 error "Asynchronous advice blocked"
17999         fi
18000
18001         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
18002         ladvise_willread_performance
18003 }
18004 run_test 255a "check 'lfs ladvise -a willread'"
18005
18006 facet_meminfo() {
18007         local facet=$1
18008         local info=$2
18009
18010         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
18011 }
18012
18013 test_255b() {
18014         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
18015                 skip "lustre < 2.8.54 does not support ladvise "
18016         remote_ost_nodsh && skip "remote OST with nodsh"
18017
18018         lfs setstripe -c 1 -i 0 $DIR/$tfile
18019
18020         ladvise_no_type dontneed $DIR/$tfile &&
18021                 skip "dontneed ladvise is not supported"
18022
18023         ladvise_no_ioctl $DIR/$tfile &&
18024                 skip "ladvise ioctl is not supported"
18025
18026         ! $LFS ladvise -a dontneed $DIR/$tfile &&
18027                 [ "$ost1_FSTYPE" = "zfs" ] &&
18028                 skip "zfs-osd does not support 'ladvise dontneed'"
18029
18030         local size_mb=100
18031         local size=$((size_mb * 1048576))
18032         # In order to prevent disturbance of other processes, only check 3/4
18033         # of the memory usage
18034         local kibibytes=$((size_mb * 1024 * 3 / 4))
18035
18036         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
18037                 error "dd to $DIR/$tfile failed"
18038
18039         #force write to complete before dropping OST cache & checking memory
18040         sync
18041
18042         local total=$(facet_meminfo ost1 MemTotal)
18043         echo "Total memory: $total KiB"
18044
18045         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
18046         local before_read=$(facet_meminfo ost1 Cached)
18047         echo "Cache used before read: $before_read KiB"
18048
18049         lfs ladvise -a willread $DIR/$tfile ||
18050                 error "Ladvise willread failed"
18051         local after_read=$(facet_meminfo ost1 Cached)
18052         echo "Cache used after read: $after_read KiB"
18053
18054         lfs ladvise -a dontneed $DIR/$tfile ||
18055                 error "Ladvise dontneed again failed"
18056         local no_read=$(facet_meminfo ost1 Cached)
18057         echo "Cache used after dontneed ladvise: $no_read KiB"
18058
18059         if [ $total -lt $((before_read + kibibytes)) ]; then
18060                 echo "Memory is too small, abort checking"
18061                 return 0
18062         fi
18063
18064         if [ $((before_read + kibibytes)) -gt $after_read ]; then
18065                 error "Ladvise willread should use more memory" \
18066                         "than $kibibytes KiB"
18067         fi
18068
18069         if [ $((no_read + kibibytes)) -gt $after_read ]; then
18070                 error "Ladvise dontneed should release more memory" \
18071                         "than $kibibytes KiB"
18072         fi
18073 }
18074 run_test 255b "check 'lfs ladvise -a dontneed'"
18075
18076 test_255c() {
18077         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
18078                 skip "lustre < 2.10.50 does not support lockahead"
18079
18080         local count
18081         local new_count
18082         local difference
18083         local i
18084         local rc
18085
18086         test_mkdir -p $DIR/$tdir
18087         $LFS setstripe -i 0 -c 1 $DIR/$tdir
18088
18089         #test 10 returns only success/failure
18090         i=10
18091         lockahead_test -d $DIR/$tdir -t $i -f $tfile
18092         rc=$?
18093         if [ $rc -eq 255 ]; then
18094                 error "Ladvise test${i} failed, ${rc}"
18095         fi
18096
18097         #test 11 counts lock enqueue requests, all others count new locks
18098         i=11
18099         count=$(do_facet ost1 \
18100                 $LCTL get_param -n ost.OSS.ost.stats)
18101         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
18102
18103         lockahead_test -d $DIR/$tdir -t $i -f $tfile
18104         rc=$?
18105         if [ $rc -eq 255 ]; then
18106                 error "Ladvise test${i} failed, ${rc}"
18107         fi
18108
18109         new_count=$(do_facet ost1 \
18110                 $LCTL get_param -n ost.OSS.ost.stats)
18111         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
18112                    awk '{ print $2 }')
18113
18114         difference="$((new_count - count))"
18115         if [ $difference -ne $rc ]; then
18116                 error "Ladvise test${i}, bad enqueue count, returned " \
18117                       "${rc}, actual ${difference}"
18118         fi
18119
18120         for i in $(seq 12 21); do
18121                 # If we do not do this, we run the risk of having too many
18122                 # locks and starting lock cancellation while we are checking
18123                 # lock counts.
18124                 cancel_lru_locks osc
18125
18126                 count=$($LCTL get_param -n \
18127                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
18128
18129                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
18130                 rc=$?
18131                 if [ $rc -eq 255 ]; then
18132                         error "Ladvise test ${i} failed, ${rc}"
18133                 fi
18134
18135                 new_count=$($LCTL get_param -n \
18136                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
18137                 difference="$((new_count - count))"
18138
18139                 # Test 15 output is divided by 100 to map down to valid return
18140                 if [ $i -eq 15 ]; then
18141                         rc="$((rc * 100))"
18142                 fi
18143
18144                 if [ $difference -ne $rc ]; then
18145                         error "Ladvise test ${i}, bad lock count, returned " \
18146                               "${rc}, actual ${difference}"
18147                 fi
18148         done
18149
18150         #test 22 returns only success/failure
18151         i=22
18152         lockahead_test -d $DIR/$tdir -t $i -f $tfile
18153         rc=$?
18154         if [ $rc -eq 255 ]; then
18155                 error "Ladvise test${i} failed, ${rc}"
18156         fi
18157 }
18158 run_test 255c "suite of ladvise lockahead tests"
18159
18160 test_256() {
18161         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18162         remote_mds_nodsh && skip "remote MDS with nodsh"
18163         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
18164         changelog_users $SINGLEMDS | grep "^cl" &&
18165                 skip "active changelog user"
18166
18167         local cl_user
18168         local cat_sl
18169         local mdt_dev
18170
18171         mdt_dev=$(mdsdevname 1)
18172         echo $mdt_dev
18173
18174         changelog_register || error "changelog_register failed"
18175
18176         rm -rf $DIR/$tdir
18177         mkdir -p $DIR/$tdir
18178
18179         changelog_clear 0 || error "changelog_clear failed"
18180
18181         # change something
18182         touch $DIR/$tdir/{1..10}
18183
18184         # stop the MDT
18185         stop $SINGLEMDS || error "Fail to stop MDT"
18186
18187         # remount the MDT
18188
18189         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
18190
18191         #after mount new plainllog is used
18192         touch $DIR/$tdir/{11..19}
18193         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
18194         stack_trap "rm -f $tmpfile"
18195         cat_sl=$(do_facet $SINGLEMDS "sync; \
18196                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
18197                  llog_reader $tmpfile | grep -c type=1064553b")
18198         do_facet $SINGLEMDS llog_reader $tmpfile
18199
18200         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
18201
18202         changelog_clear 0 || error "changelog_clear failed"
18203
18204         cat_sl=$(do_facet $SINGLEMDS "sync; \
18205                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
18206                  llog_reader $tmpfile | grep -c type=1064553b")
18207
18208         if (( cat_sl == 2 )); then
18209                 error "Empty plain llog was not deleted from changelog catalog"
18210         elif (( cat_sl != 1 )); then
18211                 error "Active plain llog shouldn't be deleted from catalog"
18212         fi
18213 }
18214 run_test 256 "Check llog delete for empty and not full state"
18215
18216 test_257() {
18217         remote_mds_nodsh && skip "remote MDS with nodsh"
18218         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
18219                 skip "Need MDS version at least 2.8.55"
18220
18221         test_mkdir $DIR/$tdir
18222
18223         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
18224                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
18225         stat $DIR/$tdir
18226
18227 #define OBD_FAIL_MDS_XATTR_REP                  0x161
18228         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
18229         local facet=mds$((mdtidx + 1))
18230         set_nodes_failloc $(facet_active_host $facet) 0x80000161
18231         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
18232
18233         stop $facet || error "stop MDS failed"
18234         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
18235                 error "start MDS fail"
18236         wait_recovery_complete $facet
18237 }
18238 run_test 257 "xattr locks are not lost"
18239
18240 # Verify we take the i_mutex when security requires it
18241 test_258a() {
18242 #define OBD_FAIL_IMUTEX_SEC 0x141c
18243         $LCTL set_param fail_loc=0x141c
18244         touch $DIR/$tfile
18245         chmod u+s $DIR/$tfile
18246         chmod a+rwx $DIR/$tfile
18247         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
18248         RC=$?
18249         if [ $RC -ne 0 ]; then
18250                 error "error, failed to take i_mutex, rc=$?"
18251         fi
18252         rm -f $DIR/$tfile
18253 }
18254 run_test 258a "verify i_mutex security behavior when suid attributes is set"
18255
18256 # Verify we do NOT take the i_mutex in the normal case
18257 test_258b() {
18258 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
18259         $LCTL set_param fail_loc=0x141d
18260         touch $DIR/$tfile
18261         chmod a+rwx $DIR
18262         chmod a+rw $DIR/$tfile
18263         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
18264         RC=$?
18265         if [ $RC -ne 0 ]; then
18266                 error "error, took i_mutex unnecessarily, rc=$?"
18267         fi
18268         rm -f $DIR/$tfile
18269
18270 }
18271 run_test 258b "verify i_mutex security behavior"
18272
18273 test_259() {
18274         local file=$DIR/$tfile
18275         local before
18276         local after
18277
18278         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
18279
18280         stack_trap "rm -f $file" EXIT
18281
18282         wait_delete_completed
18283         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
18284         echo "before: $before"
18285
18286         $LFS setstripe -i 0 -c 1 $file
18287         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
18288         sync_all_data
18289         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
18290         echo "after write: $after"
18291
18292 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
18293         do_facet ost1 $LCTL set_param fail_loc=0x2301
18294         $TRUNCATE $file 0
18295         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
18296         echo "after truncate: $after"
18297
18298         stop ost1
18299         do_facet ost1 $LCTL set_param fail_loc=0
18300         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18301         sleep 2
18302         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
18303         echo "after restart: $after"
18304         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
18305                 error "missing truncate?"
18306
18307         return 0
18308 }
18309 run_test 259 "crash at delayed truncate"
18310
18311 test_260() {
18312 #define OBD_FAIL_MDC_CLOSE               0x806
18313         $LCTL set_param fail_loc=0x80000806
18314         touch $DIR/$tfile
18315
18316 }
18317 run_test 260 "Check mdc_close fail"
18318
18319 ### Data-on-MDT sanity tests ###
18320 test_270a() {
18321         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18322                 skip "Need MDS version at least 2.10.55 for DoM"
18323
18324         # create DoM file
18325         local dom=$DIR/$tdir/dom_file
18326         local tmp=$DIR/$tdir/tmp_file
18327
18328         mkdir -p $DIR/$tdir
18329
18330         # basic checks for DoM component creation
18331         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
18332                 error "Can set MDT layout to non-first entry"
18333
18334         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
18335                 error "Can define multiple entries as MDT layout"
18336
18337         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
18338
18339         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
18340         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
18341         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
18342
18343         local mdtidx=$($LFS getstripe -m $dom)
18344         local mdtname=MDT$(printf %04x $mdtidx)
18345         local facet=mds$((mdtidx + 1))
18346         local space_check=1
18347
18348         # Skip free space checks with ZFS
18349         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
18350
18351         # write
18352         sync
18353         local size_tmp=$((65536 * 3))
18354         local mdtfree1=$(do_facet $facet \
18355                          lctl get_param -n osd*.*$mdtname.kbytesfree)
18356
18357         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
18358         # check also direct IO along write
18359         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
18360         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
18361         sync
18362         cmp $tmp $dom || error "file data is different"
18363         [ $(stat -c%s $dom) == $size_tmp ] ||
18364                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
18365         if [ $space_check == 1 ]; then
18366                 local mdtfree2=$(do_facet $facet \
18367                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
18368
18369                 # increase in usage from by $size_tmp
18370                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
18371                         error "MDT free space wrong after write: " \
18372                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
18373         fi
18374
18375         # truncate
18376         local size_dom=10000
18377
18378         $TRUNCATE $dom $size_dom
18379         [ $(stat -c%s $dom) == $size_dom ] ||
18380                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
18381         if [ $space_check == 1 ]; then
18382                 mdtfree1=$(do_facet $facet \
18383                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18384                 # decrease in usage from $size_tmp to new $size_dom
18385                 [ $(($mdtfree1 - $mdtfree2)) -ge \
18386                   $(((size_tmp - size_dom) / 1024)) ] ||
18387                         error "MDT free space is wrong after truncate: " \
18388                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
18389         fi
18390
18391         # append
18392         cat $tmp >> $dom
18393         sync
18394         size_dom=$((size_dom + size_tmp))
18395         [ $(stat -c%s $dom) == $size_dom ] ||
18396                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
18397         if [ $space_check == 1 ]; then
18398                 mdtfree2=$(do_facet $facet \
18399                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18400                 # increase in usage by $size_tmp from previous
18401                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
18402                         error "MDT free space is wrong after append: " \
18403                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
18404         fi
18405
18406         # delete
18407         rm $dom
18408         if [ $space_check == 1 ]; then
18409                 mdtfree1=$(do_facet $facet \
18410                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18411                 # decrease in usage by $size_dom from previous
18412                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
18413                         error "MDT free space is wrong after removal: " \
18414                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
18415         fi
18416
18417         # combined striping
18418         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
18419                 error "Can't create DoM + OST striping"
18420
18421         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
18422         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
18423         # check also direct IO along write
18424         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
18425         sync
18426         cmp $tmp $dom || error "file data is different"
18427         [ $(stat -c%s $dom) == $size_tmp ] ||
18428                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
18429         rm $dom $tmp
18430
18431         return 0
18432 }
18433 run_test 270a "DoM: basic functionality tests"
18434
18435 test_270b() {
18436         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18437                 skip "Need MDS version at least 2.10.55"
18438
18439         local dom=$DIR/$tdir/dom_file
18440         local max_size=1048576
18441
18442         mkdir -p $DIR/$tdir
18443         $LFS setstripe -E $max_size -L mdt $dom
18444
18445         # truncate over the limit
18446         $TRUNCATE $dom $(($max_size + 1)) &&
18447                 error "successful truncate over the maximum size"
18448         # write over the limit
18449         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
18450                 error "successful write over the maximum size"
18451         # append over the limit
18452         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
18453         echo "12345" >> $dom && error "successful append over the maximum size"
18454         rm $dom
18455
18456         return 0
18457 }
18458 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
18459
18460 test_270c() {
18461         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18462                 skip "Need MDS version at least 2.10.55"
18463
18464         mkdir -p $DIR/$tdir
18465         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18466
18467         # check files inherit DoM EA
18468         touch $DIR/$tdir/first
18469         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
18470                 error "bad pattern"
18471         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
18472                 error "bad stripe count"
18473         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
18474                 error "bad stripe size"
18475
18476         # check directory inherits DoM EA and uses it as default
18477         mkdir $DIR/$tdir/subdir
18478         touch $DIR/$tdir/subdir/second
18479         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
18480                 error "bad pattern in sub-directory"
18481         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
18482                 error "bad stripe count in sub-directory"
18483         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
18484                 error "bad stripe size in sub-directory"
18485         return 0
18486 }
18487 run_test 270c "DoM: DoM EA inheritance tests"
18488
18489 test_270d() {
18490         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18491                 skip "Need MDS version at least 2.10.55"
18492
18493         mkdir -p $DIR/$tdir
18494         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18495
18496         # inherit default DoM striping
18497         mkdir $DIR/$tdir/subdir
18498         touch $DIR/$tdir/subdir/f1
18499
18500         # change default directory striping
18501         $LFS setstripe -c 1 $DIR/$tdir/subdir
18502         touch $DIR/$tdir/subdir/f2
18503         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
18504                 error "wrong default striping in file 2"
18505         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
18506                 error "bad pattern in file 2"
18507         return 0
18508 }
18509 run_test 270d "DoM: change striping from DoM to RAID0"
18510
18511 test_270e() {
18512         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18513                 skip "Need MDS version at least 2.10.55"
18514
18515         mkdir -p $DIR/$tdir/dom
18516         mkdir -p $DIR/$tdir/norm
18517         DOMFILES=20
18518         NORMFILES=10
18519         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
18520         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
18521
18522         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
18523         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
18524
18525         # find DoM files by layout
18526         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
18527         [ $NUM -eq  $DOMFILES ] ||
18528                 error "lfs find -L: found $NUM, expected $DOMFILES"
18529         echo "Test 1: lfs find 20 DOM files by layout: OK"
18530
18531         # there should be 1 dir with default DOM striping
18532         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
18533         [ $NUM -eq  1 ] ||
18534                 error "lfs find -L: found $NUM, expected 1 dir"
18535         echo "Test 2: lfs find 1 DOM dir by layout: OK"
18536
18537         # find DoM files by stripe size
18538         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
18539         [ $NUM -eq  $DOMFILES ] ||
18540                 error "lfs find -S: found $NUM, expected $DOMFILES"
18541         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
18542
18543         # find files by stripe offset except DoM files
18544         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
18545         [ $NUM -eq  $NORMFILES ] ||
18546                 error "lfs find -i: found $NUM, expected $NORMFILES"
18547         echo "Test 5: lfs find no DOM files by stripe index: OK"
18548         return 0
18549 }
18550 run_test 270e "DoM: lfs find with DoM files test"
18551
18552 test_270f() {
18553         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18554                 skip "Need MDS version at least 2.10.55"
18555
18556         local mdtname=${FSNAME}-MDT0000-mdtlov
18557         local dom=$DIR/$tdir/dom_file
18558         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
18559                                                 lod.$mdtname.dom_stripesize)
18560         local dom_limit=131072
18561
18562         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
18563         local dom_current=$(do_facet mds1 $LCTL get_param -n \
18564                                                 lod.$mdtname.dom_stripesize)
18565         [ ${dom_limit} -eq ${dom_current} ] ||
18566                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
18567
18568         $LFS mkdir -i 0 -c 1 $DIR/$tdir
18569         $LFS setstripe -d $DIR/$tdir
18570         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
18571                 error "Can't set directory default striping"
18572
18573         # exceed maximum stripe size
18574         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
18575                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
18576         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
18577                 error "Able to create DoM component size more than LOD limit"
18578
18579         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
18580         dom_current=$(do_facet mds1 $LCTL get_param -n \
18581                                                 lod.$mdtname.dom_stripesize)
18582         [ 0 -eq ${dom_current} ] ||
18583                 error "Can't set zero DoM stripe limit"
18584         rm $dom
18585
18586         # attempt to create DoM file on server with disabled DoM should
18587         # remove DoM entry from layout and be succeed
18588         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
18589                 error "Can't create DoM file (DoM is disabled)"
18590         [ $($LFS getstripe -L $dom) == "mdt" ] &&
18591                 error "File has DoM component while DoM is disabled"
18592         rm $dom
18593
18594         # attempt to create DoM file with only DoM stripe should return error
18595         $LFS setstripe -E $dom_limit -L mdt $dom &&
18596                 error "Able to create DoM-only file while DoM is disabled"
18597
18598         # too low values to be aligned with smallest stripe size 64K
18599         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
18600         dom_current=$(do_facet mds1 $LCTL get_param -n \
18601                                                 lod.$mdtname.dom_stripesize)
18602         [ 30000 -eq ${dom_current} ] &&
18603                 error "Can set too small DoM stripe limit"
18604
18605         # 64K is a minimal stripe size in Lustre, expect limit of that size
18606         [ 65536 -eq ${dom_current} ] ||
18607                 error "Limit is not set to 64K but ${dom_current}"
18608
18609         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
18610         dom_current=$(do_facet mds1 $LCTL get_param -n \
18611                                                 lod.$mdtname.dom_stripesize)
18612         echo $dom_current
18613         [ 2147483648 -eq ${dom_current} ] &&
18614                 error "Can set too large DoM stripe limit"
18615
18616         do_facet mds1 $LCTL set_param -n \
18617                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
18618         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
18619                 error "Can't create DoM component size after limit change"
18620         do_facet mds1 $LCTL set_param -n \
18621                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
18622         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
18623                 error "Can't create DoM file after limit decrease"
18624         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
18625                 error "Can create big DoM component after limit decrease"
18626         touch ${dom}_def ||
18627                 error "Can't create file with old default layout"
18628
18629         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
18630         return 0
18631 }
18632 run_test 270f "DoM: maximum DoM stripe size checks"
18633
18634 test_271a() {
18635         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18636                 skip "Need MDS version at least 2.10.55"
18637
18638         local dom=$DIR/$tdir/dom
18639
18640         mkdir -p $DIR/$tdir
18641
18642         $LFS setstripe -E 1024K -L mdt $dom
18643
18644         lctl set_param -n mdc.*.stats=clear
18645         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
18646         cat $dom > /dev/null
18647         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
18648         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
18649         ls $dom
18650         rm -f $dom
18651 }
18652 run_test 271a "DoM: data is cached for read after write"
18653
18654 test_271b() {
18655         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18656                 skip "Need MDS version at least 2.10.55"
18657
18658         local dom=$DIR/$tdir/dom
18659
18660         mkdir -p $DIR/$tdir
18661
18662         $LFS setstripe -E 1024K -L mdt -E EOF $dom
18663
18664         lctl set_param -n mdc.*.stats=clear
18665         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
18666         cancel_lru_locks mdc
18667         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
18668         # second stat to check size is cached on client
18669         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
18670         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
18671         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
18672         rm -f $dom
18673 }
18674 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
18675
18676 test_271ba() {
18677         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18678                 skip "Need MDS version at least 2.10.55"
18679
18680         local dom=$DIR/$tdir/dom
18681
18682         mkdir -p $DIR/$tdir
18683
18684         $LFS setstripe -E 1024K -L mdt -E EOF $dom
18685
18686         lctl set_param -n mdc.*.stats=clear
18687         lctl set_param -n osc.*.stats=clear
18688         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
18689         cancel_lru_locks mdc
18690         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
18691         # second stat to check size is cached on client
18692         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
18693         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
18694         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
18695         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
18696         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
18697         rm -f $dom
18698 }
18699 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
18700
18701
18702 get_mdc_stats() {
18703         local mdtidx=$1
18704         local param=$2
18705         local mdt=MDT$(printf %04x $mdtidx)
18706
18707         if [ -z $param ]; then
18708                 lctl get_param -n mdc.*$mdt*.stats
18709         else
18710                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
18711         fi
18712 }
18713
18714 test_271c() {
18715         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18716                 skip "Need MDS version at least 2.10.55"
18717
18718         local dom=$DIR/$tdir/dom
18719
18720         mkdir -p $DIR/$tdir
18721
18722         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18723
18724         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
18725         local facet=mds$((mdtidx + 1))
18726
18727         cancel_lru_locks mdc
18728         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
18729         createmany -o $dom 1000
18730         lctl set_param -n mdc.*.stats=clear
18731         smalliomany -w $dom 1000 200
18732         get_mdc_stats $mdtidx
18733         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
18734         # Each file has 1 open, 1 IO enqueues, total 2000
18735         # but now we have also +1 getxattr for security.capability, total 3000
18736         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
18737         unlinkmany $dom 1000
18738
18739         cancel_lru_locks mdc
18740         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
18741         createmany -o $dom 1000
18742         lctl set_param -n mdc.*.stats=clear
18743         smalliomany -w $dom 1000 200
18744         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
18745         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
18746         # for OPEN and IO lock.
18747         [ $((enq - enq_2)) -ge 1000 ] ||
18748                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
18749         unlinkmany $dom 1000
18750         return 0
18751 }
18752 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
18753
18754 cleanup_271def_tests() {
18755         trap 0
18756         rm -f $1
18757 }
18758
18759 test_271d() {
18760         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
18761                 skip "Need MDS version at least 2.10.57"
18762
18763         local dom=$DIR/$tdir/dom
18764         local tmp=$TMP/$tfile
18765         trap "cleanup_271def_tests $tmp" EXIT
18766
18767         mkdir -p $DIR/$tdir
18768
18769         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18770
18771         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
18772
18773         cancel_lru_locks mdc
18774         dd if=/dev/urandom of=$tmp bs=1000 count=1
18775         dd if=$tmp of=$dom bs=1000 count=1
18776         cancel_lru_locks mdc
18777
18778         cat /etc/hosts >> $tmp
18779         lctl set_param -n mdc.*.stats=clear
18780
18781         # append data to the same file it should update local page
18782         echo "Append to the same page"
18783         cat /etc/hosts >> $dom
18784         local num=$(get_mdc_stats $mdtidx ost_read)
18785         local ra=$(get_mdc_stats $mdtidx req_active)
18786         local rw=$(get_mdc_stats $mdtidx req_waittime)
18787
18788         [ -z $num ] || error "$num READ RPC occured"
18789         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18790         echo "... DONE"
18791
18792         # compare content
18793         cmp $tmp $dom || error "file miscompare"
18794
18795         cancel_lru_locks mdc
18796         lctl set_param -n mdc.*.stats=clear
18797
18798         echo "Open and read file"
18799         cat $dom > /dev/null
18800         local num=$(get_mdc_stats $mdtidx ost_read)
18801         local ra=$(get_mdc_stats $mdtidx req_active)
18802         local rw=$(get_mdc_stats $mdtidx req_waittime)
18803
18804         [ -z $num ] || error "$num READ RPC occured"
18805         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18806         echo "... DONE"
18807
18808         # compare content
18809         cmp $tmp $dom || error "file miscompare"
18810
18811         return 0
18812 }
18813 run_test 271d "DoM: read on open (1K file in reply buffer)"
18814
18815 test_271f() {
18816         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
18817                 skip "Need MDS version at least 2.10.57"
18818
18819         local dom=$DIR/$tdir/dom
18820         local tmp=$TMP/$tfile
18821         trap "cleanup_271def_tests $tmp" EXIT
18822
18823         mkdir -p $DIR/$tdir
18824
18825         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18826
18827         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
18828
18829         cancel_lru_locks mdc
18830         dd if=/dev/urandom of=$tmp bs=265000 count=1
18831         dd if=$tmp of=$dom bs=265000 count=1
18832         cancel_lru_locks mdc
18833         cat /etc/hosts >> $tmp
18834         lctl set_param -n mdc.*.stats=clear
18835
18836         echo "Append to the same page"
18837         cat /etc/hosts >> $dom
18838         local num=$(get_mdc_stats $mdtidx ost_read)
18839         local ra=$(get_mdc_stats $mdtidx req_active)
18840         local rw=$(get_mdc_stats $mdtidx req_waittime)
18841
18842         [ -z $num ] || error "$num READ RPC occured"
18843         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18844         echo "... DONE"
18845
18846         # compare content
18847         cmp $tmp $dom || error "file miscompare"
18848
18849         cancel_lru_locks mdc
18850         lctl set_param -n mdc.*.stats=clear
18851
18852         echo "Open and read file"
18853         cat $dom > /dev/null
18854         local num=$(get_mdc_stats $mdtidx ost_read)
18855         local ra=$(get_mdc_stats $mdtidx req_active)
18856         local rw=$(get_mdc_stats $mdtidx req_waittime)
18857
18858         [ -z $num ] && num=0
18859         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
18860         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18861         echo "... DONE"
18862
18863         # compare content
18864         cmp $tmp $dom || error "file miscompare"
18865
18866         return 0
18867 }
18868 run_test 271f "DoM: read on open (200K file and read tail)"
18869
18870 test_271g() {
18871         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
18872                 skip "Skipping due to old client or server version"
18873
18874         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
18875         # to get layout
18876         $CHECKSTAT -t file $DIR1/$tfile
18877
18878         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
18879         MULTIOP_PID=$!
18880         sleep 1
18881         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
18882         $LCTL set_param fail_loc=0x80000314
18883         rm $DIR1/$tfile || error "Unlink fails"
18884         RC=$?
18885         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
18886         [ $RC -eq 0 ] || error "Failed write to stale object"
18887 }
18888 run_test 271g "Discard DoM data vs client flush race"
18889
18890 test_272a() {
18891         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
18892                 skip "Need MDS version at least 2.11.50"
18893
18894         local dom=$DIR/$tdir/dom
18895         mkdir -p $DIR/$tdir
18896
18897         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
18898         dd if=/dev/urandom of=$dom bs=512K count=1 ||
18899                 error "failed to write data into $dom"
18900         local old_md5=$(md5sum $dom)
18901
18902         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
18903                 error "failed to migrate to the same DoM component"
18904
18905         local new_md5=$(md5sum $dom)
18906
18907         [ "$old_md5" == "$new_md5" ] ||
18908                 error "md5sum differ: $old_md5, $new_md5"
18909
18910         [ $($LFS getstripe -c $dom) -eq 2 ] ||
18911                 error "migrate stripe count bad: $(LFS getstripe -c $dom) != 2"
18912 }
18913 run_test 272a "DoM migration: new layout with the same DOM component"
18914
18915 test_272b() {
18916         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
18917                 skip "Need MDS version at least 2.11.50"
18918
18919         local dom=$DIR/$tdir/dom
18920         mkdir -p $DIR/$tdir
18921         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
18922
18923         local mdtidx=$($LFS getstripe -m $dom)
18924         local mdtname=MDT$(printf %04x $mdtidx)
18925         local facet=mds$((mdtidx + 1))
18926
18927         local mdtfree1=$(do_facet $facet \
18928                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18929         dd if=/dev/urandom of=$dom bs=2M count=1 ||
18930                 error "failed to write data into $dom"
18931         local old_md5=$(md5sum $dom)
18932         cancel_lru_locks mdc
18933         local mdtfree1=$(do_facet $facet \
18934                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18935
18936         $LFS migrate -c2 $dom ||
18937                 error "failed to migrate to the new composite layout"
18938         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
18939                 error "MDT stripe was not removed"
18940
18941         cancel_lru_locks mdc
18942         local new_md5=$(md5sum $dom)
18943         [ "$old_md5" == "$new_md5" ] ||
18944                 error "$old_md5 != $new_md5"
18945
18946         # Skip free space checks with ZFS
18947         if [ "$(facet_fstype $facet)" != "zfs" ]; then
18948                 local mdtfree2=$(do_facet $facet \
18949                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18950                 [ $mdtfree2 -gt $mdtfree1 ] ||
18951                         error "MDT space is not freed after migration"
18952         fi
18953         return 0
18954 }
18955 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
18956
18957 test_272c() {
18958         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
18959                 skip "Need MDS version at least 2.11.50"
18960
18961         local dom=$DIR/$tdir/$tfile
18962         mkdir -p $DIR/$tdir
18963         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
18964
18965         local mdtidx=$($LFS getstripe -m $dom)
18966         local mdtname=MDT$(printf %04x $mdtidx)
18967         local facet=mds$((mdtidx + 1))
18968
18969         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
18970                 error "failed to write data into $dom"
18971         local old_md5=$(md5sum $dom)
18972         cancel_lru_locks mdc
18973         local mdtfree1=$(do_facet $facet \
18974                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18975
18976         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
18977                 error "failed to migrate to the new composite layout"
18978         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
18979                 error "MDT stripe was not removed"
18980
18981         cancel_lru_locks mdc
18982         local new_md5=$(md5sum $dom)
18983         [ "$old_md5" == "$new_md5" ] ||
18984                 error "$old_md5 != $new_md5"
18985
18986         # Skip free space checks with ZFS
18987         if [ "$(facet_fstype $facet)" != "zfs" ]; then
18988                 local mdtfree2=$(do_facet $facet \
18989                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18990                 [ $mdtfree2 -gt $mdtfree1 ] ||
18991                         error "MDS space is not freed after migration"
18992         fi
18993         return 0
18994 }
18995 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
18996
18997 test_272d() {
18998         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
18999                 skip "Need MDS version at least 2.12.55"
19000
19001         local dom=$DIR/$tdir/$tfile
19002         mkdir -p $DIR/$tdir
19003         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
19004
19005         local mdtidx=$($LFS getstripe -m $dom)
19006         local mdtname=MDT$(printf %04x $mdtidx)
19007         local facet=mds$((mdtidx + 1))
19008
19009         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
19010                 error "failed to write data into $dom"
19011         local old_md5=$(md5sum $dom)
19012         cancel_lru_locks mdc
19013         local mdtfree1=$(do_facet $facet \
19014                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19015
19016         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
19017                 error "failed mirroring to the new composite layout"
19018         $LFS mirror resync $dom ||
19019                 error "failed mirror resync"
19020         $LFS mirror split --mirror-id 1 -d $dom ||
19021                 error "failed mirror split"
19022
19023         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
19024                 error "MDT stripe was not removed"
19025
19026         cancel_lru_locks mdc
19027         local new_md5=$(md5sum $dom)
19028         [ "$old_md5" == "$new_md5" ] ||
19029                 error "$old_md5 != $new_md5"
19030
19031         # Skip free space checks with ZFS
19032         if [ "$(facet_fstype $facet)" != "zfs" ]; then
19033                 local mdtfree2=$(do_facet $facet \
19034                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19035                 [ $mdtfree2 -gt $mdtfree1 ] ||
19036                         error "MDS space is not freed after DOM mirror deletion"
19037         fi
19038         return 0
19039 }
19040 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
19041
19042 test_272e() {
19043         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
19044                 skip "Need MDS version at least 2.12.55"
19045
19046         local dom=$DIR/$tdir/$tfile
19047         mkdir -p $DIR/$tdir
19048         $LFS setstripe -c 2 $dom
19049
19050         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
19051                 error "failed to write data into $dom"
19052         local old_md5=$(md5sum $dom)
19053         cancel_lru_locks mdc
19054
19055         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
19056                 error "failed mirroring to the DOM layout"
19057         $LFS mirror resync $dom ||
19058                 error "failed mirror resync"
19059         $LFS mirror split --mirror-id 1 -d $dom ||
19060                 error "failed mirror split"
19061
19062         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
19063                 error "MDT stripe was not removed"
19064
19065         cancel_lru_locks mdc
19066         local new_md5=$(md5sum $dom)
19067         [ "$old_md5" == "$new_md5" ] ||
19068                 error "$old_md5 != $new_md5"
19069
19070         return 0
19071 }
19072 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
19073
19074 test_272f() {
19075         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
19076                 skip "Need MDS version at least 2.12.55"
19077
19078         local dom=$DIR/$tdir/$tfile
19079         mkdir -p $DIR/$tdir
19080         $LFS setstripe -c 2 $dom
19081
19082         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
19083                 error "failed to write data into $dom"
19084         local old_md5=$(md5sum $dom)
19085         cancel_lru_locks mdc
19086
19087         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
19088                 error "failed migrating to the DOM file"
19089
19090         cancel_lru_locks mdc
19091         local new_md5=$(md5sum $dom)
19092         [ "$old_md5" != "$new_md5" ] &&
19093                 error "$old_md5 != $new_md5"
19094
19095         return 0
19096 }
19097 run_test 272f "DoM migration: OST-striped file to DOM file"
19098
19099 test_273a() {
19100         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
19101                 skip "Need MDS version at least 2.11.50"
19102
19103         # Layout swap cannot be done if either file has DOM component,
19104         # this will never be supported, migration should be used instead
19105
19106         local dom=$DIR/$tdir/$tfile
19107         mkdir -p $DIR/$tdir
19108
19109         $LFS setstripe -c2 ${dom}_plain
19110         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
19111         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
19112                 error "can swap layout with DoM component"
19113         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
19114                 error "can swap layout with DoM component"
19115
19116         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
19117         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
19118                 error "can swap layout with DoM component"
19119         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
19120                 error "can swap layout with DoM component"
19121         return 0
19122 }
19123 run_test 273a "DoM: layout swapping should fail with DOM"
19124
19125 test_275() {
19126         remote_ost_nodsh && skip "remote OST with nodsh"
19127         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
19128                 skip "Need OST version >= 2.10.57"
19129
19130         local file=$DIR/$tfile
19131         local oss
19132
19133         oss=$(comma_list $(osts_nodes))
19134
19135         dd if=/dev/urandom of=$file bs=1M count=2 ||
19136                 error "failed to create a file"
19137         cancel_lru_locks osc
19138
19139         #lock 1
19140         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
19141                 error "failed to read a file"
19142
19143 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
19144         $LCTL set_param fail_loc=0x8000031f
19145
19146         cancel_lru_locks osc &
19147         sleep 1
19148
19149 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
19150         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
19151         #IO takes another lock, but matches the PENDING one
19152         #and places it to the IO RPC
19153         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
19154                 error "failed to read a file with PENDING lock"
19155 }
19156 run_test 275 "Read on a canceled duplicate lock"
19157
19158 test_276() {
19159         remote_ost_nodsh && skip "remote OST with nodsh"
19160         local pid
19161
19162         do_facet ost1 "(while true; do \
19163                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
19164                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
19165         pid=$!
19166
19167         for LOOP in $(seq 20); do
19168                 stop ost1
19169                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
19170         done
19171         kill -9 $pid
19172         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
19173                 rm $TMP/sanity_276_pid"
19174 }
19175 run_test 276 "Race between mount and obd_statfs"
19176
19177 test_277() {
19178         $LCTL set_param ldlm.namespaces.*.lru_size=0
19179         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
19180         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
19181                         grep ^used_mb | awk '{print $2}')
19182         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
19183         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
19184                 oflag=direct conv=notrunc
19185         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
19186                         grep ^used_mb | awk '{print $2}')
19187         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
19188 }
19189 run_test 277 "Direct IO shall drop page cache"
19190
19191 test_278() {
19192         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
19193         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
19194         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
19195                 skip "needs the same host for mdt1 mdt2" && return
19196
19197         local pid1
19198         local pid2
19199
19200 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
19201         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
19202         stop mds2 &
19203         pid2=$!
19204
19205         stop mds1
19206
19207         echo "Starting MDTs"
19208         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
19209         wait $pid2
19210 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
19211 #will return NULL
19212         do_facet mds2 $LCTL set_param fail_loc=0
19213
19214         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
19215         wait_recovery_complete mds2
19216 }
19217 run_test 278 "Race starting MDS between MDTs stop/start"
19218
19219 cleanup_test_300() {
19220         trap 0
19221         umask $SAVE_UMASK
19222 }
19223 test_striped_dir() {
19224         local mdt_index=$1
19225         local stripe_count
19226         local stripe_index
19227
19228         mkdir -p $DIR/$tdir
19229
19230         SAVE_UMASK=$(umask)
19231         trap cleanup_test_300 RETURN EXIT
19232
19233         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
19234                                                 $DIR/$tdir/striped_dir ||
19235                 error "set striped dir error"
19236
19237         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
19238         [ "$mode" = "755" ] || error "expect 755 got $mode"
19239
19240         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
19241                 error "getdirstripe failed"
19242         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
19243         if [ "$stripe_count" != "2" ]; then
19244                 error "1:stripe_count is $stripe_count, expect 2"
19245         fi
19246         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
19247         if [ "$stripe_count" != "2" ]; then
19248                 error "2:stripe_count is $stripe_count, expect 2"
19249         fi
19250
19251         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
19252         if [ "$stripe_index" != "$mdt_index" ]; then
19253                 error "stripe_index is $stripe_index, expect $mdt_index"
19254         fi
19255
19256         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
19257                 error "nlink error after create striped dir"
19258
19259         mkdir $DIR/$tdir/striped_dir/a
19260         mkdir $DIR/$tdir/striped_dir/b
19261
19262         stat $DIR/$tdir/striped_dir/a ||
19263                 error "create dir under striped dir failed"
19264         stat $DIR/$tdir/striped_dir/b ||
19265                 error "create dir under striped dir failed"
19266
19267         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
19268                 error "nlink error after mkdir"
19269
19270         rmdir $DIR/$tdir/striped_dir/a
19271         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
19272                 error "nlink error after rmdir"
19273
19274         rmdir $DIR/$tdir/striped_dir/b
19275         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
19276                 error "nlink error after rmdir"
19277
19278         chattr +i $DIR/$tdir/striped_dir
19279         createmany -o $DIR/$tdir/striped_dir/f 10 &&
19280                 error "immutable flags not working under striped dir!"
19281         chattr -i $DIR/$tdir/striped_dir
19282
19283         rmdir $DIR/$tdir/striped_dir ||
19284                 error "rmdir striped dir error"
19285
19286         cleanup_test_300
19287
19288         true
19289 }
19290
19291 test_300a() {
19292         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
19293                 skip "skipped for lustre < 2.7.0"
19294         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19295         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19296
19297         test_striped_dir 0 || error "failed on striped dir on MDT0"
19298         test_striped_dir 1 || error "failed on striped dir on MDT0"
19299 }
19300 run_test 300a "basic striped dir sanity test"
19301
19302 test_300b() {
19303         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
19304                 skip "skipped for lustre < 2.7.0"
19305         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19306         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19307
19308         local i
19309         local mtime1
19310         local mtime2
19311         local mtime3
19312
19313         test_mkdir $DIR/$tdir || error "mkdir fail"
19314         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
19315                 error "set striped dir error"
19316         for i in {0..9}; do
19317                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
19318                 sleep 1
19319                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
19320                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
19321                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
19322                 sleep 1
19323                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
19324                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
19325                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
19326         done
19327         true
19328 }
19329 run_test 300b "check ctime/mtime for striped dir"
19330
19331 test_300c() {
19332         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
19333                 skip "skipped for lustre < 2.7.0"
19334         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19335         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19336
19337         local file_count
19338
19339         mkdir -p $DIR/$tdir
19340         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
19341                 error "set striped dir error"
19342
19343         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
19344                 error "chown striped dir failed"
19345
19346         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
19347                 error "create 5k files failed"
19348
19349         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
19350
19351         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
19352
19353         rm -rf $DIR/$tdir
19354 }
19355 run_test 300c "chown && check ls under striped directory"
19356
19357 test_300d() {
19358         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
19359                 skip "skipped for lustre < 2.7.0"
19360         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19361         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19362
19363         local stripe_count
19364         local file
19365
19366         mkdir -p $DIR/$tdir
19367         $LFS setstripe -c 2 $DIR/$tdir
19368
19369         #local striped directory
19370         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
19371                 error "set striped dir error"
19372         createmany -o $DIR/$tdir/striped_dir/f 10 ||
19373                 error "create 10 files failed"
19374
19375         #remote striped directory
19376         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
19377                 error "set striped dir error"
19378         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
19379                 error "create 10 files failed"
19380
19381         for file in $(find $DIR/$tdir); do
19382                 stripe_count=$($LFS getstripe -c $file)
19383                 [ $stripe_count -eq 2 ] ||
19384                         error "wrong stripe $stripe_count for $file"
19385         done
19386
19387         rm -rf $DIR/$tdir
19388 }
19389 run_test 300d "check default stripe under striped directory"
19390
19391 test_300e() {
19392         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19393                 skip "Need MDS version at least 2.7.55"
19394         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19395         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19396
19397         local stripe_count
19398         local file
19399
19400         mkdir -p $DIR/$tdir
19401
19402         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
19403                 error "set striped dir error"
19404
19405         touch $DIR/$tdir/striped_dir/a
19406         touch $DIR/$tdir/striped_dir/b
19407         touch $DIR/$tdir/striped_dir/c
19408
19409         mkdir $DIR/$tdir/striped_dir/dir_a
19410         mkdir $DIR/$tdir/striped_dir/dir_b
19411         mkdir $DIR/$tdir/striped_dir/dir_c
19412
19413         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
19414                 error "set striped adir under striped dir error"
19415
19416         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
19417                 error "set striped bdir under striped dir error"
19418
19419         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
19420                 error "set striped cdir under striped dir error"
19421
19422         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
19423                 error "rename dir under striped dir fails"
19424
19425         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
19426                 error "rename dir under different stripes fails"
19427
19428         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
19429                 error "rename file under striped dir should succeed"
19430
19431         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
19432                 error "rename dir under striped dir should succeed"
19433
19434         rm -rf $DIR/$tdir
19435 }
19436 run_test 300e "check rename under striped directory"
19437
19438 test_300f() {
19439         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19440         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19441         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19442                 skip "Need MDS version at least 2.7.55"
19443
19444         local stripe_count
19445         local file
19446
19447         rm -rf $DIR/$tdir
19448         mkdir -p $DIR/$tdir
19449
19450         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
19451                 error "set striped dir error"
19452
19453         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
19454                 error "set striped dir error"
19455
19456         touch $DIR/$tdir/striped_dir/a
19457         mkdir $DIR/$tdir/striped_dir/dir_a
19458         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
19459                 error "create striped dir under striped dir fails"
19460
19461         touch $DIR/$tdir/striped_dir1/b
19462         mkdir $DIR/$tdir/striped_dir1/dir_b
19463         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
19464                 error "create striped dir under striped dir fails"
19465
19466         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
19467                 error "rename dir under different striped dir should fail"
19468
19469         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
19470                 error "rename striped dir under diff striped dir should fail"
19471
19472         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
19473                 error "rename file under diff striped dirs fails"
19474
19475         rm -rf $DIR/$tdir
19476 }
19477 run_test 300f "check rename cross striped directory"
19478
19479 test_300_check_default_striped_dir()
19480 {
19481         local dirname=$1
19482         local default_count=$2
19483         local default_index=$3
19484         local stripe_count
19485         local stripe_index
19486         local dir_stripe_index
19487         local dir
19488
19489         echo "checking $dirname $default_count $default_index"
19490         $LFS setdirstripe -D -c $default_count -i $default_index \
19491                                 -t all_char $DIR/$tdir/$dirname ||
19492                 error "set default stripe on striped dir error"
19493         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
19494         [ $stripe_count -eq $default_count ] ||
19495                 error "expect $default_count get $stripe_count for $dirname"
19496
19497         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
19498         [ $stripe_index -eq $default_index ] ||
19499                 error "expect $default_index get $stripe_index for $dirname"
19500
19501         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
19502                                                 error "create dirs failed"
19503
19504         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
19505         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
19506         for dir in $(find $DIR/$tdir/$dirname/*); do
19507                 stripe_count=$($LFS getdirstripe -c $dir)
19508                 [ $stripe_count -eq $default_count ] ||
19509                 [ $stripe_count -eq 0 ] || [ $default_count -eq 1 ] ||
19510                 error "stripe count $default_count != $stripe_count for $dir"
19511
19512                 stripe_index=$($LFS getdirstripe -i $dir)
19513                 [ $default_index -eq -1 ] ||
19514                         [ $stripe_index -eq $default_index ] ||
19515                         error "$stripe_index != $default_index for $dir"
19516
19517                 #check default stripe
19518                 stripe_count=$($LFS getdirstripe -D -c $dir)
19519                 [ $stripe_count -eq $default_count ] ||
19520                 error "default count $default_count != $stripe_count for $dir"
19521
19522                 stripe_index=$($LFS getdirstripe -D -i $dir)
19523                 [ $stripe_index -eq $default_index ] ||
19524                 error "default index $default_index != $stripe_index for $dir"
19525         done
19526         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
19527 }
19528
19529 test_300g() {
19530         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19531         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19532                 skip "Need MDS version at least 2.7.55"
19533
19534         local dir
19535         local stripe_count
19536         local stripe_index
19537
19538         mkdir $DIR/$tdir
19539         mkdir $DIR/$tdir/normal_dir
19540
19541         #Checking when client cache stripe index
19542         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
19543         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
19544                 error "create striped_dir failed"
19545
19546         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
19547                 error "create dir0 fails"
19548         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
19549         [ $stripe_index -eq 0 ] ||
19550                 error "dir0 expect index 0 got $stripe_index"
19551
19552         mkdir $DIR/$tdir/striped_dir/dir1 ||
19553                 error "create dir1 fails"
19554         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
19555         [ $stripe_index -eq 1 ] ||
19556                 error "dir1 expect index 1 got $stripe_index"
19557
19558         #check default stripe count/stripe index
19559         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
19560         test_300_check_default_striped_dir normal_dir 1 0
19561         test_300_check_default_striped_dir normal_dir 2 1
19562         test_300_check_default_striped_dir normal_dir 2 -1
19563
19564         #delete default stripe information
19565         echo "delete default stripeEA"
19566         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
19567                 error "set default stripe on striped dir error"
19568
19569         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
19570         for dir in $(find $DIR/$tdir/normal_dir/*); do
19571                 stripe_count=$($LFS getdirstripe -c $dir)
19572                 [ $stripe_count -eq 0 ] ||
19573                         error "expect 1 get $stripe_count for $dir"
19574                 stripe_index=$($LFS getdirstripe -i $dir)
19575                 [ $stripe_index -eq 0 ] ||
19576                         error "expect 0 get $stripe_index for $dir"
19577         done
19578 }
19579 run_test 300g "check default striped directory for normal directory"
19580
19581 test_300h() {
19582         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19583         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19584                 skip "Need MDS version at least 2.7.55"
19585
19586         local dir
19587         local stripe_count
19588
19589         mkdir $DIR/$tdir
19590         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
19591                 error "set striped dir error"
19592
19593         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
19594         test_300_check_default_striped_dir striped_dir 1 0
19595         test_300_check_default_striped_dir striped_dir 2 1
19596         test_300_check_default_striped_dir striped_dir 2 -1
19597
19598         #delete default stripe information
19599         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
19600                 error "set default stripe on striped dir error"
19601
19602         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
19603         for dir in $(find $DIR/$tdir/striped_dir/*); do
19604                 stripe_count=$($LFS getdirstripe -c $dir)
19605                 [ $stripe_count -eq 0 ] ||
19606                         error "expect 1 get $stripe_count for $dir"
19607         done
19608 }
19609 run_test 300h "check default striped directory for striped directory"
19610
19611 test_300i() {
19612         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19613         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19614         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19615                 skip "Need MDS version at least 2.7.55"
19616
19617         local stripe_count
19618         local file
19619
19620         mkdir $DIR/$tdir
19621
19622         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
19623                 error "set striped dir error"
19624
19625         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
19626                 error "create files under striped dir failed"
19627
19628         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
19629                 error "set striped hashdir error"
19630
19631         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
19632                 error "create dir0 under hash dir failed"
19633         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
19634                 error "create dir1 under hash dir failed"
19635
19636         # unfortunately, we need to umount to clear dir layout cache for now
19637         # once we fully implement dir layout, we can drop this
19638         umount_client $MOUNT || error "umount failed"
19639         mount_client $MOUNT || error "mount failed"
19640
19641         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
19642         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
19643         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
19644
19645         #set the stripe to be unknown hash type
19646         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
19647         $LCTL set_param fail_loc=0x1901
19648         for ((i = 0; i < 10; i++)); do
19649                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
19650                         error "stat f-$i failed"
19651                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
19652         done
19653
19654         touch $DIR/$tdir/striped_dir/f0 &&
19655                 error "create under striped dir with unknown hash should fail"
19656
19657         $LCTL set_param fail_loc=0
19658
19659         umount_client $MOUNT || error "umount failed"
19660         mount_client $MOUNT || error "mount failed"
19661
19662         return 0
19663 }
19664 run_test 300i "client handle unknown hash type striped directory"
19665
19666 test_300j() {
19667         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19668         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19669         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19670                 skip "Need MDS version at least 2.7.55"
19671
19672         local stripe_count
19673         local file
19674
19675         mkdir $DIR/$tdir
19676
19677         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
19678         $LCTL set_param fail_loc=0x1702
19679         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
19680                 error "set striped dir error"
19681
19682         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
19683                 error "create files under striped dir failed"
19684
19685         $LCTL set_param fail_loc=0
19686
19687         rm -rf $DIR/$tdir || error "unlink striped dir fails"
19688
19689         return 0
19690 }
19691 run_test 300j "test large update record"
19692
19693 test_300k() {
19694         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19695         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19696         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19697                 skip "Need MDS version at least 2.7.55"
19698
19699         # this test needs a huge transaction
19700         local kb
19701         kb=$(do_facet $SINGLEMDS lctl get_param -n osd*.lustre-MDT0000.kbytestotal)
19702         [ $kb -lt $((1024*1024)) ] && skip "too small mds: $kb"
19703
19704         local stripe_count
19705         local file
19706
19707         mkdir $DIR/$tdir
19708
19709         #define OBD_FAIL_LARGE_STRIPE   0x1703
19710         $LCTL set_param fail_loc=0x1703
19711         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
19712                 error "set striped dir error"
19713         $LCTL set_param fail_loc=0
19714
19715         $LFS getdirstripe $DIR/$tdir/striped_dir ||
19716                 error "getstripeddir fails"
19717         rm -rf $DIR/$tdir/striped_dir ||
19718                 error "unlink striped dir fails"
19719
19720         return 0
19721 }
19722 run_test 300k "test large striped directory"
19723
19724 test_300l() {
19725         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19726         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19727         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19728                 skip "Need MDS version at least 2.7.55"
19729
19730         local stripe_index
19731
19732         test_mkdir -p $DIR/$tdir/striped_dir
19733         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
19734                         error "chown $RUNAS_ID failed"
19735         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
19736                 error "set default striped dir failed"
19737
19738         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
19739         $LCTL set_param fail_loc=0x80000158
19740         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
19741
19742         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
19743         [ $stripe_index -eq 1 ] ||
19744                 error "expect 1 get $stripe_index for $dir"
19745 }
19746 run_test 300l "non-root user to create dir under striped dir with stale layout"
19747
19748 test_300m() {
19749         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19750         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
19751         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19752                 skip "Need MDS version at least 2.7.55"
19753
19754         mkdir -p $DIR/$tdir/striped_dir
19755         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
19756                 error "set default stripes dir error"
19757
19758         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
19759
19760         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
19761         [ $stripe_count -eq 0 ] ||
19762                         error "expect 0 get $stripe_count for a"
19763
19764         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
19765                 error "set default stripes dir error"
19766
19767         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
19768
19769         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
19770         [ $stripe_count -eq 0 ] ||
19771                         error "expect 0 get $stripe_count for b"
19772
19773         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
19774                 error "set default stripes dir error"
19775
19776         mkdir $DIR/$tdir/striped_dir/c &&
19777                 error "default stripe_index is invalid, mkdir c should fails"
19778
19779         rm -rf $DIR/$tdir || error "rmdir fails"
19780 }
19781 run_test 300m "setstriped directory on single MDT FS"
19782
19783 cleanup_300n() {
19784         local list=$(comma_list $(mdts_nodes))
19785
19786         trap 0
19787         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
19788 }
19789
19790 test_300n() {
19791         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19792         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19793         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19794                 skip "Need MDS version at least 2.7.55"
19795         remote_mds_nodsh && skip "remote MDS with nodsh"
19796
19797         local stripe_index
19798         local list=$(comma_list $(mdts_nodes))
19799
19800         trap cleanup_300n RETURN EXIT
19801         mkdir -p $DIR/$tdir
19802         chmod 777 $DIR/$tdir
19803         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
19804                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
19805                 error "create striped dir succeeds with gid=0"
19806
19807         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
19808         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
19809                 error "create striped dir fails with gid=-1"
19810
19811         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
19812         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
19813                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
19814                 error "set default striped dir succeeds with gid=0"
19815
19816
19817         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
19818         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
19819                 error "set default striped dir fails with gid=-1"
19820
19821
19822         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
19823         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
19824                                         error "create test_dir fails"
19825         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
19826                                         error "create test_dir1 fails"
19827         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
19828                                         error "create test_dir2 fails"
19829         cleanup_300n
19830 }
19831 run_test 300n "non-root user to create dir under striped dir with default EA"
19832
19833 test_300o() {
19834         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19835         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19836         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19837                 skip "Need MDS version at least 2.7.55"
19838
19839         local numfree1
19840         local numfree2
19841
19842         mkdir -p $DIR/$tdir
19843
19844         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
19845         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
19846         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
19847                 skip "not enough free inodes $numfree1 $numfree2"
19848         fi
19849
19850         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
19851         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
19852         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
19853                 skip "not enough free space $numfree1 $numfree2"
19854         fi
19855
19856         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
19857                 error "setdirstripe fails"
19858
19859         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
19860                 error "create dirs fails"
19861
19862         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
19863         ls $DIR/$tdir/striped_dir > /dev/null ||
19864                 error "ls striped dir fails"
19865         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
19866                 error "unlink big striped dir fails"
19867 }
19868 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
19869
19870 test_300p() {
19871         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19872         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19873         remote_mds_nodsh && skip "remote MDS with nodsh"
19874
19875         mkdir -p $DIR/$tdir
19876
19877         #define OBD_FAIL_OUT_ENOSPC     0x1704
19878         do_facet mds2 lctl set_param fail_loc=0x80001704
19879         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
19880                  && error "create striped directory should fail"
19881
19882         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
19883
19884         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
19885         true
19886 }
19887 run_test 300p "create striped directory without space"
19888
19889 test_300q() {
19890         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19891         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19892
19893         local fd=$(free_fd)
19894         local cmd="exec $fd<$tdir"
19895         cd $DIR
19896         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
19897         eval $cmd
19898         cmd="exec $fd<&-"
19899         trap "eval $cmd" EXIT
19900         cd $tdir || error "cd $tdir fails"
19901         rmdir  ../$tdir || error "rmdir $tdir fails"
19902         mkdir local_dir && error "create dir succeeds"
19903         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
19904         eval $cmd
19905         return 0
19906 }
19907 run_test 300q "create remote directory under orphan directory"
19908
19909 test_300r() {
19910         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.7.55) ] &&
19911                 skip "Need MDS version at least 2.7.55" && return
19912         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
19913
19914         mkdir $DIR/$tdir
19915
19916         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
19917                 error "set striped dir error"
19918
19919         $LFS getdirstripe $DIR/$tdir/striped_dir ||
19920                 error "getstripeddir fails"
19921
19922         local stripe_count
19923         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
19924                       awk '/lmv_stripe_count:/ { print $2 }')
19925
19926         [ $MDSCOUNT -ne $stripe_count ] &&
19927                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
19928
19929         rm -rf $DIR/$tdir/striped_dir ||
19930                 error "unlink striped dir fails"
19931 }
19932 run_test 300r "test -1 striped directory"
19933
19934 prepare_remote_file() {
19935         mkdir $DIR/$tdir/src_dir ||
19936                 error "create remote source failed"
19937
19938         cp /etc/hosts $DIR/$tdir/src_dir/a ||
19939                  error "cp to remote source failed"
19940         touch $DIR/$tdir/src_dir/a
19941
19942         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
19943                 error "create remote target dir failed"
19944
19945         touch $DIR/$tdir/tgt_dir/b
19946
19947         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
19948                 error "rename dir cross MDT failed!"
19949
19950         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
19951                 error "src_child still exists after rename"
19952
19953         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
19954                 error "missing file(a) after rename"
19955
19956         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
19957                 error "diff after rename"
19958 }
19959
19960 test_310a() {
19961         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
19962         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19963
19964         local remote_file=$DIR/$tdir/tgt_dir/b
19965
19966         mkdir -p $DIR/$tdir
19967
19968         prepare_remote_file || error "prepare remote file failed"
19969
19970         #open-unlink file
19971         $OPENUNLINK $remote_file $remote_file ||
19972                 error "openunlink $remote_file failed"
19973         $CHECKSTAT -a $remote_file || error "$remote_file exists"
19974 }
19975 run_test 310a "open unlink remote file"
19976
19977 test_310b() {
19978         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
19979         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19980
19981         local remote_file=$DIR/$tdir/tgt_dir/b
19982
19983         mkdir -p $DIR/$tdir
19984
19985         prepare_remote_file || error "prepare remote file failed"
19986
19987         ln $remote_file $DIR/$tfile || error "link failed for remote file"
19988         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
19989         $CHECKSTAT -t file $remote_file || error "check file failed"
19990 }
19991 run_test 310b "unlink remote file with multiple links while open"
19992
19993 test_310c() {
19994         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19995         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
19996
19997         local remote_file=$DIR/$tdir/tgt_dir/b
19998
19999         mkdir -p $DIR/$tdir
20000
20001         prepare_remote_file || error "prepare remote file failed"
20002
20003         ln $remote_file $DIR/$tfile || error "link failed for remote file"
20004         multiop_bg_pause $remote_file O_uc ||
20005                         error "mulitop failed for remote file"
20006         MULTIPID=$!
20007         $MULTIOP $DIR/$tfile Ouc
20008         kill -USR1 $MULTIPID
20009         wait $MULTIPID
20010 }
20011 run_test 310c "open-unlink remote file with multiple links"
20012
20013 #LU-4825
20014 test_311() {
20015         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20016         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
20017         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
20018                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
20019         remote_mds_nodsh && skip "remote MDS with nodsh"
20020
20021         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
20022         local mdts=$(comma_list $(mdts_nodes))
20023
20024         mkdir -p $DIR/$tdir
20025         $LFS setstripe -i 0 -c 1 $DIR/$tdir
20026         createmany -o $DIR/$tdir/$tfile. 1000
20027
20028         # statfs data is not real time, let's just calculate it
20029         old_iused=$((old_iused + 1000))
20030
20031         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
20032                         osp.*OST0000*MDT0000.create_count")
20033         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
20034                                 osp.*OST0000*MDT0000.max_create_count")
20035         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
20036
20037         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
20038         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
20039         [ $index -ne 0 ] || error "$tfile stripe index is 0"
20040
20041         unlinkmany $DIR/$tdir/$tfile. 1000
20042
20043         do_nodes $mdts "$LCTL set_param -n \
20044                         osp.*OST0000*.max_create_count=$max_count"
20045         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
20046                 do_nodes $mdts "$LCTL set_param -n \
20047                                 osp.*OST0000*.create_count=$count"
20048         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
20049                         grep "=0" && error "create_count is zero"
20050
20051         local new_iused
20052         for i in $(seq 120); do
20053                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
20054                 # system may be too busy to destroy all objs in time, use
20055                 # a somewhat small value to not fail autotest
20056                 [ $((old_iused - new_iused)) -gt 400 ] && break
20057                 sleep 1
20058         done
20059
20060         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
20061         [ $((old_iused - new_iused)) -gt 400 ] ||
20062                 error "objs not destroyed after unlink"
20063 }
20064 run_test 311 "disable OSP precreate, and unlink should destroy objs"
20065
20066 zfs_oid_to_objid()
20067 {
20068         local ost=$1
20069         local objid=$2
20070
20071         local vdevdir=$(dirname $(facet_vdevice $ost))
20072         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
20073         local zfs_zapid=$(do_facet $ost $cmd |
20074                           grep -w "/O/0/d$((objid%32))" -C 5 |
20075                           awk '/Object/{getline; print $1}')
20076         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
20077                           awk "/$objid = /"'{printf $3}')
20078
20079         echo $zfs_objid
20080 }
20081
20082 zfs_object_blksz() {
20083         local ost=$1
20084         local objid=$2
20085
20086         local vdevdir=$(dirname $(facet_vdevice $ost))
20087         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
20088         local blksz=$(do_facet $ost $cmd $objid |
20089                       awk '/dblk/{getline; printf $4}')
20090
20091         case "${blksz: -1}" in
20092                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
20093                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
20094                 *) ;;
20095         esac
20096
20097         echo $blksz
20098 }
20099
20100 test_312() { # LU-4856
20101         remote_ost_nodsh && skip "remote OST with nodsh"
20102         [ "$ost1_FSTYPE" = "zfs" ] ||
20103                 skip_env "the test only applies to zfs"
20104
20105         local max_blksz=$(do_facet ost1 \
20106                           $ZFS get -p recordsize $(facet_device ost1) |
20107                           awk '!/VALUE/{print $3}')
20108
20109         # to make life a little bit easier
20110         $LFS mkdir -c 1 -i 0 $DIR/$tdir
20111         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20112
20113         local tf=$DIR/$tdir/$tfile
20114         touch $tf
20115         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
20116
20117         # Get ZFS object id
20118         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
20119         # block size change by sequential overwrite
20120         local bs
20121
20122         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
20123                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
20124
20125                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
20126                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
20127         done
20128         rm -f $tf
20129
20130         # block size change by sequential append write
20131         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
20132         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
20133         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
20134         local count
20135
20136         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
20137                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
20138                         oflag=sync conv=notrunc
20139
20140                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
20141                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
20142                         error "blksz error, actual $blksz, " \
20143                                 "expected: 2 * $count * $PAGE_SIZE"
20144         done
20145         rm -f $tf
20146
20147         # random write
20148         touch $tf
20149         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
20150         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
20151
20152         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
20153         blksz=$(zfs_object_blksz ost1 $zfs_objid)
20154         [ $blksz -eq $PAGE_SIZE ] ||
20155                 error "blksz error: $blksz, expected: $PAGE_SIZE"
20156
20157         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
20158         blksz=$(zfs_object_blksz ost1 $zfs_objid)
20159         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
20160
20161         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
20162         blksz=$(zfs_object_blksz ost1 $zfs_objid)
20163         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
20164 }
20165 run_test 312 "make sure ZFS adjusts its block size by write pattern"
20166
20167 test_313() {
20168         remote_ost_nodsh && skip "remote OST with nodsh"
20169
20170         local file=$DIR/$tfile
20171
20172         rm -f $file
20173         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
20174
20175         # define OBD_FAIL_TGT_RCVD_EIO           0x720
20176         do_facet ost1 "$LCTL set_param fail_loc=0x720"
20177         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
20178                 error "write should failed"
20179         do_facet ost1 "$LCTL set_param fail_loc=0"
20180         rm -f $file
20181 }
20182 run_test 313 "io should fail after last_rcvd update fail"
20183
20184 test_314() {
20185         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
20186
20187         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
20188         do_facet ost1 "$LCTL set_param fail_loc=0x720"
20189         rm -f $DIR/$tfile
20190         wait_delete_completed
20191         do_facet ost1 "$LCTL set_param fail_loc=0"
20192 }
20193 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
20194
20195 test_315() { # LU-618
20196         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
20197
20198         local file=$DIR/$tfile
20199         rm -f $file
20200
20201         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
20202                 error "multiop file write failed"
20203         $MULTIOP $file oO_RDONLY:r4063232_c &
20204         PID=$!
20205
20206         sleep 2
20207
20208         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
20209         kill -USR1 $PID
20210
20211         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
20212         rm -f $file
20213 }
20214 run_test 315 "read should be accounted"
20215
20216 test_316() {
20217         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20218         large_xattr_enabled || skip_env "ea_inode feature disabled"
20219
20220         rm -rf $DIR/$tdir/d
20221         mkdir -p $DIR/$tdir/d
20222         chown nobody $DIR/$tdir/d
20223         touch $DIR/$tdir/d/file
20224
20225         $LFS mv -M1 $DIR/$tdir/d || error "lfs mv failed"
20226 }
20227 run_test 316 "lfs mv"
20228
20229 test_317() {
20230         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
20231                 skip "Need MDS version at least 2.11.53"
20232         if [ "$ost1_FSTYPE" == "zfs" ]; then
20233                 skip "LU-10370: no implementation for ZFS"
20234         fi
20235
20236         local trunc_sz
20237         local grant_blk_size
20238
20239         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
20240                         awk '/grant_block_size:/ { print $2; exit; }')
20241         #
20242         # Create File of size 5M. Truncate it to below size's and verify
20243         # blocks count.
20244         #
20245         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
20246                 error "Create file $DIR/$tfile failed"
20247         stack_trap "rm -f $DIR/$tfile" EXIT
20248
20249         for trunc_sz in 2097152 4097 4000 509 0; do
20250                 $TRUNCATE $DIR/$tfile $trunc_sz ||
20251                         error "truncate $tfile to $trunc_sz failed"
20252                 local sz=$(stat --format=%s $DIR/$tfile)
20253                 local blk=$(stat --format=%b $DIR/$tfile)
20254                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
20255                                      grant_blk_size) * 8))
20256
20257                 if [[ $blk -ne $trunc_blk ]]; then
20258                         $(which stat) $DIR/$tfile
20259                         error "Expected Block $trunc_blk got $blk for $tfile"
20260                 fi
20261
20262                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
20263                         error "Expected Size $trunc_sz got $sz for $tfile"
20264         done
20265
20266         #
20267         # sparse file test
20268         # Create file with a hole and write actual two blocks. Block count
20269         # must be 16.
20270         #
20271         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
20272                 conv=fsync || error "Create file : $DIR/$tfile"
20273
20274         # Calculate the final truncate size.
20275         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
20276
20277         #
20278         # truncate to size $trunc_sz bytes. Strip the last block
20279         # The block count must drop to 8
20280         #
20281         $TRUNCATE $DIR/$tfile $trunc_sz ||
20282                 error "truncate $tfile to $trunc_sz failed"
20283
20284         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
20285         sz=$(stat --format=%s $DIR/$tfile)
20286         blk=$(stat --format=%b $DIR/$tfile)
20287
20288         if [[ $blk -ne $trunc_bsz ]]; then
20289                 $(which stat) $DIR/$tfile
20290                 error "Expected Block $trunc_bsz got $blk for $tfile"
20291         fi
20292
20293         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
20294                 error "Expected Size $trunc_sz got $sz for $tfile"
20295 }
20296 run_test 317 "Verify blocks get correctly update after truncate"
20297
20298 test_318() {
20299         local old_max_active=$($LCTL get_param -n \
20300                             llite.*.max_read_ahead_async_active 2>/dev/null)
20301
20302         $LCTL set_param llite.*.max_read_ahead_async_active=256
20303         local max_active=$($LCTL get_param -n \
20304                            llite.*.max_read_ahead_async_active 2>/dev/null)
20305         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
20306
20307         # currently reset to 0 is unsupported, leave it 512 for now.
20308         $LCTL set_param llite.*.max_read_ahead_async_active=0 &&
20309                 error "set max_read_ahead_async_active should fail"
20310
20311         $LCTL set_param llite.*.max_read_ahead_async_active=512
20312         max_active=$($LCTL get_param -n \
20313                      llite.*.max_read_ahead_async_active 2>/dev/null)
20314         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
20315
20316         # restore @max_active
20317         [ $old_max_active -ne 0 ] && $LCTL set_param \
20318                 llite.*.max_read_ahead_async_active=$old_max_active
20319
20320         local old_threshold=$($LCTL get_param -n \
20321                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
20322         local max_per_file_mb=$($LCTL get_param -n \
20323                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
20324
20325         local invalid=$(($max_per_file_mb + 1))
20326         $LCTL set_param \
20327                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
20328                         && error "set $invalid should fail"
20329
20330         local valid=$(($invalid - 1))
20331         $LCTL set_param \
20332                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
20333                         error "set $valid should succeed"
20334         local threshold=$($LCTL get_param -n \
20335                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
20336         [ $threshold -eq $valid ] || error \
20337                 "expect threshold $valid got $threshold"
20338         $LCTL set_param \
20339                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
20340 }
20341 run_test 318 "Verify async readahead tunables"
20342
20343 test_319() {
20344         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
20345
20346         local before=$(date +%s)
20347         local evict
20348         local mdir=$DIR/$tdir
20349         local file=$mdir/xxx
20350
20351         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
20352         touch $file
20353
20354 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
20355         $LCTL set_param fail_val=5 fail_loc=0x8000032c
20356         $LFS mv -m1 $file &
20357
20358         sleep 1
20359         dd if=$file of=/dev/null
20360         wait
20361         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
20362           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
20363
20364         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
20365 }
20366 run_test 319 "lost lease lock on migrate error"
20367
20368 test_fake_rw() {
20369         local read_write=$1
20370         if [ "$read_write" = "write" ]; then
20371                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
20372         elif [ "$read_write" = "read" ]; then
20373                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
20374         else
20375                 error "argument error"
20376         fi
20377
20378         # turn off debug for performance testing
20379         local saved_debug=$($LCTL get_param -n debug)
20380         $LCTL set_param debug=0
20381
20382         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20383
20384         # get ost1 size - lustre-OST0000
20385         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
20386         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
20387         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
20388
20389         if [ "$read_write" = "read" ]; then
20390                 truncate -s $(expr 1048576 \* $blocks) $DIR/$tfile
20391         fi
20392
20393         local start_time=$(date +%s.%N)
20394         $dd_cmd bs=1M count=$blocks oflag=sync ||
20395                 error "real dd $read_write error"
20396         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
20397
20398         if [ "$read_write" = "write" ]; then
20399                 rm -f $DIR/$tfile
20400         fi
20401
20402         # define OBD_FAIL_OST_FAKE_RW           0x238
20403         do_facet ost1 $LCTL set_param fail_loc=0x238
20404
20405         local start_time=$(date +%s.%N)
20406         $dd_cmd bs=1M count=$blocks oflag=sync ||
20407                 error "fake dd $read_write error"
20408         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
20409
20410         if [ "$read_write" = "write" ]; then
20411                 # verify file size
20412                 cancel_lru_locks osc
20413                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
20414                         error "$tfile size not $blocks MB"
20415         fi
20416         do_facet ost1 $LCTL set_param fail_loc=0
20417
20418         echo "fake $read_write $duration_fake vs. normal $read_write" \
20419                 "$duration in seconds"
20420         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
20421                 error_not_in_vm "fake write is slower"
20422
20423         $LCTL set_param -n debug="$saved_debug"
20424         rm -f $DIR/$tfile
20425 }
20426 test_399a() { # LU-7655 for OST fake write
20427         remote_ost_nodsh && skip "remote OST with nodsh"
20428
20429         test_fake_rw write
20430 }
20431 run_test 399a "fake write should not be slower than normal write"
20432
20433 test_399b() { # LU-8726 for OST fake read
20434         remote_ost_nodsh && skip "remote OST with nodsh"
20435         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
20436                 skip_env "ldiskfs only test"
20437         fi
20438
20439         test_fake_rw read
20440 }
20441 run_test 399b "fake read should not be slower than normal read"
20442
20443 test_400a() { # LU-1606, was conf-sanity test_74
20444         if ! which $CC > /dev/null 2>&1; then
20445                 skip_env "$CC is not installed"
20446         fi
20447
20448         local extra_flags=''
20449         local out=$TMP/$tfile
20450         local prefix=/usr/include/lustre
20451         local prog
20452
20453         if ! [[ -d $prefix ]]; then
20454                 # Assume we're running in tree and fixup the include path.
20455                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
20456                 extra_flags+=" -L$LUSTRE/utils/.lib"
20457         fi
20458
20459         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
20460                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
20461                         error "client api broken"
20462         done
20463         rm -f $out
20464 }
20465 run_test 400a "Lustre client api program can compile and link"
20466
20467 test_400b() { # LU-1606, LU-5011
20468         local header
20469         local out=$TMP/$tfile
20470         local prefix=/usr/include/linux/lustre
20471
20472         # We use a hard coded prefix so that this test will not fail
20473         # when run in tree. There are headers in lustre/include/lustre/
20474         # that are not packaged (like lustre_idl.h) and have more
20475         # complicated include dependencies (like config.h and lnet/types.h).
20476         # Since this test about correct packaging we just skip them when
20477         # they don't exist (see below) rather than try to fixup cppflags.
20478
20479         if ! which $CC > /dev/null 2>&1; then
20480                 skip_env "$CC is not installed"
20481         fi
20482
20483         for header in $prefix/*.h; do
20484                 if ! [[ -f "$header" ]]; then
20485                         continue
20486                 fi
20487
20488                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
20489                         continue # lustre_ioctl.h is internal header
20490                 fi
20491
20492                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
20493                         error "cannot compile '$header'"
20494         done
20495         rm -f $out
20496 }
20497 run_test 400b "packaged headers can be compiled"
20498
20499 test_401a() { #LU-7437
20500         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
20501         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
20502
20503         #count the number of parameters by "list_param -R"
20504         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
20505         #count the number of parameters by listing proc files
20506         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
20507         echo "proc_dirs='$proc_dirs'"
20508         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
20509         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
20510                       sort -u | wc -l)
20511
20512         [ $params -eq $procs ] ||
20513                 error "found $params parameters vs. $procs proc files"
20514
20515         # test the list_param -D option only returns directories
20516         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
20517         #count the number of parameters by listing proc directories
20518         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
20519                 sort -u | wc -l)
20520
20521         [ $params -eq $procs ] ||
20522                 error "found $params parameters vs. $procs proc files"
20523 }
20524 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
20525
20526 test_401b() {
20527         local save=$($LCTL get_param -n jobid_var)
20528         local tmp=testing
20529
20530         $LCTL set_param foo=bar jobid_var=$tmp bar=baz &&
20531                 error "no error returned when setting bad parameters"
20532
20533         local jobid_new=$($LCTL get_param -n foe jobid_var baz)
20534         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
20535
20536         $LCTL set_param -n fog=bam jobid_var=$save bat=fog
20537         local jobid_old=$($LCTL get_param -n foe jobid_var bag)
20538         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
20539 }
20540 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
20541
20542 test_401c() {
20543         local jobid_var_old=$($LCTL get_param -n jobid_var)
20544         local jobid_var_new
20545
20546         $LCTL set_param jobid_var= &&
20547                 error "no error returned for 'set_param a='"
20548
20549         jobid_var_new=$($LCTL get_param -n jobid_var)
20550         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
20551                 error "jobid_var was changed by setting without value"
20552
20553         $LCTL set_param jobid_var &&
20554                 error "no error returned for 'set_param a'"
20555
20556         jobid_var_new=$($LCTL get_param -n jobid_var)
20557         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
20558                 error "jobid_var was changed by setting without value"
20559 }
20560 run_test 401c "Verify 'lctl set_param' without value fails in either format."
20561
20562 test_401d() {
20563         local jobid_var_old=$($LCTL get_param -n jobid_var)
20564         local jobid_var_new
20565         local new_value="foo=bar"
20566
20567         $LCTL set_param jobid_var=$new_value ||
20568                 error "'set_param a=b' did not accept a value containing '='"
20569
20570         jobid_var_new=$($LCTL get_param -n jobid_var)
20571         [[ "$jobid_var_new" == "$new_value" ]] ||
20572                 error "'set_param a=b' failed on a value containing '='"
20573
20574         # Reset the jobid_var to test the other format
20575         $LCTL set_param jobid_var=$jobid_var_old
20576         jobid_var_new=$($LCTL get_param -n jobid_var)
20577         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
20578                 error "failed to reset jobid_var"
20579
20580         $LCTL set_param jobid_var $new_value ||
20581                 error "'set_param a b' did not accept a value containing '='"
20582
20583         jobid_var_new=$($LCTL get_param -n jobid_var)
20584         [[ "$jobid_var_new" == "$new_value" ]] ||
20585                 error "'set_param a b' failed on a value containing '='"
20586
20587         $LCTL set_param jobid_var $jobid_var_old
20588         jobid_var_new=$($LCTL get_param -n jobid_var)
20589         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
20590                 error "failed to reset jobid_var"
20591 }
20592 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
20593
20594 test_402() {
20595         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
20596         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
20597                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
20598         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
20599                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
20600                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
20601         remote_mds_nodsh && skip "remote MDS with nodsh"
20602
20603         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
20604 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
20605         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
20606         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
20607                 echo "Touch failed - OK"
20608 }
20609 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
20610
20611 test_403() {
20612         local file1=$DIR/$tfile.1
20613         local file2=$DIR/$tfile.2
20614         local tfile=$TMP/$tfile
20615
20616         rm -f $file1 $file2 $tfile
20617
20618         touch $file1
20619         ln $file1 $file2
20620
20621         # 30 sec OBD_TIMEOUT in ll_getattr()
20622         # right before populating st_nlink
20623         $LCTL set_param fail_loc=0x80001409
20624         stat -c %h $file1 > $tfile &
20625
20626         # create an alias, drop all locks and reclaim the dentry
20627         < $file2
20628         cancel_lru_locks mdc
20629         cancel_lru_locks osc
20630         sysctl -w vm.drop_caches=2
20631
20632         wait
20633
20634         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
20635
20636         rm -f $tfile $file1 $file2
20637 }
20638 run_test 403 "i_nlink should not drop to zero due to aliasing"
20639
20640 test_404() { # LU-6601
20641         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
20642                 skip "Need server version newer than 2.8.52"
20643         remote_mds_nodsh && skip "remote MDS with nodsh"
20644
20645         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
20646                 awk '/osp .*-osc-MDT/ { print $4}')
20647
20648         local osp
20649         for osp in $mosps; do
20650                 echo "Deactivate: " $osp
20651                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
20652                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
20653                         awk -vp=$osp '$4 == p { print $2 }')
20654                 [ $stat = IN ] || {
20655                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
20656                         error "deactivate error"
20657                 }
20658                 echo "Activate: " $osp
20659                 do_facet $SINGLEMDS $LCTL --device %$osp activate
20660                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
20661                         awk -vp=$osp '$4 == p { print $2 }')
20662                 [ $stat = UP ] || {
20663                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
20664                         error "activate error"
20665                 }
20666         done
20667 }
20668 run_test 404 "validate manual {de}activated works properly for OSPs"
20669
20670 test_405() {
20671         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
20672         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
20673                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
20674                         skip "Layout swap lock is not supported"
20675
20676         check_swap_layouts_support
20677
20678         test_mkdir $DIR/$tdir
20679         swap_lock_test -d $DIR/$tdir ||
20680                 error "One layout swap locked test failed"
20681 }
20682 run_test 405 "Various layout swap lock tests"
20683
20684 test_406() {
20685         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20686         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
20687         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
20688         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20689         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
20690                 skip "Need MDS version at least 2.8.50"
20691
20692         local def_stripe_size=$($LFS getstripe -S $MOUNT)
20693         local test_pool=$TESTNAME
20694
20695         pool_add $test_pool || error "pool_add failed"
20696         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
20697                 error "pool_add_targets failed"
20698
20699         save_layout_restore_at_exit $MOUNT
20700
20701         # parent set default stripe count only, child will stripe from both
20702         # parent and fs default
20703         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
20704                 error "setstripe $MOUNT failed"
20705         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
20706         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
20707         for i in $(seq 10); do
20708                 local f=$DIR/$tdir/$tfile.$i
20709                 touch $f || error "touch failed"
20710                 local count=$($LFS getstripe -c $f)
20711                 [ $count -eq $OSTCOUNT ] ||
20712                         error "$f stripe count $count != $OSTCOUNT"
20713                 local offset=$($LFS getstripe -i $f)
20714                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
20715                 local size=$($LFS getstripe -S $f)
20716                 [ $size -eq $((def_stripe_size * 2)) ] ||
20717                         error "$f stripe size $size != $((def_stripe_size * 2))"
20718                 local pool=$($LFS getstripe -p $f)
20719                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
20720         done
20721
20722         # change fs default striping, delete parent default striping, now child
20723         # will stripe from new fs default striping only
20724         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
20725                 error "change $MOUNT default stripe failed"
20726         $LFS setstripe -c 0 $DIR/$tdir ||
20727                 error "delete $tdir default stripe failed"
20728         for i in $(seq 11 20); do
20729                 local f=$DIR/$tdir/$tfile.$i
20730                 touch $f || error "touch $f failed"
20731                 local count=$($LFS getstripe -c $f)
20732                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
20733                 local offset=$($LFS getstripe -i $f)
20734                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
20735                 local size=$($LFS getstripe -S $f)
20736                 [ $size -eq $def_stripe_size ] ||
20737                         error "$f stripe size $size != $def_stripe_size"
20738                 local pool=$($LFS getstripe -p $f)
20739                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
20740         done
20741
20742         unlinkmany $DIR/$tdir/$tfile. 1 20
20743
20744         local f=$DIR/$tdir/$tfile
20745         pool_remove_all_targets $test_pool $f
20746         pool_remove $test_pool $f
20747 }
20748 run_test 406 "DNE support fs default striping"
20749
20750 test_407() {
20751         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20752         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
20753                 skip "Need MDS version at least 2.8.55"
20754         remote_mds_nodsh && skip "remote MDS with nodsh"
20755
20756         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
20757                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
20758         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
20759                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
20760         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
20761
20762         #define OBD_FAIL_DT_TXN_STOP    0x2019
20763         for idx in $(seq $MDSCOUNT); do
20764                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
20765         done
20766         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
20767         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
20768                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
20769         true
20770 }
20771 run_test 407 "transaction fail should cause operation fail"
20772
20773 test_408() {
20774         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
20775
20776         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
20777         lctl set_param fail_loc=0x8000040a
20778         # let ll_prepare_partial_page() fail
20779         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
20780
20781         rm -f $DIR/$tfile
20782
20783         # create at least 100 unused inodes so that
20784         # shrink_icache_memory(0) should not return 0
20785         touch $DIR/$tfile-{0..100}
20786         rm -f $DIR/$tfile-{0..100}
20787         sync
20788
20789         echo 2 > /proc/sys/vm/drop_caches
20790 }
20791 run_test 408 "drop_caches should not hang due to page leaks"
20792
20793 test_409()
20794 {
20795         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20796
20797         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
20798         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
20799         touch $DIR/$tdir/guard || error "(2) Fail to create"
20800
20801         local PREFIX=$(str_repeat 'A' 128)
20802         echo "Create 1K hard links start at $(date)"
20803         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
20804                 error "(3) Fail to hard link"
20805
20806         echo "Links count should be right although linkEA overflow"
20807         stat $DIR/$tdir/guard || error "(4) Fail to stat"
20808         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
20809         [ $linkcount -eq 1001 ] ||
20810                 error "(5) Unexpected hard links count: $linkcount"
20811
20812         echo "List all links start at $(date)"
20813         ls -l $DIR/$tdir/foo > /dev/null ||
20814                 error "(6) Fail to list $DIR/$tdir/foo"
20815
20816         echo "Unlink hard links start at $(date)"
20817         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
20818                 error "(7) Fail to unlink"
20819         echo "Unlink hard links finished at $(date)"
20820 }
20821 run_test 409 "Large amount of cross-MDTs hard links on the same file"
20822
20823 test_410()
20824 {
20825         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
20826                 skip "Need client version at least 2.9.59"
20827
20828         # Create a file, and stat it from the kernel
20829         local testfile=$DIR/$tfile
20830         touch $testfile
20831
20832         local run_id=$RANDOM
20833         local my_ino=$(stat --format "%i" $testfile)
20834
20835         # Try to insert the module. This will always fail as the
20836         # module is designed to not be inserted.
20837         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
20838             &> /dev/null
20839
20840         # Anything but success is a test failure
20841         dmesg | grep -q \
20842             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
20843             error "no inode match"
20844 }
20845 run_test 410 "Test inode number returned from kernel thread"
20846
20847 cleanup_test411_cgroup() {
20848         trap 0
20849         rmdir "$1"
20850 }
20851
20852 test_411() {
20853         local cg_basedir=/sys/fs/cgroup/memory
20854         # LU-9966
20855         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
20856                 skip "no setup for cgroup"
20857
20858         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
20859                 error "test file creation failed"
20860         cancel_lru_locks osc
20861
20862         # Create a very small memory cgroup to force a slab allocation error
20863         local cgdir=$cg_basedir/osc_slab_alloc
20864         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
20865         trap "cleanup_test411_cgroup $cgdir" EXIT
20866         echo 2M > $cgdir/memory.kmem.limit_in_bytes
20867         echo 1M > $cgdir/memory.limit_in_bytes
20868
20869         # Should not LBUG, just be killed by oom-killer
20870         # dd will return 0 even allocation failure in some environment.
20871         # So don't check return value
20872         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
20873         cleanup_test411_cgroup $cgdir
20874
20875         return 0
20876 }
20877 run_test 411 "Slab allocation error with cgroup does not LBUG"
20878
20879 test_412() {
20880         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20881         if [ $(lustre_version_code mds1) -lt $(version_code 2.10.55) ]; then
20882                 skip "Need server version at least 2.10.55"
20883         fi
20884
20885         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
20886                 error "mkdir failed"
20887         $LFS getdirstripe $DIR/$tdir
20888         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
20889         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
20890                 error "expect $((MDSCOUT - 1)) get $stripe_index"
20891         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
20892         [ $stripe_count -eq 2 ] ||
20893                 error "expect 2 get $stripe_count"
20894 }
20895 run_test 412 "mkdir on specific MDTs"
20896
20897 test_qos_mkdir() {
20898         local mkdir_cmd=$1
20899         local stripe_count=$2
20900         local mdts=$(comma_list $(mdts_nodes))
20901
20902         local testdir
20903         local lmv_qos_prio_free
20904         local lmv_qos_threshold_rr
20905         local lmv_qos_maxage
20906         local lod_qos_prio_free
20907         local lod_qos_threshold_rr
20908         local lod_qos_maxage
20909         local count
20910         local i
20911
20912         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
20913         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
20914         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
20915                 head -n1)
20916         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
20917         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
20918         stack_trap "$LCTL set_param \
20919                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null" EXIT
20920         stack_trap "$LCTL set_param \
20921                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
20922         stack_trap "$LCTL set_param \
20923                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" EXIT
20924
20925         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
20926                 lod.lustre-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
20927         lod_qos_prio_free=${lod_qos_prio_free%%%}
20928         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
20929                 lod.lustre-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
20930         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
20931         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
20932                 lod.lustre-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
20933         stack_trap "do_nodes $mdts $LCTL set_param \
20934                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null" EXIT
20935         stack_trap "do_nodes $mdts $LCTL set_param \
20936                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null" \
20937                 EXIT
20938         stack_trap "do_nodes $mdts $LCTL set_param \
20939                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" EXIT
20940
20941         echo
20942         echo "Mkdir (stripe_count $stripe_count) roundrobin:"
20943
20944         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
20945         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
20946
20947         testdir=$DIR/$tdir-s$stripe_count/rr
20948
20949         for i in $(seq $((100 * MDSCOUNT))); do
20950                 eval $mkdir_cmd $testdir/subdir$i ||
20951                         error "$mkdir_cmd subdir$i failed"
20952         done
20953
20954         for i in $(seq $MDSCOUNT); do
20955                 count=$($LFS getdirstripe -i $testdir/* |
20956                                 grep ^$((i - 1))$ | wc -l)
20957                 echo "$count directories created on MDT$((i - 1))"
20958                 [ $count -eq 100 ] || error "subdirs are not evenly distributed"
20959
20960                 if [ $stripe_count -gt 1 ]; then
20961                         count=$($LFS getdirstripe $testdir/* |
20962                                 grep -P "^\s+$((i - 1))\t" | wc -l)
20963                         echo "$count stripes created on MDT$((i - 1))"
20964                         # deviation should < 5% of average
20965                         [ $count -lt $((95 * stripe_count)) ] ||
20966                         [ $count -gt $((105 * stripe_count)) ] &&
20967                                 error "stripes are not evenly distributed"
20968                 fi
20969         done
20970
20971         $LCTL set_param lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null
20972         do_nodes $mdts $LCTL set_param \
20973                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null
20974
20975         echo
20976         echo "Check for uneven MDTs: "
20977
20978         local ffree
20979         local bavail
20980         local max
20981         local min
20982         local max_index
20983         local min_index
20984         local tmp
20985
20986         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
20987         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
20988         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
20989
20990         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
20991         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
20992         max_index=0
20993         min_index=0
20994         for ((i = 1; i < ${#ffree[@]}; i++)); do
20995                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
20996                 if [ $tmp -gt $max ]; then
20997                         max=$tmp
20998                         max_index=$i
20999                 fi
21000                 if [ $tmp -lt $min ]; then
21001                         min=$tmp
21002                         min_index=$i
21003                 fi
21004         done
21005
21006         [ ${ffree[min_index]} -eq 0 ] &&
21007                 skip "no free files in MDT$min_index"
21008         [ ${ffree[min_index]} -gt 100000000 ] &&
21009                 skip "too much free files in MDT$min_index"
21010
21011         # Check if we need to generate uneven MDTs
21012         local threshold=50
21013         local diff=$(((max - min) * 100 / min))
21014         local value="$(generate_string 1024)"
21015
21016         while [ $diff -lt $threshold ]; do
21017                 # generate uneven MDTs, create till $threshold% diff
21018                 echo -n "weight diff=$diff% must be > $threshold% ..."
21019                 count=$((${ffree[min_index]} / 10))
21020                 # 50 sec per 10000 files in vm
21021                 [ $count -gt 40000 ] && [ "$SLOW" = "no" ] &&
21022                         skip "$count files to create"
21023                 echo "Fill MDT$min_index with $count files"
21024                 [ -d $DIR/$tdir-MDT$min_index ] ||
21025                         $LFS mkdir -i $min_index $DIR/$tdir-MDT$min_index ||
21026                         error "mkdir $tdir-MDT$min_index failed"
21027                 for i in $(seq $count); do
21028                         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE \
21029                                 $DIR/$tdir-MDT$min_index/f$j_$i > /dev/null ||
21030                                 error "create f$j_$i failed"
21031                         setfattr -n user.413b -v $value \
21032                                 $DIR/$tdir-MDT$min_index/f$j_$i ||
21033                                 error "setfattr f$j_$i failed"
21034                 done
21035
21036                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
21037                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
21038                 max=$(((${ffree[max_index]} >> 8) * \
21039                         (${bavail[max_index]} * bsize >> 16)))
21040                 min=$(((${ffree[min_index]} >> 8) * \
21041                         (${bavail[min_index]} * bsize >> 16)))
21042                 diff=$(((max - min) * 100 / min))
21043         done
21044
21045         echo "MDT filesfree available: ${ffree[@]}"
21046         echo "MDT blocks available: ${bavail[@]}"
21047         echo "weight diff=$diff%"
21048
21049         echo
21050         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
21051
21052         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
21053         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
21054         # decrease statfs age, so that it can be updated in time
21055         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
21056         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
21057
21058         sleep 1
21059
21060         testdir=$DIR/$tdir-s$stripe_count/qos
21061
21062         for i in $(seq $((100 * MDSCOUNT))); do
21063                 eval $mkdir_cmd $testdir/subdir$i ||
21064                         error "$mkdir_cmd subdir$i failed"
21065         done
21066
21067         for i in $(seq $MDSCOUNT); do
21068                 count=$($LFS getdirstripe -i $testdir/* | grep ^$((i - 1))$ |
21069                         wc -l)
21070                 echo "$count directories created on MDT$((i - 1))"
21071
21072                 if [ $stripe_count -gt 1 ]; then
21073                         count=$($LFS getdirstripe $testdir/* |
21074                                 grep -P "^\s+$((i - 1))\t" | wc -l)
21075                         echo "$count stripes created on MDT$((i - 1))"
21076                 fi
21077         done
21078
21079         max=$($LFS getdirstripe -i $testdir/* | grep ^$max_index$ | wc -l)
21080         min=$($LFS getdirstripe -i $testdir/* | grep ^$min_index$ | wc -l)
21081
21082         # D-value should > 10% of averge
21083         [ $((max - min)) -lt 10 ] &&
21084                 error "subdirs shouldn't be evenly distributed"
21085
21086         # ditto
21087         if [ $stripe_count -gt 1 ]; then
21088                 max=$($LFS getdirstripe $testdir/* |
21089                         grep -P "^\s+$max_index\t" | wc -l)
21090                 min=$($LFS getdirstripe $testdir/* |
21091                         grep -P "^\s+$min_index\t" | wc -l)
21092                 [ $((max - min)) -le $((10 * stripe_count)) ] &&
21093                         error "stripes shouldn't be evenly distributed"|| true
21094         fi
21095 }
21096
21097 test_413a() {
21098         [ $MDSCOUNT -lt 2 ] &&
21099                 skip "We need at least 2 MDTs for this test"
21100
21101         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
21102                 skip "Need server version at least 2.12.52"
21103
21104         local stripe_count
21105
21106         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
21107                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
21108                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
21109                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
21110                 test_qos_mkdir "$LFS mkdir -c $stripe_count" $stripe_count
21111         done
21112 }
21113 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
21114
21115 test_413b() {
21116         [ $MDSCOUNT -lt 2 ] &&
21117                 skip "We need at least 2 MDTs for this test"
21118
21119         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
21120                 skip "Need server version at least 2.12.52"
21121
21122         local stripe_count
21123
21124         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
21125                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
21126                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
21127                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
21128                 $LFS setdirstripe -D -c $stripe_count \
21129                         $DIR/$tdir-s$stripe_count/rr ||
21130                         error "setdirstripe failed"
21131                 $LFS setdirstripe -D -c $stripe_count \
21132                         $DIR/$tdir-s$stripe_count/qos ||
21133                         error "setdirstripe failed"
21134                 test_qos_mkdir "mkdir" $stripe_count
21135         done
21136 }
21137 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
21138
21139 test_414() {
21140 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
21141         $LCTL set_param fail_loc=0x80000521
21142         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
21143         rm -f $DIR/$tfile
21144 }
21145 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
21146
21147 test_415() {
21148         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21149         [ $(lustre_version_code mds1) -lt $(version_code 2.11.52) ] &&
21150                 skip "Need server version at least 2.11.52"
21151
21152         # LU-11102
21153         local total
21154         local setattr_pid
21155         local start_time
21156         local end_time
21157         local duration
21158
21159         total=500
21160         # this test may be slow on ZFS
21161         [ "$mds1_FSTYPE" == "zfs" ] && total=100
21162
21163         # though this test is designed for striped directory, let's test normal
21164         # directory too since lock is always saved as CoS lock.
21165         test_mkdir $DIR/$tdir || error "mkdir $tdir"
21166         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
21167
21168         (
21169                 while true; do
21170                         touch $DIR/$tdir
21171                 done
21172         ) &
21173         setattr_pid=$!
21174
21175         start_time=$(date +%s)
21176         for i in $(seq $total); do
21177                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
21178                         > /dev/null
21179         done
21180         end_time=$(date +%s)
21181         duration=$((end_time - start_time))
21182
21183         kill -9 $setattr_pid
21184
21185         echo "rename $total files took $duration sec"
21186         [ $duration -lt 100 ] || error "rename took $duration sec"
21187 }
21188 run_test 415 "lock revoke is not missing"
21189
21190 test_416() {
21191         [ $(lustre_version_code mds1) -lt $(version_code 2.11.55) ] &&
21192                 skip "Need server version at least 2.11.55"
21193
21194         # define OBD_FAIL_OSD_TXN_START    0x19a
21195         do_facet mds1 lctl set_param fail_loc=0x19a
21196
21197         lfs mkdir -c $MDSCOUNT $DIR/$tdir
21198
21199         true
21200 }
21201 run_test 416 "transaction start failure won't cause system hung"
21202
21203 cleanup_417() {
21204         trap 0
21205         do_nodes $(comma_list $(mdts_nodes)) \
21206                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
21207         do_nodes $(comma_list $(mdts_nodes)) \
21208                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
21209         do_nodes $(comma_list $(mdts_nodes)) \
21210                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
21211 }
21212
21213 test_417() {
21214         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21215         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
21216                 skip "Need MDS version at least 2.11.56"
21217
21218         trap cleanup_417 RETURN EXIT
21219
21220         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
21221         do_nodes $(comma_list $(mdts_nodes)) \
21222                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
21223         $LFS migrate -m 0 $DIR/$tdir.1 &&
21224                 error "migrate dir $tdir.1 should fail"
21225
21226         do_nodes $(comma_list $(mdts_nodes)) \
21227                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
21228         $LFS mkdir -i 1 $DIR/$tdir.2 &&
21229                 error "create remote dir $tdir.2 should fail"
21230
21231         do_nodes $(comma_list $(mdts_nodes)) \
21232                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
21233         $LFS mkdir -c 2 $DIR/$tdir.3 &&
21234                 error "create striped dir $tdir.3 should fail"
21235         true
21236 }
21237 run_test 417 "disable remote dir, striped dir and dir migration"
21238
21239 # Checks that the outputs of df [-i] and lfs df [-i] match
21240 #
21241 # usage: check_lfs_df <blocks | inodes> <mountpoint>
21242 check_lfs_df() {
21243         local dir=$2
21244         local inodes
21245         local df_out
21246         local lfs_df_out
21247         local count
21248         local passed=false
21249
21250         # blocks or inodes
21251         [ "$1" == "blocks" ] && inodes= || inodes="-i"
21252
21253         for count in {1..100}; do
21254                 cancel_lru_locks
21255                 sync; sleep 0.2
21256
21257                 # read the lines of interest
21258                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
21259                         error "df $inodes $dir | tail -n +2 failed"
21260                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
21261                         error "lfs df $inodes $dir | grep summary: failed"
21262
21263                 # skip first substrings of each output as they are different
21264                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
21265                 # compare the two outputs
21266                 passed=true
21267                 for i in {1..5}; do
21268                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
21269                 done
21270                 $passed && break
21271         done
21272
21273         if ! $passed; then
21274                 df -P $inodes $dir
21275                 echo
21276                 lfs df $inodes $dir
21277                 error "df and lfs df $1 output mismatch: "      \
21278                       "df ${inodes}: ${df_out[*]}, "            \
21279                       "lfs df ${inodes}: ${lfs_df_out[*]}"
21280         fi
21281 }
21282
21283 test_418() {
21284         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21285
21286         local dir=$DIR/$tdir
21287         local numfiles=$((RANDOM % 4096 + 2))
21288         local numblocks=$((RANDOM % 256 + 1))
21289
21290         wait_delete_completed
21291         test_mkdir $dir
21292
21293         # check block output
21294         check_lfs_df blocks $dir
21295         # check inode output
21296         check_lfs_df inodes $dir
21297
21298         # create a single file and retest
21299         echo "Creating a single file and testing"
21300         createmany -o $dir/$tfile- 1 &>/dev/null ||
21301                 error "creating 1 file in $dir failed"
21302         check_lfs_df blocks $dir
21303         check_lfs_df inodes $dir
21304
21305         # create a random number of files
21306         echo "Creating $((numfiles - 1)) files and testing"
21307         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
21308                 error "creating $((numfiles - 1)) files in $dir failed"
21309
21310         # write a random number of blocks to the first test file
21311         echo "Writing $numblocks 4K blocks and testing"
21312         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
21313                 count=$numblocks &>/dev/null ||
21314                 error "dd to $dir/${tfile}-0 failed"
21315
21316         # retest
21317         check_lfs_df blocks $dir
21318         check_lfs_df inodes $dir
21319
21320         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
21321                 error "unlinking $numfiles files in $dir failed"
21322 }
21323 run_test 418 "df and lfs df outputs match"
21324
21325 test_419()
21326 {
21327         local dir=$DIR/$tdir
21328
21329         mkdir -p $dir
21330         touch $dir/file
21331
21332         cancel_lru_locks mdc
21333
21334         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
21335         $LCTL set_param fail_loc=0x1410
21336         cat $dir/file
21337         $LCTL set_param fail_loc=0
21338         rm -rf $dir
21339 }
21340 run_test 419 "Verify open file by name doesn't crash kernel"
21341
21342 test_420()
21343 {
21344         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
21345                 skip "Need MDS version at least 2.12.53"
21346
21347         local SAVE_UMASK=$(umask)
21348         local dir=$DIR/$tdir
21349         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
21350
21351         mkdir -p $dir
21352         umask 0000
21353         mkdir -m03777 $dir/testdir
21354         ls -dn $dir/testdir
21355         # Need to remove trailing '.' when SELinux is enabled
21356         local dirperms=$(ls -dn $dir/testdir |
21357                          awk '{ sub(/\.$/, "", $1); print $1}')
21358         [ $dirperms == "drwxrwsrwt" ] ||
21359                 error "incorrect perms on $dir/testdir"
21360
21361         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
21362                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
21363         ls -n $dir/testdir/testfile
21364         local fileperms=$(ls -n $dir/testdir/testfile |
21365                           awk '{ sub(/\.$/, "", $1); print $1}')
21366         [ $fileperms == "-rwxr-xr-x" ] ||
21367                 error "incorrect perms on $dir/testdir/testfile"
21368
21369         umask $SAVE_UMASK
21370 }
21371 run_test 420 "clear SGID bit on non-directories for non-members"
21372
21373 test_421a() {
21374         local cnt
21375         local fid1
21376         local fid2
21377
21378         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
21379                 skip "Need MDS version at least 2.12.54"
21380
21381         test_mkdir $DIR/$tdir
21382         createmany -o $DIR/$tdir/f 3
21383         cnt=$(ls -1 $DIR/$tdir | wc -l)
21384         [ $cnt != 3 ] && error "unexpected #files: $cnt"
21385
21386         fid1=$(lfs path2fid $DIR/$tdir/f1)
21387         fid2=$(lfs path2fid $DIR/$tdir/f2)
21388         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
21389
21390         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
21391         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
21392
21393         cnt=$(ls -1 $DIR/$tdir | wc -l)
21394         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
21395
21396         rm -f $DIR/$tdir/f3 || error "can't remove f3"
21397         createmany -o $DIR/$tdir/f 3
21398         cnt=$(ls -1 $DIR/$tdir | wc -l)
21399         [ $cnt != 3 ] && error "unexpected #files: $cnt"
21400
21401         fid1=$(lfs path2fid $DIR/$tdir/f1)
21402         fid2=$(lfs path2fid $DIR/$tdir/f2)
21403         echo "remove using fsname $FSNAME"
21404         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
21405
21406         cnt=$(ls -1 $DIR/$tdir | wc -l)
21407         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
21408 }
21409 run_test 421a "simple rm by fid"
21410
21411 test_421b() {
21412         local cnt
21413         local FID1
21414         local FID2
21415
21416         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
21417                 skip "Need MDS version at least 2.12.54"
21418
21419         test_mkdir $DIR/$tdir
21420         createmany -o $DIR/$tdir/f 3
21421         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
21422         MULTIPID=$!
21423
21424         FID1=$(lfs path2fid $DIR/$tdir/f1)
21425         FID2=$(lfs path2fid $DIR/$tdir/f2)
21426         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
21427
21428         kill -USR1 $MULTIPID
21429         wait
21430
21431         cnt=$(ls $DIR/$tdir | wc -l)
21432         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
21433 }
21434 run_test 421b "rm by fid on open file"
21435
21436 test_421c() {
21437         local cnt
21438         local FIDS
21439
21440         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
21441                 skip "Need MDS version at least 2.12.54"
21442
21443         test_mkdir $DIR/$tdir
21444         createmany -o $DIR/$tdir/f 3
21445         touch $DIR/$tdir/$tfile
21446         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
21447         cnt=$(ls -1 $DIR/$tdir | wc -l)
21448         [ $cnt != 184 ] && error "unexpected #files: $cnt"
21449
21450         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
21451         $LFS rmfid $DIR $FID1 || error "rmfid failed"
21452
21453         cnt=$(ls $DIR/$tdir | wc -l)
21454         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
21455 }
21456 run_test 421c "rm by fid against hardlinked files"
21457
21458 test_421d() {
21459         local cnt
21460         local FIDS
21461
21462         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
21463                 skip "Need MDS version at least 2.12.54"
21464
21465         test_mkdir $DIR/$tdir
21466         createmany -o $DIR/$tdir/f 4097
21467         cnt=$(ls -1 $DIR/$tdir | wc -l)
21468         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
21469
21470         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
21471         $LFS rmfid $DIR $FIDS || error "rmfid failed"
21472
21473         cnt=$(ls $DIR/$tdir | wc -l)
21474         rm -rf $DIR/$tdir
21475         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
21476 }
21477 run_test 421d "rmfid en masse"
21478
21479 test_421e() {
21480         local cnt
21481         local FID
21482
21483         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21484         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
21485                 skip "Need MDS version at least 2.12.54"
21486
21487         mkdir -p $DIR/$tdir
21488         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
21489         createmany -o $DIR/$tdir/striped_dir/f 512
21490         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
21491         [ $cnt != 512 ] && error "unexpected #files: $cnt"
21492
21493         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
21494                 sed "s/[/][^:]*://g")
21495         $LFS rmfid $DIR $FIDS || error "rmfid failed"
21496
21497         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
21498         rm -rf $DIR/$tdir
21499         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
21500 }
21501 run_test 421e "rmfid in DNE"
21502
21503 test_421f() {
21504         local cnt
21505         local FID
21506
21507         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
21508                 skip "Need MDS version at least 2.12.54"
21509
21510         test_mkdir $DIR/$tdir
21511         touch $DIR/$tdir/f
21512         cnt=$(ls -1 $DIR/$tdir | wc -l)
21513         [ $cnt != 1 ] && error "unexpected #files: $cnt"
21514
21515         FID=$(lfs path2fid $DIR/$tdir/f)
21516         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
21517         # rmfid should fail
21518         cnt=$(ls -1 $DIR/$tdir | wc -l)
21519         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
21520
21521         chmod a+rw $DIR/$tdir
21522         ls -la $DIR/$tdir
21523         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
21524         # rmfid should fail
21525         cnt=$(ls -1 $DIR/$tdir | wc -l)
21526         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
21527
21528         rm -f $DIR/$tdir/f
21529         $RUNAS touch $DIR/$tdir/f
21530         FID=$(lfs path2fid $DIR/$tdir/f)
21531         echo "rmfid as root"
21532         $LFS rmfid $DIR $FID || error "rmfid as root failed"
21533         cnt=$(ls -1 $DIR/$tdir | wc -l)
21534         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
21535
21536         rm -f $DIR/$tdir/f
21537         $RUNAS touch $DIR/$tdir/f
21538         cnt=$(ls -1 $DIR/$tdir | wc -l)
21539         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
21540         FID=$(lfs path2fid $DIR/$tdir/f)
21541         # rmfid w/o user_fid2path mount option should fail
21542         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
21543         cnt=$(ls -1 $DIR/$tdir | wc -l)
21544         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
21545
21546         umount_client $MOUNT || error "failed to umount client"
21547         mount_client $MOUNT "$MOUNT_OPTS,user_fid2path" ||
21548                 error "failed to mount client'"
21549
21550         $RUNAS $LFS rmfid $DIR $FID || error "rmfid failed"
21551         # rmfid should succeed
21552         cnt=$(ls -1 $DIR/$tdir | wc -l)
21553         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
21554
21555         # rmfid shouldn't allow to remove files due to dir's permission
21556         chmod a+rwx $DIR/$tdir
21557         touch $DIR/$tdir/f
21558         ls -la $DIR/$tdir
21559         FID=$(lfs path2fid $DIR/$tdir/f)
21560         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail"
21561
21562         umount_client $MOUNT || error "failed to umount client"
21563         mount_client $MOUNT "$MOUNT_OPTS" ||
21564                 error "failed to mount client'"
21565
21566 }
21567 run_test 421f "rmfid checks permissions"
21568
21569 test_421g() {
21570         local cnt
21571         local FIDS
21572
21573         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21574         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
21575                 skip "Need MDS version at least 2.12.54"
21576
21577         mkdir -p $DIR/$tdir
21578         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
21579         createmany -o $DIR/$tdir/striped_dir/f 512
21580         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
21581         [ $cnt != 512 ] && error "unexpected #files: $cnt"
21582
21583         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
21584                 sed "s/[/][^:]*://g")
21585
21586         rm -f $DIR/$tdir/striped_dir/f1*
21587         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
21588         removed=$((512 - cnt))
21589
21590         # few files have been just removed, so we expect
21591         # rmfid to fail on their fids
21592         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
21593         [ $removed != $errors ] && error "$errors != $removed"
21594
21595         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
21596         rm -rf $DIR/$tdir
21597         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
21598 }
21599 run_test 421g "rmfid to return errors properly"
21600
21601 test_422() {
21602         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
21603         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
21604         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
21605         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
21606         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
21607
21608         local amc=$(at_max_get client)
21609         local amo=$(at_max_get mds1)
21610         local timeout=`lctl get_param -n timeout`
21611
21612         at_max_set 0 client
21613         at_max_set 0 mds1
21614
21615 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
21616         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
21617                         fail_val=$(((2*timeout + 10)*1000))
21618         touch $DIR/$tdir/d3/file &
21619         sleep 2
21620 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
21621         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
21622                         fail_val=$((2*timeout + 5))
21623         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
21624         local pid=$!
21625         sleep 1
21626         kill -9 $pid
21627         sleep $((2 * timeout))
21628         echo kill $pid
21629         kill -9 $pid
21630         lctl mark touch
21631         touch $DIR/$tdir/d2/file3
21632         touch $DIR/$tdir/d2/file4
21633         touch $DIR/$tdir/d2/file5
21634
21635         wait
21636         at_max_set $amc client
21637         at_max_set $amo mds1
21638
21639         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
21640         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
21641                 error "Watchdog is always throttled"
21642 }
21643 run_test 422 "kill a process with RPC in progress"
21644
21645 prep_801() {
21646         [[ $(lustre_version_code mds1) -lt $(version_code 2.9.55) ]] ||
21647         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
21648                 skip "Need server version at least 2.9.55"
21649
21650         start_full_debug_logging
21651 }
21652
21653 post_801() {
21654         stop_full_debug_logging
21655 }
21656
21657 barrier_stat() {
21658         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
21659                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
21660                            awk '/The barrier for/ { print $7 }')
21661                 echo $st
21662         else
21663                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
21664                 echo \'$st\'
21665         fi
21666 }
21667
21668 barrier_expired() {
21669         local expired
21670
21671         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
21672                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
21673                           awk '/will be expired/ { print $7 }')
21674         else
21675                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
21676         fi
21677
21678         echo $expired
21679 }
21680
21681 test_801a() {
21682         prep_801
21683
21684         echo "Start barrier_freeze at: $(date)"
21685         #define OBD_FAIL_BARRIER_DELAY          0x2202
21686         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
21687         # Do not reduce barrier time - See LU-11873
21688         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
21689
21690         sleep 2
21691         local b_status=$(barrier_stat)
21692         echo "Got barrier status at: $(date)"
21693         [ "$b_status" = "'freezing_p1'" ] ||
21694                 error "(1) unexpected barrier status $b_status"
21695
21696         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
21697         wait
21698         b_status=$(barrier_stat)
21699         [ "$b_status" = "'frozen'" ] ||
21700                 error "(2) unexpected barrier status $b_status"
21701
21702         local expired=$(barrier_expired)
21703         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
21704         sleep $((expired + 3))
21705
21706         b_status=$(barrier_stat)
21707         [ "$b_status" = "'expired'" ] ||
21708                 error "(3) unexpected barrier status $b_status"
21709
21710         # Do not reduce barrier time - See LU-11873
21711         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
21712                 error "(4) fail to freeze barrier"
21713
21714         b_status=$(barrier_stat)
21715         [ "$b_status" = "'frozen'" ] ||
21716                 error "(5) unexpected barrier status $b_status"
21717
21718         echo "Start barrier_thaw at: $(date)"
21719         #define OBD_FAIL_BARRIER_DELAY          0x2202
21720         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
21721         do_facet mgs $LCTL barrier_thaw $FSNAME &
21722
21723         sleep 2
21724         b_status=$(barrier_stat)
21725         echo "Got barrier status at: $(date)"
21726         [ "$b_status" = "'thawing'" ] ||
21727                 error "(6) unexpected barrier status $b_status"
21728
21729         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
21730         wait
21731         b_status=$(barrier_stat)
21732         [ "$b_status" = "'thawed'" ] ||
21733                 error "(7) unexpected barrier status $b_status"
21734
21735         #define OBD_FAIL_BARRIER_FAILURE        0x2203
21736         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
21737         do_facet mgs $LCTL barrier_freeze $FSNAME
21738
21739         b_status=$(barrier_stat)
21740         [ "$b_status" = "'failed'" ] ||
21741                 error "(8) unexpected barrier status $b_status"
21742
21743         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
21744         do_facet mgs $LCTL barrier_thaw $FSNAME
21745
21746         post_801
21747 }
21748 run_test 801a "write barrier user interfaces and stat machine"
21749
21750 test_801b() {
21751         prep_801
21752
21753         mkdir $DIR/$tdir || error "(1) fail to mkdir"
21754         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
21755         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
21756         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
21757         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
21758
21759         cancel_lru_locks mdc
21760
21761         # 180 seconds should be long enough
21762         do_facet mgs $LCTL barrier_freeze $FSNAME 180
21763
21764         local b_status=$(barrier_stat)
21765         [ "$b_status" = "'frozen'" ] ||
21766                 error "(6) unexpected barrier status $b_status"
21767
21768         mkdir $DIR/$tdir/d0/d10 &
21769         mkdir_pid=$!
21770
21771         touch $DIR/$tdir/d1/f13 &
21772         touch_pid=$!
21773
21774         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
21775         ln_pid=$!
21776
21777         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
21778         mv_pid=$!
21779
21780         rm -f $DIR/$tdir/d4/f12 &
21781         rm_pid=$!
21782
21783         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
21784
21785         # To guarantee taht the 'stat' is not blocked
21786         b_status=$(barrier_stat)
21787         [ "$b_status" = "'frozen'" ] ||
21788                 error "(8) unexpected barrier status $b_status"
21789
21790         # let above commands to run at background
21791         sleep 5
21792
21793         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
21794         ps -p $touch_pid || error "(10) touch should be blocked"
21795         ps -p $ln_pid || error "(11) link should be blocked"
21796         ps -p $mv_pid || error "(12) rename should be blocked"
21797         ps -p $rm_pid || error "(13) unlink should be blocked"
21798
21799         b_status=$(barrier_stat)
21800         [ "$b_status" = "'frozen'" ] ||
21801                 error "(14) unexpected barrier status $b_status"
21802
21803         do_facet mgs $LCTL barrier_thaw $FSNAME
21804         b_status=$(barrier_stat)
21805         [ "$b_status" = "'thawed'" ] ||
21806                 error "(15) unexpected barrier status $b_status"
21807
21808         wait $mkdir_pid || error "(16) mkdir should succeed"
21809         wait $touch_pid || error "(17) touch should succeed"
21810         wait $ln_pid || error "(18) link should succeed"
21811         wait $mv_pid || error "(19) rename should succeed"
21812         wait $rm_pid || error "(20) unlink should succeed"
21813
21814         post_801
21815 }
21816 run_test 801b "modification will be blocked by write barrier"
21817
21818 test_801c() {
21819         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
21820
21821         prep_801
21822
21823         stop mds2 || error "(1) Fail to stop mds2"
21824
21825         do_facet mgs $LCTL barrier_freeze $FSNAME 30
21826
21827         local b_status=$(barrier_stat)
21828         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
21829                 do_facet mgs $LCTL barrier_thaw $FSNAME
21830                 error "(2) unexpected barrier status $b_status"
21831         }
21832
21833         do_facet mgs $LCTL barrier_rescan $FSNAME ||
21834                 error "(3) Fail to rescan barrier bitmap"
21835
21836         # Do not reduce barrier time - See LU-11873
21837         do_facet mgs $LCTL barrier_freeze $FSNAME 20
21838
21839         b_status=$(barrier_stat)
21840         [ "$b_status" = "'frozen'" ] ||
21841                 error "(4) unexpected barrier status $b_status"
21842
21843         do_facet mgs $LCTL barrier_thaw $FSNAME
21844         b_status=$(barrier_stat)
21845         [ "$b_status" = "'thawed'" ] ||
21846                 error "(5) unexpected barrier status $b_status"
21847
21848         local devname=$(mdsdevname 2)
21849
21850         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
21851
21852         do_facet mgs $LCTL barrier_rescan $FSNAME ||
21853                 error "(7) Fail to rescan barrier bitmap"
21854
21855         post_801
21856 }
21857 run_test 801c "rescan barrier bitmap"
21858
21859 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
21860 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
21861 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
21862 saved_MOUNT_OPTS=$MOUNT_OPTS
21863
21864 cleanup_802a() {
21865         trap 0
21866
21867         stopall
21868         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
21869         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
21870         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
21871         MOUNT_OPTS=$saved_MOUNT_OPTS
21872         setupall
21873 }
21874
21875 test_802a() {
21876         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
21877         [[ $(lustre_version_code mds1) -lt $(version_code 2.9.55) ]] ||
21878         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
21879                 skip "Need server version at least 2.9.55"
21880
21881         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
21882
21883         mkdir $DIR/$tdir || error "(1) fail to mkdir"
21884
21885         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
21886                 error "(2) Fail to copy"
21887
21888         trap cleanup_802a EXIT
21889
21890         # sync by force before remount as readonly
21891         sync; sync_all_data; sleep 3; sync_all_data
21892
21893         stopall
21894
21895         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
21896         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
21897         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
21898
21899         echo "Mount the server as read only"
21900         setupall server_only || error "(3) Fail to start servers"
21901
21902         echo "Mount client without ro should fail"
21903         mount_client $MOUNT &&
21904                 error "(4) Mount client without 'ro' should fail"
21905
21906         echo "Mount client with ro should succeed"
21907         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
21908         mount_client $MOUNT ||
21909                 error "(5) Mount client with 'ro' should succeed"
21910
21911         echo "Modify should be refused"
21912         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
21913
21914         echo "Read should be allowed"
21915         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
21916                 error "(7) Read should succeed under ro mode"
21917
21918         cleanup_802a
21919 }
21920 run_test 802a "simulate readonly device"
21921
21922 test_802b() {
21923         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21924         remote_mds_nodsh && skip "remote MDS with nodsh"
21925
21926         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
21927                 skip "readonly option not available"
21928
21929         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
21930
21931         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
21932                 error "(2) Fail to copy"
21933
21934         # write back all cached data before setting MDT to readonly
21935         cancel_lru_locks
21936         sync_all_data
21937
21938         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
21939         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
21940
21941         echo "Modify should be refused"
21942         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
21943
21944         echo "Read should be allowed"
21945         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
21946                 error "(7) Read should succeed under ro mode"
21947
21948         # disable readonly
21949         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
21950 }
21951 run_test 802b "be able to set MDTs to readonly"
21952
21953 test_803() {
21954         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
21955         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
21956                 skip "MDS needs to be newer than 2.10.54"
21957
21958         mkdir -p $DIR/$tdir
21959         # Create some objects on all MDTs to trigger related logs objects
21960         for idx in $(seq $MDSCOUNT); do
21961                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
21962                         $DIR/$tdir/dir${idx} ||
21963                         error "Fail to create $DIR/$tdir/dir${idx}"
21964         done
21965
21966         sync; sleep 3
21967         wait_delete_completed # ensure old test cleanups are finished
21968         echo "before create:"
21969         $LFS df -i $MOUNT
21970         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
21971
21972         for i in {1..10}; do
21973                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
21974                         error "Fail to create $DIR/$tdir/foo$i"
21975         done
21976
21977         sync; sleep 3
21978         echo "after create:"
21979         $LFS df -i $MOUNT
21980         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
21981
21982         # allow for an llog to be cleaned up during the test
21983         [ $after_used -ge $((before_used + 10 - 1)) ] ||
21984                 error "before ($before_used) + 10 > after ($after_used)"
21985
21986         for i in {1..10}; do
21987                 rm -rf $DIR/$tdir/foo$i ||
21988                         error "Fail to remove $DIR/$tdir/foo$i"
21989         done
21990
21991         sleep 3 # avoid MDT return cached statfs
21992         wait_delete_completed
21993         echo "after unlink:"
21994         $LFS df -i $MOUNT
21995         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
21996
21997         # allow for an llog to be created during the test
21998         [ $after_used -le $((before_used + 1)) ] ||
21999                 error "after ($after_used) > before ($before_used) + 1"
22000 }
22001 run_test 803 "verify agent object for remote object"
22002
22003 test_804() {
22004         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
22005         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
22006                 skip "MDS needs to be newer than 2.10.54"
22007         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
22008
22009         mkdir -p $DIR/$tdir
22010         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
22011                 error "Fail to create $DIR/$tdir/dir0"
22012
22013         local fid=$($LFS path2fid $DIR/$tdir/dir0)
22014         local dev=$(mdsdevname 2)
22015
22016         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
22017                 grep ${fid} || error "NOT found agent entry for dir0"
22018
22019         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
22020                 error "Fail to create $DIR/$tdir/dir1"
22021
22022         touch $DIR/$tdir/dir1/foo0 ||
22023                 error "Fail to create $DIR/$tdir/dir1/foo0"
22024         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
22025         local rc=0
22026
22027         for idx in $(seq $MDSCOUNT); do
22028                 dev=$(mdsdevname $idx)
22029                 do_facet mds${idx} \
22030                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
22031                         grep ${fid} && rc=$idx
22032         done
22033
22034         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
22035                 error "Fail to rename foo0 to foo1"
22036         if [ $rc -eq 0 ]; then
22037                 for idx in $(seq $MDSCOUNT); do
22038                         dev=$(mdsdevname $idx)
22039                         do_facet mds${idx} \
22040                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
22041                         grep ${fid} && rc=$idx
22042                 done
22043         fi
22044
22045         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
22046                 error "Fail to rename foo1 to foo2"
22047         if [ $rc -eq 0 ]; then
22048                 for idx in $(seq $MDSCOUNT); do
22049                         dev=$(mdsdevname $idx)
22050                         do_facet mds${idx} \
22051                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
22052                         grep ${fid} && rc=$idx
22053                 done
22054         fi
22055
22056         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
22057
22058         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
22059                 error "Fail to link to $DIR/$tdir/dir1/foo2"
22060         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
22061                 error "Fail to rename foo2 to foo0"
22062         unlink $DIR/$tdir/dir1/foo0 ||
22063                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
22064         rm -rf $DIR/$tdir/dir0 ||
22065                 error "Fail to rm $DIR/$tdir/dir0"
22066
22067         for idx in $(seq $MDSCOUNT); do
22068                 dev=$(mdsdevname $idx)
22069                 rc=0
22070
22071                 stop mds${idx}
22072                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
22073                         rc=$?
22074                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
22075                         error "mount mds$idx failed"
22076                 df $MOUNT > /dev/null 2>&1
22077
22078                 # e2fsck should not return error
22079                 [ $rc -eq 0 ] ||
22080                         error "e2fsck detected error on MDT${idx}: rc=$rc"
22081         done
22082 }
22083 run_test 804 "verify agent entry for remote entry"
22084
22085 cleanup_805() {
22086         do_facet $SINGLEMDS zfs set quota=$old $fsset
22087         unlinkmany $DIR/$tdir/f- 1000000
22088         trap 0
22089 }
22090
22091 test_805() {
22092         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
22093         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
22094         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
22095                 skip "netfree not implemented before 0.7"
22096         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
22097                 skip "Need MDS version at least 2.10.57"
22098
22099         local fsset
22100         local freekb
22101         local usedkb
22102         local old
22103         local quota
22104         local pref="osd-zfs.lustre-MDT0000."
22105
22106         # limit available space on MDS dataset to meet nospace issue
22107         # quickly. then ZFS 0.7.2 can use reserved space if asked
22108         # properly (using netfree flag in osd_declare_destroy()
22109         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
22110         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
22111                 gawk '{print $3}')
22112         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
22113         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
22114         let "usedkb=usedkb-freekb"
22115         let "freekb=freekb/2"
22116         if let "freekb > 5000"; then
22117                 let "freekb=5000"
22118         fi
22119         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
22120         trap cleanup_805 EXIT
22121         mkdir $DIR/$tdir
22122         $LFS setstripe -E 1M -L mdt $DIR/$tdir || error "DoM not working"
22123         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
22124         rm -rf $DIR/$tdir || error "not able to remove"
22125         do_facet $SINGLEMDS zfs set quota=$old $fsset
22126         trap 0
22127 }
22128 run_test 805 "ZFS can remove from full fs"
22129
22130 # Size-on-MDS test
22131 check_lsom_data()
22132 {
22133         local file=$1
22134         local size=$($LFS getsom -s $file)
22135         local expect=$(stat -c %s $file)
22136
22137         [[ $size == $expect ]] ||
22138                 error "$file expected size: $expect, got: $size"
22139
22140         local blocks=$($LFS getsom -b $file)
22141         expect=$(stat -c %b $file)
22142         [[ $blocks == $expect ]] ||
22143                 error "$file expected blocks: $expect, got: $blocks"
22144 }
22145
22146 check_lsom_size()
22147 {
22148         local size=$($LFS getsom -s $1)
22149         local expect=$2
22150
22151         [[ $size == $expect ]] ||
22152                 error "$file expected size: $expect, got: $size"
22153 }
22154
22155 test_806() {
22156         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22157                 skip "Need MDS version at least 2.11.52"
22158
22159         local bs=1048576
22160
22161         touch $DIR/$tfile || error "touch $tfile failed"
22162
22163         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22164         save_lustre_params client "llite.*.xattr_cache" > $save
22165         lctl set_param llite.*.xattr_cache=0
22166         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22167
22168         # single-threaded write
22169         echo "Test SOM for single-threaded write"
22170         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
22171                 error "write $tfile failed"
22172         check_lsom_size $DIR/$tfile $bs
22173
22174         local num=32
22175         local size=$(($num * $bs))
22176         local offset=0
22177         local i
22178
22179         echo "Test SOM for single client multi-threaded($num) write"
22180         $TRUNCATE $DIR/$tfile 0
22181         for ((i = 0; i < $num; i++)); do
22182                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
22183                 local pids[$i]=$!
22184                 offset=$((offset + $bs))
22185         done
22186         for (( i=0; i < $num; i++ )); do
22187                 wait ${pids[$i]}
22188         done
22189         check_lsom_size $DIR/$tfile $size
22190
22191         $TRUNCATE $DIR/$tfile 0
22192         for ((i = 0; i < $num; i++)); do
22193                 offset=$((offset - $bs))
22194                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
22195                 local pids[$i]=$!
22196         done
22197         for (( i=0; i < $num; i++ )); do
22198                 wait ${pids[$i]}
22199         done
22200         check_lsom_size $DIR/$tfile $size
22201
22202         # multi-client writes
22203         num=$(get_node_count ${CLIENTS//,/ })
22204         size=$(($num * $bs))
22205         offset=0
22206         i=0
22207
22208         echo "Test SOM for multi-client ($num) writes"
22209         $TRUNCATE $DIR/$tfile 0
22210         for client in ${CLIENTS//,/ }; do
22211                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
22212                 local pids[$i]=$!
22213                 i=$((i + 1))
22214                 offset=$((offset + $bs))
22215         done
22216         for (( i=0; i < $num; i++ )); do
22217                 wait ${pids[$i]}
22218         done
22219         check_lsom_size $DIR/$tfile $offset
22220
22221         i=0
22222         $TRUNCATE $DIR/$tfile 0
22223         for client in ${CLIENTS//,/ }; do
22224                 offset=$((offset - $bs))
22225                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
22226                 local pids[$i]=$!
22227                 i=$((i + 1))
22228         done
22229         for (( i=0; i < $num; i++ )); do
22230                 wait ${pids[$i]}
22231         done
22232         check_lsom_size $DIR/$tfile $size
22233
22234         # verify truncate
22235         echo "Test SOM for truncate"
22236         $TRUNCATE $DIR/$tfile 1048576
22237         check_lsom_size $DIR/$tfile 1048576
22238         $TRUNCATE $DIR/$tfile 1234
22239         check_lsom_size $DIR/$tfile 1234
22240
22241         # verify SOM blocks count
22242         echo "Verify SOM block count"
22243         $TRUNCATE $DIR/$tfile 0
22244         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
22245                 error "failed to write file $tfile"
22246         check_lsom_data $DIR/$tfile
22247 }
22248 run_test 806 "Verify Lazy Size on MDS"
22249
22250 test_807() {
22251         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
22252         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22253                 skip "Need MDS version at least 2.11.52"
22254
22255         # Registration step
22256         changelog_register || error "changelog_register failed"
22257         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
22258         changelog_users $SINGLEMDS | grep -q $cl_user ||
22259                 error "User $cl_user not found in changelog_users"
22260
22261         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22262         save_lustre_params client "llite.*.xattr_cache" > $save
22263         lctl set_param llite.*.xattr_cache=0
22264         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22265
22266         rm -rf $DIR/$tdir || error "rm $tdir failed"
22267         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
22268         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
22269         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
22270         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
22271                 error "truncate $tdir/trunc failed"
22272
22273         local bs=1048576
22274         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
22275                 error "write $tfile failed"
22276
22277         # multi-client wirtes
22278         local num=$(get_node_count ${CLIENTS//,/ })
22279         local offset=0
22280         local i=0
22281
22282         echo "Test SOM for multi-client ($num) writes"
22283         touch $DIR/$tfile || error "touch $tfile failed"
22284         $TRUNCATE $DIR/$tfile 0
22285         for client in ${CLIENTS//,/ }; do
22286                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
22287                 local pids[$i]=$!
22288                 i=$((i + 1))
22289                 offset=$((offset + $bs))
22290         done
22291         for (( i=0; i < $num; i++ )); do
22292                 wait ${pids[$i]}
22293         done
22294
22295         sleep 5
22296         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
22297         check_lsom_data $DIR/$tdir/trunc
22298         check_lsom_data $DIR/$tdir/single_dd
22299         check_lsom_data $DIR/$tfile
22300
22301         rm -rf $DIR/$tdir
22302         # Deregistration step
22303         changelog_deregister || error "changelog_deregister failed"
22304 }
22305 run_test 807 "verify LSOM syncing tool"
22306
22307 check_som_nologged()
22308 {
22309         local lines=$($LFS changelog $FSNAME-MDT0000 |
22310                 grep 'x=trusted.som' | wc -l)
22311         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
22312 }
22313
22314 test_808() {
22315         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
22316                 skip "Need MDS version at least 2.11.55"
22317
22318         # Registration step
22319         changelog_register || error "changelog_register failed"
22320
22321         touch $DIR/$tfile || error "touch $tfile failed"
22322         check_som_nologged
22323
22324         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
22325                 error "write $tfile failed"
22326         check_som_nologged
22327
22328         $TRUNCATE $DIR/$tfile 1234
22329         check_som_nologged
22330
22331         $TRUNCATE $DIR/$tfile 1048576
22332         check_som_nologged
22333
22334         # Deregistration step
22335         changelog_deregister || error "changelog_deregister failed"
22336 }
22337 run_test 808 "Check trusted.som xattr not logged in Changelogs"
22338
22339 check_som_nodata()
22340 {
22341         $LFS getsom $1
22342         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
22343 }
22344
22345 test_809() {
22346         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22347                 skip "Need MDS version at least 2.11.56"
22348
22349         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
22350                 error "failed to create DoM-only file $DIR/$tfile"
22351         touch $DIR/$tfile || error "touch $tfile failed"
22352         check_som_nodata $DIR/$tfile
22353
22354         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
22355                 error "write $tfile failed"
22356         check_som_nodata $DIR/$tfile
22357
22358         $TRUNCATE $DIR/$tfile 1234
22359         check_som_nodata $DIR/$tfile
22360
22361         $TRUNCATE $DIR/$tfile 4097
22362         check_som_nodata $DIR/$file
22363 }
22364 run_test 809 "Verify no SOM xattr store for DoM-only files"
22365
22366 test_810() {
22367         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22368         $GSS && skip_env "could not run with gss"
22369         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
22370                 skip "OST < 2.12.58 doesn't align checksum"
22371
22372         set_checksums 1
22373         stack_trap "set_checksums $ORIG_CSUM" EXIT
22374         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
22375
22376         local csum
22377         local before
22378         local after
22379         for csum in $CKSUM_TYPES; do
22380                 #define OBD_FAIL_OSC_NO_GRANT   0x411
22381                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
22382                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
22383                         eval set -- $i
22384                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
22385                         before=$(md5sum $DIR/$tfile)
22386                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
22387                         after=$(md5sum $DIR/$tfile)
22388                         [ "$before" == "$after" ] ||
22389                                 error "$csum: $before != $after bs=$1 seek=$2"
22390                 done
22391         done
22392 }
22393 run_test 810 "partial page writes on ZFS (LU-11663)"
22394
22395 test_811() {
22396         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.11.56) ] &&
22397                 skip "Need MDS version at least 2.11.56"
22398
22399         #define OBD_FAIL_MDS_ORPHAN_DELETE      0x165
22400         do_facet mds1 $LCTL set_param fail_loc=0x165
22401         $MULTIOP $DIR/$tfile Ouc || error "multiop failed"
22402
22403         stop mds1
22404         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
22405
22406         sleep 5
22407         [[ $(do_facet mds1 pgrep orph_.*-MDD | wc -l) -eq 0 ]] ||
22408                 error "MDD orphan cleanup thread not quit"
22409 }
22410 run_test 811 "orphan name stub can be cleaned up in startup"
22411
22412 test_812() {
22413         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
22414                 skip "OST < 2.12.51 doesn't support this fail_loc"
22415         [ "$SHARED_KEY" = true ] &&
22416                 skip "OSC connections never go IDLE with Shared-Keys enabled"
22417
22418         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22419         # ensure ost1 is connected
22420         stat $DIR/$tfile >/dev/null || error "can't stat"
22421         wait_osc_import_state client ost1 FULL
22422         # no locks, no reqs to let the connection idle
22423         cancel_lru_locks osc
22424
22425         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
22426 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
22427         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
22428         wait_osc_import_state client ost1 CONNECTING
22429         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
22430
22431         stat $DIR/$tfile >/dev/null || error "can't stat file"
22432 }
22433 run_test 812 "do not drop reqs generated when imp is going to idle (LU-11951)"
22434
22435 test_813() {
22436         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
22437         [ -z "$file_heat_sav" ] && skip "no file heat support"
22438
22439         local readsample
22440         local writesample
22441         local readbyte
22442         local writebyte
22443         local readsample1
22444         local writesample1
22445         local readbyte1
22446         local writebyte1
22447
22448         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
22449         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
22450
22451         $LCTL set_param -n llite.*.file_heat=1
22452         echo "Turn on file heat"
22453         echo "Period second: $period_second, Decay percentage: $decay_pct"
22454
22455         echo "QQQQ" > $DIR/$tfile
22456         echo "QQQQ" > $DIR/$tfile
22457         echo "QQQQ" > $DIR/$tfile
22458         cat $DIR/$tfile > /dev/null
22459         cat $DIR/$tfile > /dev/null
22460         cat $DIR/$tfile > /dev/null
22461         cat $DIR/$tfile > /dev/null
22462
22463         local out=$($LFS heat_get $DIR/$tfile)
22464
22465         $LFS heat_get $DIR/$tfile
22466         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
22467         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
22468         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
22469         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
22470
22471         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
22472         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
22473         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
22474         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
22475
22476         sleep $((period_second + 3))
22477         echo "Sleep $((period_second + 3)) seconds..."
22478         # The recursion formula to calculate the heat of the file f is as
22479         # follow:
22480         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
22481         # Where Hi is the heat value in the period between time points i*I and
22482         # (i+1)*I; Ci is the access count in the period; the symbol P refers
22483         # to the weight of Ci.
22484         out=$($LFS heat_get $DIR/$tfile)
22485         $LFS heat_get $DIR/$tfile
22486         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
22487         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
22488         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
22489         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
22490
22491         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
22492                 error "read sample ($readsample) is wrong"
22493         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
22494                 error "write sample ($writesample) is wrong"
22495         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
22496                 error "read bytes ($readbyte) is wrong"
22497         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
22498                 error "write bytes ($writebyte) is wrong"
22499
22500         echo "QQQQ" > $DIR/$tfile
22501         echo "QQQQ" > $DIR/$tfile
22502         echo "QQQQ" > $DIR/$tfile
22503         cat $DIR/$tfile > /dev/null
22504         cat $DIR/$tfile > /dev/null
22505         cat $DIR/$tfile > /dev/null
22506         cat $DIR/$tfile > /dev/null
22507
22508         sleep $((period_second + 3))
22509         echo "Sleep $((period_second + 3)) seconds..."
22510
22511         out=$($LFS heat_get $DIR/$tfile)
22512         $LFS heat_get $DIR/$tfile
22513         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
22514         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
22515         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
22516         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
22517
22518         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
22519                 4 * $decay_pct) / 100") -eq 1 ] ||
22520                 error "read sample ($readsample1) is wrong"
22521         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
22522                 3 * $decay_pct) / 100") -eq 1 ] ||
22523                 error "write sample ($writesample1) is wrong"
22524         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
22525                 20 * $decay_pct) / 100") -eq 1 ] ||
22526                 error "read bytes ($readbyte1) is wrong"
22527         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
22528                 15 * $decay_pct) / 100") -eq 1 ] ||
22529                 error "write bytes ($writebyte1) is wrong"
22530
22531         echo "Turn off file heat for the file $DIR/$tfile"
22532         $LFS heat_set -o $DIR/$tfile
22533
22534         echo "QQQQ" > $DIR/$tfile
22535         echo "QQQQ" > $DIR/$tfile
22536         echo "QQQQ" > $DIR/$tfile
22537         cat $DIR/$tfile > /dev/null
22538         cat $DIR/$tfile > /dev/null
22539         cat $DIR/$tfile > /dev/null
22540         cat $DIR/$tfile > /dev/null
22541
22542         out=$($LFS heat_get $DIR/$tfile)
22543         $LFS heat_get $DIR/$tfile
22544         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
22545         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
22546         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
22547         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
22548
22549         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
22550         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
22551         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
22552         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
22553
22554         echo "Trun on file heat for the file $DIR/$tfile"
22555         $LFS heat_set -O $DIR/$tfile
22556
22557         echo "QQQQ" > $DIR/$tfile
22558         echo "QQQQ" > $DIR/$tfile
22559         echo "QQQQ" > $DIR/$tfile
22560         cat $DIR/$tfile > /dev/null
22561         cat $DIR/$tfile > /dev/null
22562         cat $DIR/$tfile > /dev/null
22563         cat $DIR/$tfile > /dev/null
22564
22565         out=$($LFS heat_get $DIR/$tfile)
22566         $LFS heat_get $DIR/$tfile
22567         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
22568         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
22569         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
22570         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
22571
22572         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
22573         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
22574         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
22575         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
22576
22577         $LFS heat_set -c $DIR/$tfile
22578         $LCTL set_param -n llite.*.file_heat=0
22579         echo "Turn off file heat support for the Lustre filesystem"
22580
22581         echo "QQQQ" > $DIR/$tfile
22582         echo "QQQQ" > $DIR/$tfile
22583         echo "QQQQ" > $DIR/$tfile
22584         cat $DIR/$tfile > /dev/null
22585         cat $DIR/$tfile > /dev/null
22586         cat $DIR/$tfile > /dev/null
22587         cat $DIR/$tfile > /dev/null
22588
22589         out=$($LFS heat_get $DIR/$tfile)
22590         $LFS heat_get $DIR/$tfile
22591         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
22592         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
22593         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
22594         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
22595
22596         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
22597         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
22598         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
22599         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
22600
22601         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
22602         rm -f $DIR/$tfile
22603 }
22604 run_test 813 "File heat verfication"
22605
22606 test_814()
22607 {
22608         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
22609         echo -n y >> $DIR/$tfile
22610         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
22611         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
22612 }
22613 run_test 814 "sparse cp works as expected (LU-12361)"
22614
22615 test_815()
22616 {
22617         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
22618         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
22619 }
22620 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
22621
22622 test_816() {
22623         [ "$SHARED_KEY" = true ] &&
22624                 skip "OSC connections never go IDLE with Shared-Keys enabled"
22625
22626         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22627         # ensure ost1 is connected
22628         stat $DIR/$tfile >/dev/null || error "can't stat"
22629         wait_osc_import_state client ost1 FULL
22630         # no locks, no reqs to let the connection idle
22631         cancel_lru_locks osc
22632         lru_resize_disable osc
22633         local before
22634         local now
22635         before=$($LCTL get_param -n \
22636                  ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
22637
22638         wait_osc_import_state client ost1 IDLE
22639         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
22640         now=$($LCTL get_param -n \
22641               ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
22642         [ $before == $now ] || error "lru_size changed $before != $now"
22643 }
22644 run_test 816 "do not reset lru_resize on idle reconnect"
22645
22646 cleanup_817() {
22647         umount $tmpdir
22648         exportfs -u localhost:$DIR/nfsexp
22649         rm -rf $DIR/nfsexp
22650 }
22651
22652 test_817() {
22653         systemctl restart nfs-server.service || skip "failed to restart nfsd"
22654
22655         mkdir -p $DIR/nfsexp
22656         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
22657                 error "failed to export nfs"
22658
22659         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
22660         stack_trap cleanup_817 EXIT
22661
22662         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
22663                 error "failed to mount nfs to $tmpdir"
22664
22665         cp /bin/true $tmpdir
22666         $DIR/nfsexp/true || error "failed to execute 'true' command"
22667 }
22668 run_test 817 "nfsd won't cache write lock for exec file"
22669
22670 test_818() {
22671         mkdir $DIR/$tdir
22672         $LFS setstripe -c1 -i0 $DIR/$tfile
22673         $LFS setstripe -c1 -i1 $DIR/$tfile
22674         stop $SINGLEMDS
22675         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
22676         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
22677         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
22678                 error "start $SINGLEMDS failed"
22679         rm -rf $DIR/$tdir
22680 }
22681 run_test 818 "unlink with failed llog"
22682
22683 test_819a() {
22684         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22685         cancel_lru_locks osc
22686         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
22687         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
22688         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
22689         rm -f $TDIR/$tfile
22690 }
22691 run_test 819a "too big niobuf in read"
22692
22693 test_819b() {
22694         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
22695         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
22696         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22697         cancel_lru_locks osc
22698         sleep 1
22699         rm -f $TDIR/$tfile
22700 }
22701 run_test 819b "too big niobuf in write"
22702
22703 #
22704 # tests that do cleanup/setup should be run at the end
22705 #
22706
22707 test_900() {
22708         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22709         local ls
22710
22711         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
22712         $LCTL set_param fail_loc=0x903
22713
22714         cancel_lru_locks MGC
22715
22716         FAIL_ON_ERROR=true cleanup
22717         FAIL_ON_ERROR=true setup
22718 }
22719 run_test 900 "umount should not race with any mgc requeue thread"
22720
22721 complete $SECONDS
22722 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
22723 check_and_cleanup_lustre
22724 if [ "$I_MOUNTED" != "yes" ]; then
22725         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
22726 fi
22727 exit_status