Whamcloud - gitweb
LU-13745 tests: skip sanity test_426 for 4.15+
[fs/lustre-release.git] / lustre / tests / sanity.sh
1 #!/bin/bash
2 #
3 # Run select tests by setting ONLY, or as arguments to the script.
4 # Skip specific tests by setting EXCEPT.
5 #
6 # e.g. ONLY="22 23" or ONLY="`seq 32 39`" or EXCEPT="31"
7 set -e
8
9 ONLY=${ONLY:-"$*"}
10
11 # Check Grants after these tests
12 GRANT_CHECK_LIST="$GRANT_CHECK_LIST 42a 42b 42c 42d 42e 63a 63b 64a 64b 64c 64d"
13
14 OSC=${OSC:-"osc"}
15
16 CC=${CC:-cc}
17 CREATETEST=${CREATETEST:-createtest}
18 LVERIFY=${LVERIFY:-ll_dirstripe_verify}
19 OPENFILE=${OPENFILE:-openfile}
20 OPENUNLINK=${OPENUNLINK:-openunlink}
21 READS=${READS:-"reads"}
22 MUNLINK=${MUNLINK:-munlink}
23 SOCKETSERVER=${SOCKETSERVER:-socketserver}
24 SOCKETCLIENT=${SOCKETCLIENT:-socketclient}
25 MEMHOG=${MEMHOG:-memhog}
26 DIRECTIO=${DIRECTIO:-directio}
27 ACCEPTOR_PORT=${ACCEPTOR_PORT:-988}
28 DEF_STRIPE_COUNT=-1
29 CHECK_GRANT=${CHECK_GRANT:-"yes"}
30 GRANT_CHECK_LIST=${GRANT_CHECK_LIST:-""}
31 export PARALLEL=${PARALLEL:-"no"}
32
33 TRACE=${TRACE:-""}
34 LUSTRE=${LUSTRE:-$(dirname $0)/..}
35 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
36 . $LUSTRE/tests/test-framework.sh
37 init_test_env $@
38
39 init_logging
40
41 ALWAYS_EXCEPT="$SANITY_EXCEPT "
42 # bug number for skipped test: LU-9693 LU-6493 LU-9693
43 ALWAYS_EXCEPT+="               42a     42b     42c "
44 # bug number:    LU-8411 LU-9054
45 ALWAYS_EXCEPT+=" 407     312"
46
47 if $SHARED_KEY; then
48         # bug number:    LU-9795 LU-9795 LU-9795 LU-9795
49         ALWAYS_EXCEPT+=" 17n     60a     133g    300f"
50 fi
51
52 selinux_status=$(getenforce)
53 if [ "$selinux_status" != "Disabled" ]; then
54         # bug number:
55         ALWAYS_EXCEPT+=""
56 fi
57
58 # skip the grant tests for ARM until they are fixed
59 if [[ $(uname -m) = aarch64 ]]; then
60         # bug number:    LU-11596
61         ALWAYS_EXCEPT+=" $GRANT_CHECK_LIST"
62         # bug number:    LU-11671 LU-11667
63         ALWAYS_EXCEPT+=" 45       317"
64         # bug number:    LU-14067 LU-14067
65         ALWAYS_EXCEPT+=" 400a     400b"
66 fi
67
68 # skip splice tests on kernels >= 4.15.0 until they are fixed
69 if [ $LINUX_VERSION_CODE -ge $(version_code 4.15.0) ]; then
70         # bug number:   LU-14045
71         ALWAYS_EXCEPT+=" 426"
72 fi
73 # skip nfs tests on kernels >= 4.12.0 until they are fixed
74 if [ $LINUX_VERSION_CODE -ge $(version_code 4.12.0) ]; then
75         # bug number:   LU-12661
76         ALWAYS_EXCEPT+=" 817"
77 fi
78 # skip cgroup tests on RHEL8.1 kernels until they are fixed
79 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
80       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
81         # bug number:   LU-13063
82         ALWAYS_EXCEPT+=" 411"
83 fi
84
85 #                                  5          12     8   12  (min)"
86 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 64b 68 71 115 135 136 300o"
87
88 if [ "$mds1_FSTYPE" = "zfs" ]; then
89         # bug number for skipped test:
90         ALWAYS_EXCEPT="$ALWAYS_EXCEPT  "
91         #                                               13    (min)"
92         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
93 fi
94
95 # Get the SLES distro version
96 #
97 # Returns a version string that should only be used in comparing
98 # strings returned by version_code()
99 sles_version_code()
100 {
101         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
102
103         # All SuSE Linux versions have one decimal. version_code expects two
104         local sles_version=$version.0
105         version_code $sles_version
106 }
107
108 # Check if we are running on Ubuntu or SLES so we can make decisions on
109 # what tests to run
110 if [ -r /etc/SuSE-release ]; then
111         sles_version=$(sles_version_code)
112         [ $sles_version -lt $(version_code 11.4.0) ] &&
113                 # bug number for skipped test: LU-4341
114                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  170"
115         [ $sles_version -lt $(version_code 12.0.0) ] &&
116                 # bug number for skipped test: LU-3703
117                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  234"
118 elif [ -r /etc/os-release ]; then
119         if grep -qi ubuntu /etc/os-release; then
120                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
121                                                 -e 's/^VERSION=//p' \
122                                                 /etc/os-release |
123                                                 awk '{ print $1 }'))
124
125                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
126                         # bug number for skipped test:
127                         #                LU-10334 LU-10366
128                         ALWAYS_EXCEPT+=" 103a     410"
129                 fi
130         fi
131 fi
132
133 build_test_filter
134 FAIL_ON_ERROR=false
135
136 cleanup() {
137         echo -n "cln.."
138         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
139         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
140 }
141 setup() {
142         echo -n "mnt.."
143         load_modules
144         setupall || exit 10
145         echo "done"
146 }
147
148 check_swap_layouts_support()
149 {
150         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
151                 skip "Does not support layout lock."
152 }
153
154 check_swap_layout_no_dom()
155 {
156         local FOLDER=$1
157         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
158         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
159 }
160
161 check_and_setup_lustre
162 DIR=${DIR:-$MOUNT}
163 assert_DIR
164
165 MAXFREE=${MAXFREE:-$((200000 * $OSTCOUNT))}
166
167 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
168 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
169 rm -rf $DIR/[Rdfs][0-9]*
170
171 # $RUNAS_ID may get set incorrectly somewhere else
172 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
173         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
174
175 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
176
177 if [ "${ONLY}" = "MOUNT" ] ; then
178         echo "Lustre is up, please go on"
179         exit
180 fi
181
182 echo "preparing for tests involving mounts"
183 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
184 touch $EXT2_DEV
185 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
186 echo # add a newline after mke2fs.
187
188 umask 077
189
190 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
191 lctl set_param debug=-1 2> /dev/null || true
192 test_0a() {
193         touch $DIR/$tfile
194         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
195         rm $DIR/$tfile
196         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
197 }
198 run_test 0a "touch; rm ====================="
199
200 test_0b() {
201         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
202         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
203 }
204 run_test 0b "chmod 0755 $DIR ============================="
205
206 test_0c() {
207         $LCTL get_param mdc.*.import | grep "state: FULL" ||
208                 error "import not FULL"
209         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
210                 error "bad target"
211 }
212 run_test 0c "check import proc"
213
214 test_0d() { # LU-3397
215         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
216                 skip "proc exports not supported before 2.10.57"
217
218         local mgs_exp="mgs.MGS.exports"
219         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
220         local exp_client_nid
221         local exp_client_version
222         local exp_val
223         local imp_val
224         local temp_imp=$DIR/$tfile.import
225         local temp_exp=$DIR/$tfile.export
226
227         # save mgc import file to $temp_imp
228         $LCTL get_param mgc.*.import | tee $temp_imp
229         # Check if client uuid is found in MGS export
230         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
231                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
232                         $client_uuid ] &&
233                         break;
234         done
235         # save mgs export file to $temp_exp
236         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
237
238         # Compare the value of field "connect_flags"
239         imp_val=$(grep "connect_flags" $temp_imp)
240         exp_val=$(grep "connect_flags" $temp_exp)
241         [ "$exp_val" == "$imp_val" ] ||
242                 error "export flags '$exp_val' != import flags '$imp_val'"
243
244         # Compare the value of client version
245         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
246         exp_val=$(version_code $exp_client_version)
247         imp_val=$CLIENT_VERSION
248         [ "$exp_val" == "$imp_val" ] ||
249                 error "export client version '$exp_val' != '$imp_val'"
250 }
251 run_test 0d "check export proc ============================="
252
253 test_1() {
254         test_mkdir $DIR/$tdir
255         test_mkdir $DIR/$tdir/d2
256         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
257         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
258         rmdir $DIR/$tdir/d2
259         rmdir $DIR/$tdir
260         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
261 }
262 run_test 1 "mkdir; remkdir; rmdir"
263
264 test_2() {
265         test_mkdir $DIR/$tdir
266         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
267         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
268         rm -r $DIR/$tdir
269         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
270 }
271 run_test 2 "mkdir; touch; rmdir; check file"
272
273 test_3() {
274         test_mkdir $DIR/$tdir
275         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
276         touch $DIR/$tdir/$tfile
277         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
278         rm -r $DIR/$tdir
279         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
280 }
281 run_test 3 "mkdir; touch; rmdir; check dir"
282
283 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
284 test_4() {
285         test_mkdir -i 1 $DIR/$tdir
286
287         touch $DIR/$tdir/$tfile ||
288                 error "Create file under remote directory failed"
289
290         rmdir $DIR/$tdir &&
291                 error "Expect error removing in-use dir $DIR/$tdir"
292
293         test -d $DIR/$tdir || error "Remote directory disappeared"
294
295         rm -rf $DIR/$tdir || error "remove remote dir error"
296 }
297 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
298
299 test_5() {
300         test_mkdir $DIR/$tdir
301         test_mkdir $DIR/$tdir/d2
302         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
303         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
304         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
305 }
306 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
307
308 test_6a() {
309         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
310         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
311         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
312                 error "$tfile does not have perm 0666 or UID $UID"
313         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
314         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
315                 error "$tfile should be 0666 and owned by UID $UID"
316 }
317 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
318
319 test_6c() {
320         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
321
322         touch $DIR/$tfile
323         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
324         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
325                 error "$tfile should be owned by UID $RUNAS_ID"
326         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
327         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
328                 error "$tfile should be owned by UID $RUNAS_ID"
329 }
330 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
331
332 test_6e() {
333         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
334
335         touch $DIR/$tfile
336         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
337         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
338                 error "$tfile should be owned by GID $UID"
339         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
340         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
341                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
342 }
343 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
344
345 test_6g() {
346         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
347
348         test_mkdir $DIR/$tdir
349         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
350         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
351         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
352         test_mkdir $DIR/$tdir/d/subdir
353         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
354                 error "$tdir/d/subdir should be GID $RUNAS_GID"
355         if [[ $MDSCOUNT -gt 1 ]]; then
356                 # check remote dir sgid inherite
357                 $LFS mkdir -i 0 $DIR/$tdir.local ||
358                         error "mkdir $tdir.local failed"
359                 chmod g+s $DIR/$tdir.local ||
360                         error "chmod $tdir.local failed"
361                 chgrp $RUNAS_GID $DIR/$tdir.local ||
362                         error "chgrp $tdir.local failed"
363                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
364                         error "mkdir $tdir.remote failed"
365                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
366                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
367                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
368                         error "$tdir.remote should be mode 02755"
369         fi
370 }
371 run_test 6g "verify new dir in sgid dir inherits group"
372
373 test_6h() { # bug 7331
374         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
375
376         touch $DIR/$tfile || error "touch failed"
377         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
378         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
379                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
380         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
381                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
382 }
383 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
384
385 test_7a() {
386         test_mkdir $DIR/$tdir
387         $MCREATE $DIR/$tdir/$tfile
388         chmod 0666 $DIR/$tdir/$tfile
389         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
390                 error "$tdir/$tfile should be mode 0666"
391 }
392 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
393
394 test_7b() {
395         if [ ! -d $DIR/$tdir ]; then
396                 test_mkdir $DIR/$tdir
397         fi
398         $MCREATE $DIR/$tdir/$tfile
399         echo -n foo > $DIR/$tdir/$tfile
400         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
401         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
402 }
403 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
404
405 test_8() {
406         test_mkdir $DIR/$tdir
407         touch $DIR/$tdir/$tfile
408         chmod 0666 $DIR/$tdir/$tfile
409         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
410                 error "$tfile mode not 0666"
411 }
412 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
413
414 test_9() {
415         test_mkdir $DIR/$tdir
416         test_mkdir $DIR/$tdir/d2
417         test_mkdir $DIR/$tdir/d2/d3
418         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
419 }
420 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
421
422 test_10() {
423         test_mkdir $DIR/$tdir
424         test_mkdir $DIR/$tdir/d2
425         touch $DIR/$tdir/d2/$tfile
426         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
427                 error "$tdir/d2/$tfile not a file"
428 }
429 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
430
431 test_11() {
432         test_mkdir $DIR/$tdir
433         test_mkdir $DIR/$tdir/d2
434         chmod 0666 $DIR/$tdir/d2
435         chmod 0705 $DIR/$tdir/d2
436         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
437                 error "$tdir/d2 mode not 0705"
438 }
439 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
440
441 test_12() {
442         test_mkdir $DIR/$tdir
443         touch $DIR/$tdir/$tfile
444         chmod 0666 $DIR/$tdir/$tfile
445         chmod 0654 $DIR/$tdir/$tfile
446         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
447                 error "$tdir/d2 mode not 0654"
448 }
449 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
450
451 test_13() {
452         test_mkdir $DIR/$tdir
453         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
454         >  $DIR/$tdir/$tfile
455         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
456                 error "$tdir/$tfile size not 0 after truncate"
457 }
458 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
459
460 test_14() {
461         test_mkdir $DIR/$tdir
462         touch $DIR/$tdir/$tfile
463         rm $DIR/$tdir/$tfile
464         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
465 }
466 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
467
468 test_15() {
469         test_mkdir $DIR/$tdir
470         touch $DIR/$tdir/$tfile
471         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
472         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
473                 error "$tdir/${tfile_2} not a file after rename"
474         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
475 }
476 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
477
478 test_16() {
479         test_mkdir $DIR/$tdir
480         touch $DIR/$tdir/$tfile
481         rm -rf $DIR/$tdir/$tfile
482         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
483 }
484 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
485
486 test_17a() {
487         test_mkdir $DIR/$tdir
488         touch $DIR/$tdir/$tfile
489         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
490         ls -l $DIR/$tdir
491         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
492                 error "$tdir/l-exist not a symlink"
493         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
494                 error "$tdir/l-exist not referencing a file"
495         rm -f $DIR/$tdir/l-exist
496         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
497 }
498 run_test 17a "symlinks: create, remove (real)"
499
500 test_17b() {
501         test_mkdir $DIR/$tdir
502         ln -s no-such-file $DIR/$tdir/l-dangle
503         ls -l $DIR/$tdir
504         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
505                 error "$tdir/l-dangle not referencing no-such-file"
506         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
507                 error "$tdir/l-dangle not referencing non-existent file"
508         rm -f $DIR/$tdir/l-dangle
509         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
510 }
511 run_test 17b "symlinks: create, remove (dangling)"
512
513 test_17c() { # bug 3440 - don't save failed open RPC for replay
514         test_mkdir $DIR/$tdir
515         ln -s foo $DIR/$tdir/$tfile
516         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
517 }
518 run_test 17c "symlinks: open dangling (should return error)"
519
520 test_17d() {
521         test_mkdir $DIR/$tdir
522         ln -s foo $DIR/$tdir/$tfile
523         touch $DIR/$tdir/$tfile || error "creating to new symlink"
524 }
525 run_test 17d "symlinks: create dangling"
526
527 test_17e() {
528         test_mkdir $DIR/$tdir
529         local foo=$DIR/$tdir/$tfile
530         ln -s $foo $foo || error "create symlink failed"
531         ls -l $foo || error "ls -l failed"
532         ls $foo && error "ls not failed" || true
533 }
534 run_test 17e "symlinks: create recursive symlink (should return error)"
535
536 test_17f() {
537         test_mkdir $DIR/$tdir
538         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
539         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
540         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
541         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
542         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
543         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
544         ls -l  $DIR/$tdir
545 }
546 run_test 17f "symlinks: long and very long symlink name"
547
548 # str_repeat(S, N) generate a string that is string S repeated N times
549 str_repeat() {
550         local s=$1
551         local n=$2
552         local ret=''
553         while [ $((n -= 1)) -ge 0 ]; do
554                 ret=$ret$s
555         done
556         echo $ret
557 }
558
559 # Long symlinks and LU-2241
560 test_17g() {
561         test_mkdir $DIR/$tdir
562         local TESTS="59 60 61 4094 4095"
563
564         # Fix for inode size boundary in 2.1.4
565         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
566                 TESTS="4094 4095"
567
568         # Patch not applied to 2.2 or 2.3 branches
569         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
570         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
571                 TESTS="4094 4095"
572
573         for i in $TESTS; do
574                 local SYMNAME=$(str_repeat 'x' $i)
575                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
576                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
577         done
578 }
579 run_test 17g "symlinks: really long symlink name and inode boundaries"
580
581 test_17h() { #bug 17378
582         [ $PARALLEL == "yes" ] && skip "skip parallel run"
583         remote_mds_nodsh && skip "remote MDS with nodsh"
584
585         local mdt_idx
586
587         test_mkdir $DIR/$tdir
588         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
589         $LFS setstripe -c -1 $DIR/$tdir
590         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
591         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
592         touch $DIR/$tdir/$tfile || true
593 }
594 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
595
596 test_17i() { #bug 20018
597         [ $PARALLEL == "yes" ] && skip "skip parallel run"
598         remote_mds_nodsh && skip "remote MDS with nodsh"
599
600         local foo=$DIR/$tdir/$tfile
601         local mdt_idx
602
603         test_mkdir -c1 $DIR/$tdir
604         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
605         ln -s $foo $foo || error "create symlink failed"
606 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
607         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
608         ls -l $foo && error "error not detected"
609         return 0
610 }
611 run_test 17i "don't panic on short symlink (should return error)"
612
613 test_17k() { #bug 22301
614         [ $PARALLEL == "yes" ] && skip "skip parallel run"
615         [[ -z "$(which rsync 2>/dev/null)" ]] &&
616                 skip "no rsync command"
617         rsync --help | grep -q xattr ||
618                 skip_env "$(rsync --version | head -n1) does not support xattrs"
619         test_mkdir $DIR/$tdir
620         test_mkdir $DIR/$tdir.new
621         touch $DIR/$tdir/$tfile
622         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
623         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
624                 error "rsync failed with xattrs enabled"
625 }
626 run_test 17k "symlinks: rsync with xattrs enabled"
627
628 test_17l() { # LU-279
629         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
630                 skip "no getfattr command"
631
632         test_mkdir $DIR/$tdir
633         touch $DIR/$tdir/$tfile
634         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
635         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
636                 # -h to not follow symlinks. -m '' to list all the xattrs.
637                 # grep to remove first line: '# file: $path'.
638                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
639                 do
640                         lgetxattr_size_check $path $xattr ||
641                                 error "lgetxattr_size_check $path $xattr failed"
642                 done
643         done
644 }
645 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
646
647 # LU-1540
648 test_17m() {
649         [ $PARALLEL == "yes" ] && skip "skip parallel run"
650         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
651         remote_mds_nodsh && skip "remote MDS with nodsh"
652         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
653         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
654                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
655
656         local short_sym="0123456789"
657         local wdir=$DIR/$tdir
658         local i
659
660         test_mkdir $wdir
661         long_sym=$short_sym
662         # create a long symlink file
663         for ((i = 0; i < 4; ++i)); do
664                 long_sym=${long_sym}${long_sym}
665         done
666
667         echo "create 512 short and long symlink files under $wdir"
668         for ((i = 0; i < 256; ++i)); do
669                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
670                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
671         done
672
673         echo "erase them"
674         rm -f $wdir/*
675         sync
676         wait_delete_completed
677
678         echo "recreate the 512 symlink files with a shorter string"
679         for ((i = 0; i < 512; ++i)); do
680                 # rewrite the symlink file with a shorter string
681                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
682                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
683         done
684
685         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
686         local devname=$(mdsdevname $mds_index)
687
688         echo "stop and checking mds${mds_index}:"
689         # e2fsck should not return error
690         stop mds${mds_index}
691         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
692         rc=$?
693
694         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
695                 error "start mds${mds_index} failed"
696         df $MOUNT > /dev/null 2>&1
697         [ $rc -eq 0 ] ||
698                 error "e2fsck detected error for short/long symlink: rc=$rc"
699         rm -f $wdir/*
700 }
701 run_test 17m "run e2fsck against MDT which contains short/long symlink"
702
703 check_fs_consistency_17n() {
704         local mdt_index
705         local rc=0
706
707         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
708         # so it only check MDT1/MDT2 instead of all of MDTs.
709         for mdt_index in 1 2; do
710                 local devname=$(mdsdevname $mdt_index)
711                 # e2fsck should not return error
712                 stop mds${mdt_index}
713                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
714                         rc=$((rc + $?))
715
716                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
717                         error "mount mds$mdt_index failed"
718                 df $MOUNT > /dev/null 2>&1
719         done
720         return $rc
721 }
722
723 test_17n() {
724         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
725         [ $PARALLEL == "yes" ] && skip "skip parallel run"
726         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
727         remote_mds_nodsh && skip "remote MDS with nodsh"
728         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
729         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
730                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
731
732         local i
733
734         test_mkdir $DIR/$tdir
735         for ((i=0; i<10; i++)); do
736                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
737                         error "create remote dir error $i"
738                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
739                         error "create files under remote dir failed $i"
740         done
741
742         check_fs_consistency_17n ||
743                 error "e2fsck report error after create files under remote dir"
744
745         for ((i = 0; i < 10; i++)); do
746                 rm -rf $DIR/$tdir/remote_dir_${i} ||
747                         error "destroy remote dir error $i"
748         done
749
750         check_fs_consistency_17n ||
751                 error "e2fsck report error after unlink files under remote dir"
752
753         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
754                 skip "lustre < 2.4.50 does not support migrate mv"
755
756         for ((i = 0; i < 10; i++)); do
757                 mkdir -p $DIR/$tdir/remote_dir_${i}
758                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
759                         error "create files under remote dir failed $i"
760                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
761                         error "migrate remote dir error $i"
762         done
763         check_fs_consistency_17n || error "e2fsck report error after migration"
764
765         for ((i = 0; i < 10; i++)); do
766                 rm -rf $DIR/$tdir/remote_dir_${i} ||
767                         error "destroy remote dir error $i"
768         done
769
770         check_fs_consistency_17n || error "e2fsck report error after unlink"
771 }
772 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
773
774 test_17o() {
775         remote_mds_nodsh && skip "remote MDS with nodsh"
776         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
777                 skip "Need MDS version at least 2.3.64"
778
779         local wdir=$DIR/${tdir}o
780         local mdt_index
781         local rc=0
782
783         test_mkdir $wdir
784         touch $wdir/$tfile
785         mdt_index=$($LFS getstripe -m $wdir/$tfile)
786         mdt_index=$((mdt_index + 1))
787
788         cancel_lru_locks mdc
789         #fail mds will wait the failover finish then set
790         #following fail_loc to avoid interfer the recovery process.
791         fail mds${mdt_index}
792
793         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
794         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
795         ls -l $wdir/$tfile && rc=1
796         do_facet mds${mdt_index} lctl set_param fail_loc=0
797         [[ $rc -eq 0 ]] || error "stat file should fail"
798 }
799 run_test 17o "stat file with incompat LMA feature"
800
801 test_18() {
802         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
803         ls $DIR || error "Failed to ls $DIR: $?"
804 }
805 run_test 18 "touch .../f ; ls ... =============================="
806
807 test_19a() {
808         touch $DIR/$tfile
809         ls -l $DIR
810         rm $DIR/$tfile
811         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
812 }
813 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
814
815 test_19b() {
816         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
817 }
818 run_test 19b "ls -l .../f19 (should return error) =============="
819
820 test_19c() {
821         [ $RUNAS_ID -eq $UID ] &&
822                 skip_env "RUNAS_ID = UID = $UID -- skipping"
823
824         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
825 }
826 run_test 19c "$RUNAS touch .../f19 (should return error) =="
827
828 test_19d() {
829         cat $DIR/f19 && error || true
830 }
831 run_test 19d "cat .../f19 (should return error) =============="
832
833 test_20() {
834         touch $DIR/$tfile
835         rm $DIR/$tfile
836         touch $DIR/$tfile
837         rm $DIR/$tfile
838         touch $DIR/$tfile
839         rm $DIR/$tfile
840         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
841 }
842 run_test 20 "touch .../f ; ls -l ..."
843
844 test_21() {
845         test_mkdir $DIR/$tdir
846         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
847         ln -s dangle $DIR/$tdir/link
848         echo foo >> $DIR/$tdir/link
849         cat $DIR/$tdir/dangle
850         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
851         $CHECKSTAT -f -t file $DIR/$tdir/link ||
852                 error "$tdir/link not linked to a file"
853 }
854 run_test 21 "write to dangling link"
855
856 test_22() {
857         local wdir=$DIR/$tdir
858         test_mkdir $wdir
859         chown $RUNAS_ID:$RUNAS_GID $wdir
860         (cd $wdir || error "cd $wdir failed";
861                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
862                 $RUNAS tar xf -)
863         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
864         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
865         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
866                 error "checkstat -u failed"
867 }
868 run_test 22 "unpack tar archive as non-root user"
869
870 # was test_23
871 test_23a() {
872         test_mkdir $DIR/$tdir
873         local file=$DIR/$tdir/$tfile
874
875         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
876         openfile -f O_CREAT:O_EXCL $file &&
877                 error "$file recreate succeeded" || true
878 }
879 run_test 23a "O_CREAT|O_EXCL in subdir"
880
881 test_23b() { # bug 18988
882         test_mkdir $DIR/$tdir
883         local file=$DIR/$tdir/$tfile
884
885         rm -f $file
886         echo foo > $file || error "write filed"
887         echo bar >> $file || error "append filed"
888         $CHECKSTAT -s 8 $file || error "wrong size"
889         rm $file
890 }
891 run_test 23b "O_APPEND check"
892
893 # LU-9409, size with O_APPEND and tiny writes
894 test_23c() {
895         local file=$DIR/$tfile
896
897         # single dd
898         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
899         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
900         rm -f $file
901
902         # racing tiny writes
903         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
904         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
905         wait
906         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
907         rm -f $file
908
909         #racing tiny & normal writes
910         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
911         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
912         wait
913         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
914         rm -f $file
915
916         #racing tiny & normal writes 2, ugly numbers
917         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
918         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
919         wait
920         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
921         rm -f $file
922 }
923 run_test 23c "O_APPEND size checks for tiny writes"
924
925 # LU-11069 file offset is correct after appending writes
926 test_23d() {
927         local file=$DIR/$tfile
928         local offset
929
930         echo CentaurHauls > $file
931         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
932         if ((offset != 26)); then
933                 error "wrong offset, expected 26, got '$offset'"
934         fi
935 }
936 run_test 23d "file offset is correct after appending writes"
937
938 # rename sanity
939 test_24a() {
940         echo '-- same directory rename'
941         test_mkdir $DIR/$tdir
942         touch $DIR/$tdir/$tfile.1
943         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
944         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
945 }
946 run_test 24a "rename file to non-existent target"
947
948 test_24b() {
949         test_mkdir $DIR/$tdir
950         touch $DIR/$tdir/$tfile.{1,2}
951         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
952         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
953         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
954 }
955 run_test 24b "rename file to existing target"
956
957 test_24c() {
958         test_mkdir $DIR/$tdir
959         test_mkdir $DIR/$tdir/d$testnum.1
960         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
961         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
962         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
963 }
964 run_test 24c "rename directory to non-existent target"
965
966 test_24d() {
967         test_mkdir -c1 $DIR/$tdir
968         test_mkdir -c1 $DIR/$tdir/d$testnum.1
969         test_mkdir -c1 $DIR/$tdir/d$testnum.2
970         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
971         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
972         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
973 }
974 run_test 24d "rename directory to existing target"
975
976 test_24e() {
977         echo '-- cross directory renames --'
978         test_mkdir $DIR/R5a
979         test_mkdir $DIR/R5b
980         touch $DIR/R5a/f
981         mv $DIR/R5a/f $DIR/R5b/g
982         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
983         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
984 }
985 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
986
987 test_24f() {
988         test_mkdir $DIR/R6a
989         test_mkdir $DIR/R6b
990         touch $DIR/R6a/f $DIR/R6b/g
991         mv $DIR/R6a/f $DIR/R6b/g
992         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
993         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
994 }
995 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
996
997 test_24g() {
998         test_mkdir $DIR/R7a
999         test_mkdir $DIR/R7b
1000         test_mkdir $DIR/R7a/d
1001         mv $DIR/R7a/d $DIR/R7b/e
1002         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
1003         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
1004 }
1005 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
1006
1007 test_24h() {
1008         test_mkdir -c1 $DIR/R8a
1009         test_mkdir -c1 $DIR/R8b
1010         test_mkdir -c1 $DIR/R8a/d
1011         test_mkdir -c1 $DIR/R8b/e
1012         mrename $DIR/R8a/d $DIR/R8b/e
1013         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1014         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1015 }
1016 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1017
1018 test_24i() {
1019         echo "-- rename error cases"
1020         test_mkdir $DIR/R9
1021         test_mkdir $DIR/R9/a
1022         touch $DIR/R9/f
1023         mrename $DIR/R9/f $DIR/R9/a
1024         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1025         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1026         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1027 }
1028 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1029
1030 test_24j() {
1031         test_mkdir $DIR/R10
1032         mrename $DIR/R10/f $DIR/R10/g
1033         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1034         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1035         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1036 }
1037 run_test 24j "source does not exist ============================"
1038
1039 test_24k() {
1040         test_mkdir $DIR/R11a
1041         test_mkdir $DIR/R11a/d
1042         touch $DIR/R11a/f
1043         mv $DIR/R11a/f $DIR/R11a/d
1044         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1045         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1046 }
1047 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1048
1049 # bug 2429 - rename foo foo foo creates invalid file
1050 test_24l() {
1051         f="$DIR/f24l"
1052         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1053 }
1054 run_test 24l "Renaming a file to itself ========================"
1055
1056 test_24m() {
1057         f="$DIR/f24m"
1058         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1059         # on ext3 this does not remove either the source or target files
1060         # though the "expected" operation would be to remove the source
1061         $CHECKSTAT -t file ${f} || error "${f} missing"
1062         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1063 }
1064 run_test 24m "Renaming a file to a hard link to itself ========="
1065
1066 test_24n() {
1067     f="$DIR/f24n"
1068     # this stats the old file after it was renamed, so it should fail
1069     touch ${f}
1070     $CHECKSTAT ${f} || error "${f} missing"
1071     mv ${f} ${f}.rename
1072     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1073     $CHECKSTAT -a ${f} || error "${f} exists"
1074 }
1075 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1076
1077 test_24o() {
1078         test_mkdir $DIR/$tdir
1079         rename_many -s random -v -n 10 $DIR/$tdir
1080 }
1081 run_test 24o "rename of files during htree split"
1082
1083 test_24p() {
1084         test_mkdir $DIR/R12a
1085         test_mkdir $DIR/R12b
1086         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1087         mrename $DIR/R12a $DIR/R12b
1088         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1089         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1090         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1091         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1092 }
1093 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1094
1095 cleanup_multiop_pause() {
1096         trap 0
1097         kill -USR1 $MULTIPID
1098 }
1099
1100 test_24q() {
1101         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1102
1103         test_mkdir $DIR/R13a
1104         test_mkdir $DIR/R13b
1105         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1106         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1107         MULTIPID=$!
1108
1109         trap cleanup_multiop_pause EXIT
1110         mrename $DIR/R13a $DIR/R13b
1111         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1112         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1113         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1114         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1115         cleanup_multiop_pause
1116         wait $MULTIPID || error "multiop close failed"
1117 }
1118 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1119
1120 test_24r() { #bug 3789
1121         test_mkdir $DIR/R14a
1122         test_mkdir $DIR/R14a/b
1123         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1124         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1125         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1126 }
1127 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1128
1129 test_24s() {
1130         test_mkdir $DIR/R15a
1131         test_mkdir $DIR/R15a/b
1132         test_mkdir $DIR/R15a/b/c
1133         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1134         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1135         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1136 }
1137 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1138 test_24t() {
1139         test_mkdir $DIR/R16a
1140         test_mkdir $DIR/R16a/b
1141         test_mkdir $DIR/R16a/b/c
1142         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1143         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1144         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1145 }
1146 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1147
1148 test_24u() { # bug12192
1149         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1150         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1151 }
1152 run_test 24u "create stripe file"
1153
1154 simple_cleanup_common() {
1155         local rc=0
1156         trap 0
1157         [ -z "$DIR" ] || [ -z "$tdir" ] && return 0
1158
1159         local start=$SECONDS
1160         rm -rf $DIR/$tdir
1161         rc=$?
1162         wait_delete_completed
1163         echo "cleanup time $((SECONDS - start))"
1164         return $rc
1165 }
1166
1167 max_pages_per_rpc() {
1168         local mdtname="$(printf "MDT%04x" ${1:-0})"
1169         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1170 }
1171
1172 test_24v() {
1173         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1174
1175         local nrfiles=${COUNT:-100000}
1176         local fname="$DIR/$tdir/$tfile"
1177
1178         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1179         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1180
1181         test_mkdir "$(dirname $fname)"
1182         # assume MDT0000 has the fewest inodes
1183         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1184         local free_inodes=$(($(mdt_free_inodes 0) * stripes))
1185         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1186
1187         trap simple_cleanup_common EXIT
1188
1189         createmany -m "$fname" $nrfiles
1190
1191         cancel_lru_locks mdc
1192         lctl set_param mdc.*.stats clear
1193
1194         # was previously test_24D: LU-6101
1195         # readdir() returns correct number of entries after cursor reload
1196         local num_ls=$(ls $DIR/$tdir | wc -l)
1197         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1198         local num_all=$(ls -a $DIR/$tdir | wc -l)
1199         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1200                 [ $num_all -ne $((nrfiles + 2)) ]; then
1201                         error "Expected $nrfiles files, got $num_ls " \
1202                                 "($num_uniq unique $num_all .&..)"
1203         fi
1204         # LU-5 large readdir
1205         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1206         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1207         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1208         # take into account of overhead in lu_dirpage header and end mark in
1209         # each page, plus one in rpc_num calculation.
1210         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1211         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1212         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1213         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1214         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1215         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1216         echo "readpages: $mds_readpage rpc_max: $rpc_max"
1217         (( $mds_readpage < $rpc_max - 2 || $mds_readpage > $rpc_max + 1)) &&
1218                 error "large readdir doesn't take effect: " \
1219                       "$mds_readpage should be about $rpc_max"
1220
1221         simple_cleanup_common
1222 }
1223 run_test 24v "list large directory (test hash collision, b=17560)"
1224
1225 test_24w() { # bug21506
1226         SZ1=234852
1227         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1228         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1229         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1230         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1231         [[ "$SZ1" -eq "$SZ2" ]] ||
1232                 error "Error reading at the end of the file $tfile"
1233 }
1234 run_test 24w "Reading a file larger than 4Gb"
1235
1236 test_24x() {
1237         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1238         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1239         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1240                 skip "Need MDS version at least 2.7.56"
1241
1242         local MDTIDX=1
1243         local remote_dir=$DIR/$tdir/remote_dir
1244
1245         test_mkdir $DIR/$tdir
1246         $LFS mkdir -i $MDTIDX $remote_dir ||
1247                 error "create remote directory failed"
1248
1249         test_mkdir $DIR/$tdir/src_dir
1250         touch $DIR/$tdir/src_file
1251         test_mkdir $remote_dir/tgt_dir
1252         touch $remote_dir/tgt_file
1253
1254         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1255                 error "rename dir cross MDT failed!"
1256
1257         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1258                 error "rename file cross MDT failed!"
1259
1260         touch $DIR/$tdir/ln_file
1261         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1262                 error "ln file cross MDT failed"
1263
1264         rm -rf $DIR/$tdir || error "Can not delete directories"
1265 }
1266 run_test 24x "cross MDT rename/link"
1267
1268 test_24y() {
1269         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1270         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1271
1272         local remote_dir=$DIR/$tdir/remote_dir
1273         local mdtidx=1
1274
1275         test_mkdir $DIR/$tdir
1276         $LFS mkdir -i $mdtidx $remote_dir ||
1277                 error "create remote directory failed"
1278
1279         test_mkdir $remote_dir/src_dir
1280         touch $remote_dir/src_file
1281         test_mkdir $remote_dir/tgt_dir
1282         touch $remote_dir/tgt_file
1283
1284         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1285                 error "rename subdir in the same remote dir failed!"
1286
1287         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1288                 error "rename files in the same remote dir failed!"
1289
1290         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1291                 error "link files in the same remote dir failed!"
1292
1293         rm -rf $DIR/$tdir || error "Can not delete directories"
1294 }
1295 run_test 24y "rename/link on the same dir should succeed"
1296
1297 test_24z() {
1298         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1299         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1300                 skip "Need MDS version at least 2.12.51"
1301
1302         local index
1303
1304         for index in 0 1; do
1305                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1306                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1307         done
1308
1309         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1310
1311         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1312         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1313
1314         local mdts=$(comma_list $(mdts_nodes))
1315
1316         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1317         stack_trap "do_nodes $mdts $LCTL \
1318                 set_param mdt.*.enable_remote_rename=1" EXIT
1319
1320         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1321
1322         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1323         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1324 }
1325 run_test 24z "cross-MDT rename is done as cp"
1326
1327 test_24A() { # LU-3182
1328         local NFILES=5000
1329
1330         rm -rf $DIR/$tdir
1331         test_mkdir $DIR/$tdir
1332         trap simple_cleanup_common EXIT
1333         createmany -m $DIR/$tdir/$tfile $NFILES
1334         local t=$(ls $DIR/$tdir | wc -l)
1335         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1336         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1337         if [ $t -ne $NFILES ] || [ $u -ne $NFILES ] ||
1338            [ $v -ne $((NFILES + 2)) ] ; then
1339                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1340         fi
1341
1342         simple_cleanup_common || error "Can not delete directories"
1343 }
1344 run_test 24A "readdir() returns correct number of entries."
1345
1346 test_24B() { # LU-4805
1347         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1348
1349         local count
1350
1351         test_mkdir $DIR/$tdir
1352         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1353                 error "create striped dir failed"
1354
1355         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1356         [ $count -eq 2 ] || error "Expected 2, got $count"
1357
1358         touch $DIR/$tdir/striped_dir/a
1359
1360         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1361         [ $count -eq 3 ] || error "Expected 3, got $count"
1362
1363         touch $DIR/$tdir/striped_dir/.f
1364
1365         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1366         [ $count -eq 4 ] || error "Expected 4, got $count"
1367
1368         rm -rf $DIR/$tdir || error "Can not delete directories"
1369 }
1370 run_test 24B "readdir for striped dir return correct number of entries"
1371
1372 test_24C() {
1373         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1374
1375         mkdir $DIR/$tdir
1376         mkdir $DIR/$tdir/d0
1377         mkdir $DIR/$tdir/d1
1378
1379         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1380                 error "create striped dir failed"
1381
1382         cd $DIR/$tdir/d0/striped_dir
1383
1384         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1385         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1386         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1387
1388         [ "$d0_ino" = "$parent_ino" ] ||
1389                 error ".. wrong, expect $d0_ino, get $parent_ino"
1390
1391         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1392                 error "mv striped dir failed"
1393
1394         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1395
1396         [ "$d1_ino" = "$parent_ino" ] ||
1397                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1398 }
1399 run_test 24C "check .. in striped dir"
1400
1401 test_24E() {
1402         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1403         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1404
1405         mkdir -p $DIR/$tdir
1406         mkdir $DIR/$tdir/src_dir
1407         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1408                 error "create remote source failed"
1409
1410         touch $DIR/$tdir/src_dir/src_child/a
1411
1412         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1413                 error "create remote target dir failed"
1414
1415         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1416                 error "create remote target child failed"
1417
1418         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1419                 error "rename dir cross MDT failed!"
1420
1421         find $DIR/$tdir
1422
1423         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1424                 error "src_child still exists after rename"
1425
1426         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1427                 error "missing file(a) after rename"
1428
1429         rm -rf $DIR/$tdir || error "Can not delete directories"
1430 }
1431 run_test 24E "cross MDT rename/link"
1432
1433 test_24F () {
1434         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1435
1436         local repeats=1000
1437         [ "$SLOW" = "no" ] && repeats=100
1438
1439         mkdir -p $DIR/$tdir
1440
1441         echo "$repeats repeats"
1442         for ((i = 0; i < repeats; i++)); do
1443                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1444                 touch $DIR/$tdir/test/a || error "touch fails"
1445                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1446                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1447         done
1448
1449         true
1450 }
1451 run_test 24F "hash order vs readdir (LU-11330)"
1452
1453 test_25a() {
1454         echo '== symlink sanity ============================================='
1455
1456         test_mkdir $DIR/d25
1457         ln -s d25 $DIR/s25
1458         touch $DIR/s25/foo ||
1459                 error "File creation in symlinked directory failed"
1460 }
1461 run_test 25a "create file in symlinked directory ==============="
1462
1463 test_25b() {
1464         [ ! -d $DIR/d25 ] && test_25a
1465         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1466 }
1467 run_test 25b "lookup file in symlinked directory ==============="
1468
1469 test_26a() {
1470         test_mkdir $DIR/d26
1471         test_mkdir $DIR/d26/d26-2
1472         ln -s d26/d26-2 $DIR/s26
1473         touch $DIR/s26/foo || error "File creation failed"
1474 }
1475 run_test 26a "multiple component symlink ======================="
1476
1477 test_26b() {
1478         test_mkdir -p $DIR/$tdir/d26-2
1479         ln -s $tdir/d26-2/foo $DIR/s26-2
1480         touch $DIR/s26-2 || error "File creation failed"
1481 }
1482 run_test 26b "multiple component symlink at end of lookup ======"
1483
1484 test_26c() {
1485         test_mkdir $DIR/d26.2
1486         touch $DIR/d26.2/foo
1487         ln -s d26.2 $DIR/s26.2-1
1488         ln -s s26.2-1 $DIR/s26.2-2
1489         ln -s s26.2-2 $DIR/s26.2-3
1490         chmod 0666 $DIR/s26.2-3/foo
1491 }
1492 run_test 26c "chain of symlinks"
1493
1494 # recursive symlinks (bug 439)
1495 test_26d() {
1496         ln -s d26-3/foo $DIR/d26-3
1497 }
1498 run_test 26d "create multiple component recursive symlink"
1499
1500 test_26e() {
1501         [ ! -h $DIR/d26-3 ] && test_26d
1502         rm $DIR/d26-3
1503 }
1504 run_test 26e "unlink multiple component recursive symlink"
1505
1506 # recursive symlinks (bug 7022)
1507 test_26f() {
1508         test_mkdir $DIR/$tdir
1509         test_mkdir $DIR/$tdir/$tfile
1510         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1511         test_mkdir -p lndir/bar1
1512         test_mkdir $DIR/$tdir/$tfile/$tfile
1513         cd $tfile                || error "cd $tfile failed"
1514         ln -s .. dotdot          || error "ln dotdot failed"
1515         ln -s dotdot/lndir lndir || error "ln lndir failed"
1516         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1517         output=`ls $tfile/$tfile/lndir/bar1`
1518         [ "$output" = bar1 ] && error "unexpected output"
1519         rm -r $tfile             || error "rm $tfile failed"
1520         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1521 }
1522 run_test 26f "rm -r of a directory which has recursive symlink"
1523
1524 test_27a() {
1525         test_mkdir $DIR/$tdir
1526         $LFS getstripe $DIR/$tdir
1527         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1528         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1529         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1530 }
1531 run_test 27a "one stripe file"
1532
1533 test_27b() {
1534         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1535
1536         test_mkdir $DIR/$tdir
1537         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1538         $LFS getstripe -c $DIR/$tdir/$tfile
1539         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1540                 error "two-stripe file doesn't have two stripes"
1541
1542         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1543 }
1544 run_test 27b "create and write to two stripe file"
1545
1546 # 27c family tests specific striping, setstripe -o
1547 test_27ca() {
1548         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1549         test_mkdir -p $DIR/$tdir
1550         local osts="1"
1551
1552         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1553         $LFS getstripe -i $DIR/$tdir/$tfile
1554         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1555                 error "stripe not on specified OST"
1556
1557         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1558 }
1559 run_test 27ca "one stripe on specified OST"
1560
1561 test_27cb() {
1562         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1563         test_mkdir -p $DIR/$tdir
1564         local osts="1,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 27cb "two stripes on specified OSTs"
1578
1579 test_27cc() {
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
1584         test_mkdir -p $DIR/$tdir
1585         local osts="0,0"
1586         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1587         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1588         echo "$getstripe"
1589
1590         # Strip getstripe output to a space separated list of OSTs
1591         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1592                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1593         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1594                 error "stripes not on specified OSTs"
1595
1596         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1597 }
1598 run_test 27cc "two stripes on the same OST"
1599
1600 test_27cd() {
1601         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1602         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1603                 skip "server does not support overstriping"
1604         test_mkdir -p $DIR/$tdir
1605         local osts="0,1,1,0"
1606         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1607         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1608         echo "$getstripe"
1609
1610         # Strip getstripe output to a space separated list of OSTs
1611         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1612                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1613         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1614                 error "stripes not on specified OSTs"
1615
1616         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1617 }
1618 run_test 27cd "four stripes on two OSTs"
1619
1620 test_27ce() {
1621         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1622                 skip_env "too many osts, skipping"
1623         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1624                 skip "server does not support overstriping"
1625         # We do one more stripe than we have OSTs
1626         [ $OSTCOUNT -ge 159 ] || large_xattr_enabled ||
1627                 skip_env "ea_inode feature disabled"
1628
1629         test_mkdir -p $DIR/$tdir
1630         local osts=""
1631         for i in $(seq 0 $OSTCOUNT);
1632         do
1633                 osts=$osts"0"
1634                 if [ $i -ne $OSTCOUNT ]; then
1635                         osts=$osts","
1636                 fi
1637         done
1638         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1639         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1640         echo "$getstripe"
1641
1642         # Strip getstripe output to a space separated list of OSTs
1643         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1644                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1645         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1646                 error "stripes not on specified OSTs"
1647
1648         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1649 }
1650 run_test 27ce "more stripes than OSTs with -o"
1651
1652 test_27cf() {
1653         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1654         local pid=0
1655
1656         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1657         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1658         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1659         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1660                 error "failed to set $osp_proc=0"
1661
1662         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1663         pid=$!
1664         sleep 1
1665         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1666         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1667                 error "failed to set $osp_proc=1"
1668         wait $pid
1669         [[ $pid -ne 0 ]] ||
1670                 error "should return error due to $osp_proc=0"
1671 }
1672 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1673
1674 test_27d() {
1675         test_mkdir $DIR/$tdir
1676         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1677                 error "setstripe failed"
1678         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1679         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1680 }
1681 run_test 27d "create file with default settings"
1682
1683 test_27e() {
1684         # LU-5839 adds check for existed layout before setting it
1685         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1686                 skip "Need MDS version at least 2.7.56"
1687
1688         test_mkdir $DIR/$tdir
1689         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1690         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1691         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1692 }
1693 run_test 27e "setstripe existing file (should return error)"
1694
1695 test_27f() {
1696         test_mkdir $DIR/$tdir
1697         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1698                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1699         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1700                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1701         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1702         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1703 }
1704 run_test 27f "setstripe with bad stripe size (should return error)"
1705
1706 test_27g() {
1707         test_mkdir $DIR/$tdir
1708         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1709         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1710                 error "$DIR/$tdir/$tfile has object"
1711 }
1712 run_test 27g "$LFS getstripe with no objects"
1713
1714 test_27ga() {
1715         test_mkdir $DIR/$tdir
1716         touch $DIR/$tdir/$tfile || error "touch failed"
1717         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1718         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1719         local rc=$?
1720         (( rc == 2 )) || error "getstripe did not return ENOENT"
1721 }
1722 run_test 27ga "$LFS getstripe with missing file (should return error)"
1723
1724 test_27i() {
1725         test_mkdir $DIR/$tdir
1726         touch $DIR/$tdir/$tfile || error "touch failed"
1727         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1728                 error "missing objects"
1729 }
1730 run_test 27i "$LFS getstripe with some objects"
1731
1732 test_27j() {
1733         test_mkdir $DIR/$tdir
1734         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1735                 error "setstripe failed" || true
1736 }
1737 run_test 27j "setstripe with bad stripe offset (should return error)"
1738
1739 test_27k() { # bug 2844
1740         test_mkdir $DIR/$tdir
1741         local file=$DIR/$tdir/$tfile
1742         local ll_max_blksize=$((4 * 1024 * 1024))
1743         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1744         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1745         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1746         dd if=/dev/zero of=$file bs=4k count=1
1747         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1748         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1749 }
1750 run_test 27k "limit i_blksize for broken user apps"
1751
1752 test_27l() {
1753         mcreate $DIR/$tfile || error "creating file"
1754         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1755                 error "setstripe should have failed" || true
1756 }
1757 run_test 27l "check setstripe permissions (should return error)"
1758
1759 test_27m() {
1760         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1761
1762         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1763                 skip_env "multiple clients -- skipping"
1764
1765         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1766                    head -n1)
1767         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1768                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1769         fi
1770         trap simple_cleanup_common EXIT
1771         test_mkdir $DIR/$tdir
1772         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1773         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1774                 error "dd should fill OST0"
1775         i=2
1776         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1777                 i=$((i + 1))
1778                 [ $i -gt 256 ] && break
1779         done
1780         i=$((i + 1))
1781         touch $DIR/$tdir/$tfile.$i
1782         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1783             awk '{print $1}'| grep -w "0") ] &&
1784                 error "OST0 was full but new created file still use it"
1785         i=$((i + 1))
1786         touch $DIR/$tdir/$tfile.$i
1787         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1788             awk '{print $1}'| grep -w "0") ] &&
1789                 error "OST0 was full but new created file still use it"
1790         simple_cleanup_common
1791 }
1792 run_test 27m "create file while OST0 was full"
1793
1794 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1795 # if the OST isn't full anymore.
1796 reset_enospc() {
1797         local ostidx=${1:-""}
1798         local delay
1799         local ready
1800         local get_prealloc
1801
1802         local list=$(comma_list $(osts_nodes))
1803         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1804
1805         do_nodes $list lctl set_param fail_loc=0
1806         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1807         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1808                 awk '{print $1 * 2;exit;}')
1809         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1810                         grep -v \"^0$\""
1811         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1812 }
1813
1814 __exhaust_precreations() {
1815         local OSTIDX=$1
1816         local FAILLOC=$2
1817         local FAILIDX=${3:-$OSTIDX}
1818         local ofacet=ost$((OSTIDX + 1))
1819
1820         test_mkdir -p -c1 $DIR/$tdir
1821         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
1822         local mfacet=mds$((mdtidx + 1))
1823         echo OSTIDX=$OSTIDX MDTIDX=$mdtidx
1824
1825         local OST=$(ostname_from_index $OSTIDX)
1826
1827         # on the mdt's osc
1828         local mdtosc_proc1=$(get_mdtosc_proc_path $mfacet $OST)
1829         local last_id=$(do_facet $mfacet lctl get_param -n \
1830                         osp.$mdtosc_proc1.prealloc_last_id)
1831         local next_id=$(do_facet $mfacet lctl get_param -n \
1832                         osp.$mdtosc_proc1.prealloc_next_id)
1833
1834         local mdtosc_proc2=$(get_mdtosc_proc_path $mfacet)
1835         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1836
1837         test_mkdir -p $DIR/$tdir/${OST}
1838         $LFS setstripe -i $OSTIDX -c 1 $DIR/$tdir/${OST}
1839 #define OBD_FAIL_OST_ENOSPC              0x215
1840         do_facet $ofacet lctl set_param fail_val=$FAILIDX fail_loc=0x215
1841         echo "Creating to objid $last_id on ost $OST..."
1842         createmany -o $DIR/$tdir/${OST}/f $next_id $((last_id - next_id + 2))
1843         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1844         do_facet $ofacet lctl set_param fail_loc=$FAILLOC
1845 }
1846
1847 exhaust_precreations() {
1848         __exhaust_precreations $1 $2 $3
1849         sleep_maxage
1850 }
1851
1852 exhaust_all_precreations() {
1853         local i
1854         for (( i=0; i < OSTCOUNT; i++ )) ; do
1855                 __exhaust_precreations $i $1 -1
1856         done
1857         sleep_maxage
1858 }
1859
1860 test_27n() {
1861         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1862         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1863         remote_mds_nodsh && skip "remote MDS with nodsh"
1864         remote_ost_nodsh && skip "remote OST with nodsh"
1865
1866         reset_enospc
1867         rm -f $DIR/$tdir/$tfile
1868         exhaust_precreations 0 0x80000215
1869         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1870         touch $DIR/$tdir/$tfile || error "touch failed"
1871         $LFS getstripe $DIR/$tdir/$tfile
1872         reset_enospc
1873 }
1874 run_test 27n "create file with some full OSTs"
1875
1876 test_27o() {
1877         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1878         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1879         remote_mds_nodsh && skip "remote MDS with nodsh"
1880         remote_ost_nodsh && skip "remote OST with nodsh"
1881
1882         reset_enospc
1883         rm -f $DIR/$tdir/$tfile
1884         exhaust_all_precreations 0x215
1885
1886         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1887
1888         reset_enospc
1889         rm -rf $DIR/$tdir/*
1890 }
1891 run_test 27o "create file with all full OSTs (should error)"
1892
1893 test_27p() {
1894         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1895         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1896         remote_mds_nodsh && skip "remote MDS with nodsh"
1897         remote_ost_nodsh && skip "remote OST with nodsh"
1898
1899         reset_enospc
1900         rm -f $DIR/$tdir/$tfile
1901         test_mkdir $DIR/$tdir
1902
1903         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1904         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1905         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1906
1907         exhaust_precreations 0 0x80000215
1908         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1909         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1910         $LFS getstripe $DIR/$tdir/$tfile
1911
1912         reset_enospc
1913 }
1914 run_test 27p "append to a truncated file with some full OSTs"
1915
1916 test_27q() {
1917         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1918         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1919         remote_mds_nodsh && skip "remote MDS with nodsh"
1920         remote_ost_nodsh && skip "remote OST with nodsh"
1921
1922         reset_enospc
1923         rm -f $DIR/$tdir/$tfile
1924
1925         test_mkdir $DIR/$tdir
1926         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1927         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1928                 error "truncate $DIR/$tdir/$tfile failed"
1929         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1930
1931         exhaust_all_precreations 0x215
1932
1933         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1934         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1935
1936         reset_enospc
1937 }
1938 run_test 27q "append to truncated file with all OSTs full (should error)"
1939
1940 test_27r() {
1941         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1942         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1943         remote_mds_nodsh && skip "remote MDS with nodsh"
1944         remote_ost_nodsh && skip "remote OST with nodsh"
1945
1946         reset_enospc
1947         rm -f $DIR/$tdir/$tfile
1948         exhaust_precreations 0 0x80000215
1949
1950         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1951
1952         reset_enospc
1953 }
1954 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
1955
1956 test_27s() { # bug 10725
1957         test_mkdir $DIR/$tdir
1958         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
1959         local stripe_count=0
1960         [ $OSTCOUNT -eq 1 ] || stripe_count=2
1961         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
1962                 error "stripe width >= 2^32 succeeded" || true
1963
1964 }
1965 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
1966
1967 test_27t() { # bug 10864
1968         WDIR=$(pwd)
1969         WLFS=$(which lfs)
1970         cd $DIR
1971         touch $tfile
1972         $WLFS getstripe $tfile
1973         cd $WDIR
1974 }
1975 run_test 27t "check that utils parse path correctly"
1976
1977 test_27u() { # bug 4900
1978         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1979         remote_mds_nodsh && skip "remote MDS with nodsh"
1980
1981         local index
1982         local list=$(comma_list $(mdts_nodes))
1983
1984 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
1985         do_nodes $list $LCTL set_param fail_loc=0x139
1986         test_mkdir -p $DIR/$tdir
1987         trap simple_cleanup_common EXIT
1988         createmany -o $DIR/$tdir/t- 1000
1989         do_nodes $list $LCTL set_param fail_loc=0
1990
1991         TLOG=$TMP/$tfile.getstripe
1992         $LFS getstripe $DIR/$tdir > $TLOG
1993         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
1994         unlinkmany $DIR/$tdir/t- 1000
1995         trap 0
1996         [[ $OBJS -gt 0 ]] &&
1997                 error "$OBJS objects created on OST-0. See $TLOG" ||
1998                 rm -f $TLOG
1999 }
2000 run_test 27u "skip object creation on OSC w/o objects"
2001
2002 test_27v() { # bug 4900
2003         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2004         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2005         remote_mds_nodsh && skip "remote MDS with nodsh"
2006         remote_ost_nodsh && skip "remote OST with nodsh"
2007
2008         exhaust_all_precreations 0x215
2009         reset_enospc
2010
2011         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2012
2013         touch $DIR/$tdir/$tfile
2014         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2015         # all except ost1
2016         for (( i=1; i < OSTCOUNT; i++ )); do
2017                 do_facet ost$i lctl set_param fail_loc=0x705
2018         done
2019         local START=`date +%s`
2020         createmany -o $DIR/$tdir/$tfile 32
2021
2022         local FINISH=`date +%s`
2023         local TIMEOUT=`lctl get_param -n timeout`
2024         local PROCESS=$((FINISH - START))
2025         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2026                error "$FINISH - $START >= $TIMEOUT / 2"
2027         sleep $((TIMEOUT / 2 - PROCESS))
2028         reset_enospc
2029 }
2030 run_test 27v "skip object creation on slow OST"
2031
2032 test_27w() { # bug 10997
2033         test_mkdir $DIR/$tdir
2034         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2035         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2036                 error "stripe size $size != 65536" || true
2037         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2038                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2039 }
2040 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2041
2042 test_27wa() {
2043         [[ $OSTCOUNT -lt 2 ]] &&
2044                 skip_env "skipping multiple stripe count/offset test"
2045
2046         test_mkdir $DIR/$tdir
2047         for i in $(seq 1 $OSTCOUNT); do
2048                 offset=$((i - 1))
2049                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2050                         error "setstripe -c $i -i $offset failed"
2051                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2052                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2053                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2054                 [ $index -ne $offset ] &&
2055                         error "stripe offset $index != $offset" || true
2056         done
2057 }
2058 run_test 27wa "check $LFS setstripe -c -i options"
2059
2060 test_27x() {
2061         remote_ost_nodsh && skip "remote OST with nodsh"
2062         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2063         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2064
2065         OFFSET=$(($OSTCOUNT - 1))
2066         OSTIDX=0
2067         local OST=$(ostname_from_index $OSTIDX)
2068
2069         test_mkdir $DIR/$tdir
2070         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2071         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2072         sleep_maxage
2073         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2074         for i in $(seq 0 $OFFSET); do
2075                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2076                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2077                 error "OST0 was degraded but new created file still use it"
2078         done
2079         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2080 }
2081 run_test 27x "create files while OST0 is degraded"
2082
2083 test_27y() {
2084         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2085         remote_mds_nodsh && skip "remote MDS with nodsh"
2086         remote_ost_nodsh && skip "remote OST with nodsh"
2087         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2088
2089         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2090         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2091                 osp.$mdtosc.prealloc_last_id)
2092         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2093                 osp.$mdtosc.prealloc_next_id)
2094         local fcount=$((last_id - next_id))
2095         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2096         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2097
2098         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2099                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2100         local OST_DEACTIVE_IDX=-1
2101         local OSC
2102         local OSTIDX
2103         local OST
2104
2105         for OSC in $MDS_OSCS; do
2106                 OST=$(osc_to_ost $OSC)
2107                 OSTIDX=$(index_from_ostuuid $OST)
2108                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2109                         OST_DEACTIVE_IDX=$OSTIDX
2110                 fi
2111                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2112                         echo $OSC "is Deactivated:"
2113                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2114                 fi
2115         done
2116
2117         OSTIDX=$(index_from_ostuuid $OST)
2118         test_mkdir $DIR/$tdir
2119         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2120
2121         for OSC in $MDS_OSCS; do
2122                 OST=$(osc_to_ost $OSC)
2123                 OSTIDX=$(index_from_ostuuid $OST)
2124                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2125                         echo $OST "is degraded:"
2126                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2127                                                 obdfilter.$OST.degraded=1
2128                 fi
2129         done
2130
2131         sleep_maxage
2132         createmany -o $DIR/$tdir/$tfile $fcount
2133
2134         for OSC in $MDS_OSCS; do
2135                 OST=$(osc_to_ost $OSC)
2136                 OSTIDX=$(index_from_ostuuid $OST)
2137                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2138                         echo $OST "is recovered from degraded:"
2139                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2140                                                 obdfilter.$OST.degraded=0
2141                 else
2142                         do_facet $SINGLEMDS lctl --device %$OSC activate
2143                 fi
2144         done
2145
2146         # all osp devices get activated, hence -1 stripe count restored
2147         local stripe_count=0
2148
2149         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2150         # devices get activated.
2151         sleep_maxage
2152         $LFS setstripe -c -1 $DIR/$tfile
2153         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2154         rm -f $DIR/$tfile
2155         [ $stripe_count -ne $OSTCOUNT ] &&
2156                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2157         return 0
2158 }
2159 run_test 27y "create files while OST0 is degraded and the rest inactive"
2160
2161 check_seq_oid()
2162 {
2163         log "check file $1"
2164
2165         lmm_count=$($LFS getstripe -c $1)
2166         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2167         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2168
2169         local old_ifs="$IFS"
2170         IFS=$'[:]'
2171         fid=($($LFS path2fid $1))
2172         IFS="$old_ifs"
2173
2174         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2175         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2176
2177         # compare lmm_seq and lu_fid->f_seq
2178         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2179         # compare lmm_object_id and lu_fid->oid
2180         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2181
2182         # check the trusted.fid attribute of the OST objects of the file
2183         local have_obdidx=false
2184         local stripe_nr=0
2185         $LFS getstripe $1 | while read obdidx oid hex seq; do
2186                 # skip lines up to and including "obdidx"
2187                 [ -z "$obdidx" ] && break
2188                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2189                 $have_obdidx || continue
2190
2191                 local ost=$((obdidx + 1))
2192                 local dev=$(ostdevname $ost)
2193                 local oid_hex
2194
2195                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2196
2197                 seq=$(echo $seq | sed -e "s/^0x//g")
2198                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2199                         oid_hex=$(echo $oid)
2200                 else
2201                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2202                 fi
2203                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2204
2205                 local ff=""
2206                 #
2207                 # Don't unmount/remount the OSTs if we don't need to do that.
2208                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2209                 # update too, until that use mount/ll_decode_filter_fid/mount.
2210                 # Re-enable when debugfs will understand new filter_fid.
2211                 #
2212                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2213                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2214                                 $dev 2>/dev/null" | grep "parent=")
2215                 fi
2216                 if [ -z "$ff" ]; then
2217                         stop ost$ost
2218                         mount_fstype ost$ost
2219                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2220                                 $(facet_mntpt ost$ost)/$obj_file)
2221                         unmount_fstype ost$ost
2222                         start ost$ost $dev $OST_MOUNT_OPTS
2223                         clients_up
2224                 fi
2225
2226                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2227
2228                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2229
2230                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2231                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2232                 #
2233                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2234                 #       stripe_size=1048576 component_id=1 component_start=0 \
2235                 #       component_end=33554432
2236                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2237                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2238                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2239                 local ff_pstripe
2240                 if grep -q 'stripe=' <<<$ff; then
2241                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2242                 else
2243                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2244                         # into f_ver in this case.  See comment on ff_parent.
2245                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2246                 fi
2247
2248                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2249                 [ $ff_pseq = $lmm_seq ] ||
2250                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2251                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2252                 [ $ff_poid = $lmm_oid ] ||
2253                         error "FF parent OID $ff_poid != $lmm_oid"
2254                 (($ff_pstripe == $stripe_nr)) ||
2255                         error "FF stripe $ff_pstripe != $stripe_nr"
2256
2257                 stripe_nr=$((stripe_nr + 1))
2258                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2259                         continue
2260                 if grep -q 'stripe_count=' <<<$ff; then
2261                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2262                                             -e 's/ .*//' <<<$ff)
2263                         [ $lmm_count = $ff_scnt ] ||
2264                                 error "FF stripe count $lmm_count != $ff_scnt"
2265                 fi
2266         done
2267 }
2268
2269 test_27z() {
2270         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2271         remote_ost_nodsh && skip "remote OST with nodsh"
2272
2273         test_mkdir $DIR/$tdir
2274         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2275                 { error "setstripe -c -1 failed"; return 1; }
2276         # We need to send a write to every object to get parent FID info set.
2277         # This _should_ also work for setattr, but does not currently.
2278         # touch $DIR/$tdir/$tfile-1 ||
2279         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2280                 { error "dd $tfile-1 failed"; return 2; }
2281         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2282                 { error "setstripe -c -1 failed"; return 3; }
2283         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2284                 { error "dd $tfile-2 failed"; return 4; }
2285
2286         # make sure write RPCs have been sent to OSTs
2287         sync; sleep 5; sync
2288
2289         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2290         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2291 }
2292 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2293
2294 test_27A() { # b=19102
2295         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2296
2297         save_layout_restore_at_exit $MOUNT
2298         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2299         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2300                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2301         local default_size=$($LFS getstripe -S $MOUNT)
2302         local default_offset=$($LFS getstripe -i $MOUNT)
2303         local dsize=$(do_facet $SINGLEMDS \
2304                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2305         [ $default_size -eq $dsize ] ||
2306                 error "stripe size $default_size != $dsize"
2307         [ $default_offset -eq -1 ] ||
2308                 error "stripe offset $default_offset != -1"
2309 }
2310 run_test 27A "check filesystem-wide default LOV EA values"
2311
2312 test_27B() { # LU-2523
2313         test_mkdir $DIR/$tdir
2314         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2315         touch $DIR/$tdir/f0
2316         # open f1 with O_LOV_DELAY_CREATE
2317         # rename f0 onto f1
2318         # call setstripe ioctl on open file descriptor for f1
2319         # close
2320         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2321                 $DIR/$tdir/f0
2322
2323         rm -f $DIR/$tdir/f1
2324         # open f1 with O_LOV_DELAY_CREATE
2325         # unlink f1
2326         # call setstripe ioctl on open file descriptor for f1
2327         # close
2328         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2329
2330         # Allow multiop to fail in imitation of NFS's busted semantics.
2331         true
2332 }
2333 run_test 27B "call setstripe on open unlinked file/rename victim"
2334
2335 # 27C family tests full striping and overstriping
2336 test_27Ca() { #LU-2871
2337         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2338
2339         declare -a ost_idx
2340         local index
2341         local found
2342         local i
2343         local j
2344
2345         test_mkdir $DIR/$tdir
2346         cd $DIR/$tdir
2347         for i in $(seq 0 $((OSTCOUNT - 1))); do
2348                 # set stripe across all OSTs starting from OST$i
2349                 $LFS setstripe -i $i -c -1 $tfile$i
2350                 # get striping information
2351                 ost_idx=($($LFS getstripe $tfile$i |
2352                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2353                 echo ${ost_idx[@]}
2354
2355                 # check the layout
2356                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2357                         error "${#ost_idx[@]} != $OSTCOUNT"
2358
2359                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2360                         found=0
2361                         for j in $(echo ${ost_idx[@]}); do
2362                                 if [ $index -eq $j ]; then
2363                                         found=1
2364                                         break
2365                                 fi
2366                         done
2367                         [ $found = 1 ] ||
2368                                 error "Can not find $index in ${ost_idx[@]}"
2369                 done
2370         done
2371 }
2372 run_test 27Ca "check full striping across all OSTs"
2373
2374 test_27Cb() {
2375         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2376                 skip "server does not support overstriping"
2377         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2378                 skip_env "too many osts, skipping"
2379
2380         test_mkdir -p $DIR/$tdir
2381         local setcount=$(($OSTCOUNT * 2))
2382         [ $setcount -ge 160 ] || large_xattr_enabled ||
2383                 skip_env "ea_inode feature disabled"
2384
2385         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2386                 error "setstripe failed"
2387
2388         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2389         [ $count -eq $setcount ] ||
2390                 error "stripe count $count, should be $setcount"
2391
2392         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2393                 error "overstriped should be set in pattern"
2394
2395         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2396                 error "dd failed"
2397 }
2398 run_test 27Cb "more stripes than OSTs with -C"
2399
2400 test_27Cc() {
2401         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2402                 skip "server does not support overstriping"
2403         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2404
2405         test_mkdir -p $DIR/$tdir
2406         local setcount=$(($OSTCOUNT - 1))
2407
2408         [ $setcount -ge 160 ] || large_xattr_enabled ||
2409                 skip_env "ea_inode feature disabled"
2410
2411         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2412                 error "setstripe failed"
2413
2414         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2415         [ $count -eq $setcount ] ||
2416                 error "stripe count $count, should be $setcount"
2417
2418         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2419                 error "overstriped should not be set in pattern"
2420
2421         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2422                 error "dd failed"
2423 }
2424 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2425
2426 test_27Cd() {
2427         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2428                 skip "server does not support overstriping"
2429         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2430         large_xattr_enabled || skip_env "ea_inode feature disabled"
2431
2432         test_mkdir -p $DIR/$tdir
2433         local setcount=$LOV_MAX_STRIPE_COUNT
2434
2435         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2436                 error "setstripe failed"
2437
2438         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2439         [ $count -eq $setcount ] ||
2440                 error "stripe count $count, should be $setcount"
2441
2442         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2443                 error "overstriped should be set in pattern"
2444
2445         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2446                 error "dd failed"
2447
2448         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2449 }
2450 run_test 27Cd "test maximum stripe count"
2451
2452 test_27Ce() {
2453         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2454                 skip "server does not support overstriping"
2455         test_mkdir -p $DIR/$tdir
2456
2457         pool_add $TESTNAME || error "Pool creation failed"
2458         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2459
2460         local setcount=8
2461
2462         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2463                 error "setstripe failed"
2464
2465         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2466         [ $count -eq $setcount ] ||
2467                 error "stripe count $count, should be $setcount"
2468
2469         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2470                 error "overstriped should be set in pattern"
2471
2472         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2473                 error "dd failed"
2474
2475         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2476 }
2477 run_test 27Ce "test pool with overstriping"
2478
2479 test_27Cf() {
2480         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2481                 skip "server does not support overstriping"
2482         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2483                 skip_env "too many osts, skipping"
2484
2485         test_mkdir -p $DIR/$tdir
2486
2487         local setcount=$(($OSTCOUNT * 2))
2488         [ $setcount -ge 160 ] || large_xattr_enabled ||
2489                 skip_env "ea_inode feature disabled"
2490
2491         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2492                 error "setstripe failed"
2493
2494         echo 1 > $DIR/$tdir/$tfile
2495
2496         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2497         [ $count -eq $setcount ] ||
2498                 error "stripe count $count, should be $setcount"
2499
2500         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2501                 error "overstriped should be set in pattern"
2502
2503         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2504                 error "dd failed"
2505
2506         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2507 }
2508 run_test 27Cf "test default inheritance with overstriping"
2509
2510 test_27D() {
2511         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2512         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2513         remote_mds_nodsh && skip "remote MDS with nodsh"
2514
2515         local POOL=${POOL:-testpool}
2516         local first_ost=0
2517         local last_ost=$(($OSTCOUNT - 1))
2518         local ost_step=1
2519         local ost_list=$(seq $first_ost $ost_step $last_ost)
2520         local ost_range="$first_ost $last_ost $ost_step"
2521
2522         test_mkdir $DIR/$tdir
2523         pool_add $POOL || error "pool_add failed"
2524         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2525
2526         local skip27D
2527         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2528                 skip27D+="-s 29"
2529         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2530                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2531                         skip27D+=" -s 30,31"
2532         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2533           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2534                 skip27D+=" -s 32,33"
2535         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2536                 skip27D+=" -s 34"
2537         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2538                 error "llapi_layout_test failed"
2539
2540         destroy_test_pools || error "destroy test pools failed"
2541 }
2542 run_test 27D "validate llapi_layout API"
2543
2544 # Verify that default_easize is increased from its initial value after
2545 # accessing a widely striped file.
2546 test_27E() {
2547         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2548         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2549                 skip "client does not have LU-3338 fix"
2550
2551         # 72 bytes is the minimum space required to store striping
2552         # information for a file striped across one OST:
2553         # (sizeof(struct lov_user_md_v3) +
2554         #  sizeof(struct lov_user_ost_data_v1))
2555         local min_easize=72
2556         $LCTL set_param -n llite.*.default_easize $min_easize ||
2557                 error "lctl set_param failed"
2558         local easize=$($LCTL get_param -n llite.*.default_easize)
2559
2560         [ $easize -eq $min_easize ] ||
2561                 error "failed to set default_easize"
2562
2563         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2564                 error "setstripe failed"
2565         # In order to ensure stat() call actually talks to MDS we need to
2566         # do something drastic to this file to shake off all lock, e.g.
2567         # rename it (kills lookup lock forcing cache cleaning)
2568         mv $DIR/$tfile $DIR/${tfile}-1
2569         ls -l $DIR/${tfile}-1
2570         rm $DIR/${tfile}-1
2571
2572         easize=$($LCTL get_param -n llite.*.default_easize)
2573
2574         [ $easize -gt $min_easize ] ||
2575                 error "default_easize not updated"
2576 }
2577 run_test 27E "check that default extended attribute size properly increases"
2578
2579 test_27F() { # LU-5346/LU-7975
2580         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2581         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2582         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2583                 skip "Need MDS version at least 2.8.51"
2584         remote_ost_nodsh && skip "remote OST with nodsh"
2585
2586         test_mkdir $DIR/$tdir
2587         rm -f $DIR/$tdir/f0
2588         $LFS setstripe -c 2 $DIR/$tdir
2589
2590         # stop all OSTs to reproduce situation for LU-7975 ticket
2591         for num in $(seq $OSTCOUNT); do
2592                 stop ost$num
2593         done
2594
2595         # open/create f0 with O_LOV_DELAY_CREATE
2596         # truncate f0 to a non-0 size
2597         # close
2598         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2599
2600         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2601         # open/write it again to force delayed layout creation
2602         cat /etc/hosts > $DIR/$tdir/f0 &
2603         catpid=$!
2604
2605         # restart OSTs
2606         for num in $(seq $OSTCOUNT); do
2607                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2608                         error "ost$num failed to start"
2609         done
2610
2611         wait $catpid || error "cat failed"
2612
2613         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2614         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2615                 error "wrong stripecount"
2616
2617 }
2618 run_test 27F "Client resend delayed layout creation with non-zero size"
2619
2620 test_27G() { #LU-10629
2621         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2622                 skip "Need MDS version at least 2.11.51"
2623         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2624         remote_mds_nodsh && skip "remote MDS with nodsh"
2625         local POOL=${POOL:-testpool}
2626         local ostrange="0 0 1"
2627
2628         test_mkdir $DIR/$tdir
2629         touch $DIR/$tdir/$tfile.nopool
2630         pool_add $POOL || error "pool_add failed"
2631         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2632         $LFS setstripe -p $POOL $DIR/$tdir
2633
2634         local pool=$($LFS getstripe -p $DIR/$tdir)
2635
2636         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2637         touch $DIR/$tdir/$tfile.default
2638         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2639         $LFS find $DIR/$tdir -type f --pool $POOL
2640         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2641         [[ "$found" == "2" ]] ||
2642                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2643
2644         $LFS setstripe -d $DIR/$tdir
2645
2646         pool=$($LFS getstripe -p -d $DIR/$tdir)
2647
2648         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2649 }
2650 run_test 27G "Clear OST pool from stripe"
2651
2652 test_27H() {
2653         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2654                 skip "Need MDS version newer than 2.11.54"
2655         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2656         test_mkdir $DIR/$tdir
2657         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2658         touch $DIR/$tdir/$tfile
2659         $LFS getstripe -c $DIR/$tdir/$tfile
2660         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2661                 error "two-stripe file doesn't have two stripes"
2662
2663         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2664         $LFS getstripe -y $DIR/$tdir/$tfile
2665         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2666              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2667                 error "expected l_ost_idx: [02]$ not matched"
2668
2669         # make sure ost list has been cleared
2670         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2671         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2672                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2673         touch $DIR/$tdir/f3
2674         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2675 }
2676 run_test 27H "Set specific OSTs stripe"
2677
2678 test_27I() {
2679         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2680         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2681         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2682                 skip "Need MDS version newer than 2.12.52"
2683         local pool=$TESTNAME
2684         local ostrange="1 1 1"
2685
2686         save_layout_restore_at_exit $MOUNT
2687         $LFS setstripe -c 2 -i 0 $MOUNT
2688         pool_add $pool || error "pool_add failed"
2689         pool_add_targets $pool $ostrange || "pool_add_targets failed"
2690         test_mkdir $DIR/$tdir
2691         $LFS setstripe -p $pool $DIR/$tdir
2692         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2693         $LFS getstripe $DIR/$tdir/$tfile
2694 }
2695 run_test 27I "check that root dir striping does not break parent dir one"
2696
2697 test_27J() {
2698         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2699                 skip "Need MDS version newer than 2.12.51"
2700
2701         test_mkdir $DIR/$tdir
2702         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2703         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2704
2705         # create foreign file (raw way)
2706         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2707                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2708
2709         # verify foreign file (raw way)
2710         parse_foreign_file -f $DIR/$tdir/$tfile |
2711                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2712                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2713         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2714                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2715         parse_foreign_file -f $DIR/$tdir/$tfile |
2716                 grep "lov_foreign_size: 73" ||
2717                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2718         parse_foreign_file -f $DIR/$tdir/$tfile |
2719                 grep "lov_foreign_type: 1" ||
2720                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2721         parse_foreign_file -f $DIR/$tdir/$tfile |
2722                 grep "lov_foreign_flags: 0x0000DA08" ||
2723                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2724         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2725                 grep "lov_foreign_value: 0x" |
2726                 sed -e 's/lov_foreign_value: 0x//')
2727         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2728         [[ $lov = ${lov2// /} ]] ||
2729                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2730
2731         # create foreign file (lfs + API)
2732         $LFS setstripe --foreign=daos --flags 0xda08 \
2733                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2734                 error "$DIR/$tdir/${tfile}2: create failed"
2735
2736         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2737                 grep "lfm_magic:.*0x0BD70BD0" ||
2738                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2739         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2740         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2741                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2742         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*daos" ||
2743                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2744         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2745                 grep "lfm_flags:.*0x0000DA08" ||
2746                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2747         $LFS getstripe $DIR/$tdir/${tfile}2 |
2748                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2749                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2750
2751         # modify striping should fail
2752         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2753                 error "$DIR/$tdir/$tfile: setstripe should fail"
2754         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2755                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2756
2757         # R/W should fail
2758         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2759         cat $DIR/$tdir/${tfile}2 &&
2760                 error "$DIR/$tdir/${tfile}2: read should fail"
2761         cat /etc/passwd > $DIR/$tdir/$tfile &&
2762                 error "$DIR/$tdir/$tfile: write should fail"
2763         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2764                 error "$DIR/$tdir/${tfile}2: write should fail"
2765
2766         # chmod should work
2767         chmod 222 $DIR/$tdir/$tfile ||
2768                 error "$DIR/$tdir/$tfile: chmod failed"
2769         chmod 222 $DIR/$tdir/${tfile}2 ||
2770                 error "$DIR/$tdir/${tfile}2: chmod failed"
2771
2772         # chown should work
2773         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2774                 error "$DIR/$tdir/$tfile: chown failed"
2775         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2776                 error "$DIR/$tdir/${tfile}2: chown failed"
2777
2778         # rename should work
2779         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2780                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2781         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2782                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2783
2784         #remove foreign file
2785         rm $DIR/$tdir/${tfile}.new ||
2786                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2787         rm $DIR/$tdir/${tfile}2.new ||
2788                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2789 }
2790 run_test 27J "basic ops on file with foreign LOV"
2791
2792 test_27K() {
2793         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2794                 skip "Need MDS version newer than 2.12.49"
2795
2796         test_mkdir $DIR/$tdir
2797         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2798         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2799
2800         # create foreign dir (raw way)
2801         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2802                 error "create_foreign_dir FAILED"
2803
2804         # verify foreign dir (raw way)
2805         parse_foreign_dir -d $DIR/$tdir/$tdir |
2806                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2807                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2808         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2809                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2810         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2811                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2812         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_flags: 0$" ||
2813                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2814         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2815                 grep "lmv_foreign_value: 0x" |
2816                 sed 's/lmv_foreign_value: 0x//')
2817         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2818                 sed 's/ //g')
2819         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2820
2821         # create foreign dir (lfs + API)
2822         $LFS mkdir --foreign=daos --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2823                 $DIR/$tdir/${tdir}2 ||
2824                 error "$DIR/$tdir/${tdir}2: create failed"
2825
2826         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2827                 grep "lfm_magic:.*0x0CD50CD0" ||
2828                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2829         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2830         # - sizeof(lfm_type) - sizeof(lfm_flags)
2831         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2832                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2833         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*daos" ||
2834                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2835         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2836                 grep "lfm_flags:.*0x0000DA05" ||
2837                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2838         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2839                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2840                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2841
2842         # file create in dir should fail
2843         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
2844         touch $DIR/$tdir/${tdir}2/$tfile &&
2845                 "$DIR/${tdir}2: file create should fail"
2846
2847         # chmod should work
2848         chmod 777 $DIR/$tdir/$tdir ||
2849                 error "$DIR/$tdir: chmod failed"
2850         chmod 777 $DIR/$tdir/${tdir}2 ||
2851                 error "$DIR/${tdir}2: chmod failed"
2852
2853         # chown should work
2854         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2855                 error "$DIR/$tdir: chown failed"
2856         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2857                 error "$DIR/${tdir}2: chown failed"
2858
2859         # rename should work
2860         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2861                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2862         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2863                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2864
2865         #remove foreign dir
2866         rmdir $DIR/$tdir/${tdir}.new ||
2867                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2868         rmdir $DIR/$tdir/${tdir}2.new ||
2869                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2870 }
2871 run_test 27K "basic ops on dir with foreign LMV"
2872
2873 test_27L() {
2874         remote_mds_nodsh && skip "remote MDS with nodsh"
2875
2876         local POOL=${POOL:-$TESTNAME}
2877
2878         pool_add $POOL || error "pool_add failed"
2879
2880         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2881                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2882                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2883 }
2884 run_test 27L "lfs pool_list gives correct pool name"
2885
2886 test_27M() {
2887         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2888                 skip "Need MDS version >= than 2.12.57"
2889         remote_mds_nodsh && skip "remote MDS with nodsh"
2890         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2891
2892         test_mkdir $DIR/$tdir
2893
2894         # Set default striping on directory
2895         $LFS setstripe -C 4 $DIR/$tdir
2896
2897         echo 1 > $DIR/$tdir/${tfile}.1
2898         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2899         local setcount=4
2900         [ $count -eq $setcount ] ||
2901                 error "(1) stripe count $count, should be $setcount"
2902
2903         # Capture existing append_stripe_count setting for restore
2904         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2905         local mdts=$(comma_list $(mdts_nodes))
2906         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$orig_count" EXIT
2907
2908         local appendcount=$orig_count
2909         echo 1 >> $DIR/$tdir/${tfile}.2_append
2910         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
2911         [ $count -eq $appendcount ] ||
2912                 error "(2)stripe count $count, should be $appendcount for append"
2913
2914         # Disable O_APPEND striping, verify it works
2915         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
2916
2917         # Should now get the default striping, which is 4
2918         setcount=4
2919         echo 1 >> $DIR/$tdir/${tfile}.3_append
2920         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
2921         [ $count -eq $setcount ] ||
2922                 error "(3) stripe count $count, should be $setcount"
2923
2924         # Try changing the stripe count for append files
2925         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
2926
2927         # Append striping is now 2 (directory default is still 4)
2928         appendcount=2
2929         echo 1 >> $DIR/$tdir/${tfile}.4_append
2930         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
2931         [ $count -eq $appendcount ] ||
2932                 error "(4) stripe count $count, should be $appendcount for append"
2933
2934         # Test append stripe count of -1
2935         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
2936         appendcount=$OSTCOUNT
2937         echo 1 >> $DIR/$tdir/${tfile}.5
2938         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
2939         [ $count -eq $appendcount ] ||
2940                 error "(5) stripe count $count, should be $appendcount for append"
2941
2942         # Set append striping back to default of 1
2943         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
2944
2945         # Try a new default striping, PFL + DOM
2946         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
2947
2948         # Create normal DOM file, DOM returns stripe count == 0
2949         setcount=0
2950         touch $DIR/$tdir/${tfile}.6
2951         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
2952         [ $count -eq $setcount ] ||
2953                 error "(6) stripe count $count, should be $setcount"
2954
2955         # Show
2956         appendcount=1
2957         echo 1 >> $DIR/$tdir/${tfile}.7_append
2958         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
2959         [ $count -eq $appendcount ] ||
2960                 error "(7) stripe count $count, should be $appendcount for append"
2961
2962         # Clean up DOM layout
2963         $LFS setstripe -d $DIR/$tdir
2964
2965         # Now test that append striping works when layout is from root
2966         $LFS setstripe -c 2 $MOUNT
2967         # Make a special directory for this
2968         mkdir $DIR/${tdir}/${tdir}.2
2969         stack_trap "$LFS setstripe -d $MOUNT" EXIT
2970
2971         # Verify for normal file
2972         setcount=2
2973         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
2974         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
2975         [ $count -eq $setcount ] ||
2976                 error "(8) stripe count $count, should be $setcount"
2977
2978         appendcount=1
2979         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
2980         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
2981         [ $count -eq $appendcount ] ||
2982                 error "(9) stripe count $count, should be $appendcount for append"
2983
2984         # Now test O_APPEND striping with pools
2985         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
2986         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'" EXIT
2987
2988         # Create the pool
2989         pool_add $TESTNAME || error "pool creation failed"
2990         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
2991
2992         echo 1 >> $DIR/$tdir/${tfile}.10_append
2993
2994         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
2995         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
2996
2997         # Check that count is still correct
2998         appendcount=1
2999         echo 1 >> $DIR/$tdir/${tfile}.11_append
3000         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3001         [ $count -eq $appendcount ] ||
3002                 error "(11) stripe count $count, should be $appendcount for append"
3003
3004         # Disable O_APPEND stripe count, verify pool works separately
3005         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3006
3007         echo 1 >> $DIR/$tdir/${tfile}.12_append
3008
3009         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3010         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3011
3012         # Remove pool setting, verify it's not applied
3013         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3014
3015         echo 1 >> $DIR/$tdir/${tfile}.13_append
3016
3017         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3018         [ "$pool" = "" ] || error "(13) pool found: $pool"
3019 }
3020 run_test 27M "test O_APPEND striping"
3021
3022 test_27N() {
3023         combined_mgs_mds && skip "needs separate MGS/MDT"
3024
3025         pool_add $TESTNAME || error "pool_add failed"
3026         do_facet mgs "$LCTL pool_list $FSNAME" |
3027                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3028                 error "lctl pool_list on MGS failed"
3029 }
3030 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3031
3032 # createtest also checks that device nodes are created and
3033 # then visible correctly (#2091)
3034 test_28() { # bug 2091
3035         test_mkdir $DIR/d28
3036         $CREATETEST $DIR/d28/ct || error "createtest failed"
3037 }
3038 run_test 28 "create/mknod/mkdir with bad file types ============"
3039
3040 test_29() {
3041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3042
3043         sync; sleep 1; sync # flush out any dirty pages from previous tests
3044         cancel_lru_locks
3045         test_mkdir $DIR/d29
3046         touch $DIR/d29/foo
3047         log 'first d29'
3048         ls -l $DIR/d29
3049
3050         declare -i LOCKCOUNTORIG=0
3051         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3052                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3053         done
3054         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3055
3056         declare -i LOCKUNUSEDCOUNTORIG=0
3057         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3058                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3059         done
3060
3061         log 'second d29'
3062         ls -l $DIR/d29
3063         log 'done'
3064
3065         declare -i LOCKCOUNTCURRENT=0
3066         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3067                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3068         done
3069
3070         declare -i LOCKUNUSEDCOUNTCURRENT=0
3071         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3072                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3073         done
3074
3075         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3076                 $LCTL set_param -n ldlm.dump_namespaces ""
3077                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3078                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3079                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3080                 return 2
3081         fi
3082         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3083                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3084                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3085                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3086                 return 3
3087         fi
3088 }
3089 run_test 29 "IT_GETATTR regression  ============================"
3090
3091 test_30a() { # was test_30
3092         cp $(which ls) $DIR || cp /bin/ls $DIR
3093         $DIR/ls / || error "Can't execute binary from lustre"
3094         rm $DIR/ls
3095 }
3096 run_test 30a "execute binary from Lustre (execve) =============="
3097
3098 test_30b() {
3099         cp `which ls` $DIR || cp /bin/ls $DIR
3100         chmod go+rx $DIR/ls
3101         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3102         rm $DIR/ls
3103 }
3104 run_test 30b "execute binary from Lustre as non-root ==========="
3105
3106 test_30c() { # b=22376
3107         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3108
3109         cp $(which ls) $DIR || cp /bin/ls $DIR
3110         chmod a-rw $DIR/ls
3111         cancel_lru_locks mdc
3112         cancel_lru_locks osc
3113         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3114         rm -f $DIR/ls
3115 }
3116 run_test 30c "execute binary from Lustre without read perms ===="
3117
3118 test_30d() {
3119         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3120
3121         for i in {1..10}; do
3122                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3123                 local PID=$!
3124                 sleep 1
3125                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3126                 wait $PID || error "executing dd from Lustre failed"
3127                 rm -f $DIR/$tfile
3128         done
3129
3130         rm -f $DIR/dd
3131 }
3132 run_test 30d "execute binary from Lustre while clear locks"
3133
3134 test_31a() {
3135         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3136         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3137 }
3138 run_test 31a "open-unlink file =================================="
3139
3140 test_31b() {
3141         touch $DIR/f31 || error "touch $DIR/f31 failed"
3142         ln $DIR/f31 $DIR/f31b || error "ln failed"
3143         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3144         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3145 }
3146 run_test 31b "unlink file with multiple links while open ======="
3147
3148 test_31c() {
3149         touch $DIR/f31 || error "touch $DIR/f31 failed"
3150         ln $DIR/f31 $DIR/f31c || error "ln failed"
3151         multiop_bg_pause $DIR/f31 O_uc ||
3152                 error "multiop_bg_pause for $DIR/f31 failed"
3153         MULTIPID=$!
3154         $MULTIOP $DIR/f31c Ouc
3155         kill -USR1 $MULTIPID
3156         wait $MULTIPID
3157 }
3158 run_test 31c "open-unlink file with multiple links ============="
3159
3160 test_31d() {
3161         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3162         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3163 }
3164 run_test 31d "remove of open directory ========================="
3165
3166 test_31e() { # bug 2904
3167         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3168 }
3169 run_test 31e "remove of open non-empty directory ==============="
3170
3171 test_31f() { # bug 4554
3172         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3173
3174         set -vx
3175         test_mkdir $DIR/d31f
3176         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3177         cp /etc/hosts $DIR/d31f
3178         ls -l $DIR/d31f
3179         $LFS getstripe $DIR/d31f/hosts
3180         multiop_bg_pause $DIR/d31f D_c || return 1
3181         MULTIPID=$!
3182
3183         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3184         test_mkdir $DIR/d31f
3185         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3186         cp /etc/hosts $DIR/d31f
3187         ls -l $DIR/d31f
3188         $LFS getstripe $DIR/d31f/hosts
3189         multiop_bg_pause $DIR/d31f D_c || return 1
3190         MULTIPID2=$!
3191
3192         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3193         wait $MULTIPID || error "first opendir $MULTIPID failed"
3194
3195         sleep 6
3196
3197         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3198         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3199         set +vx
3200 }
3201 run_test 31f "remove of open directory with open-unlink file ==="
3202
3203 test_31g() {
3204         echo "-- cross directory link --"
3205         test_mkdir -c1 $DIR/${tdir}ga
3206         test_mkdir -c1 $DIR/${tdir}gb
3207         touch $DIR/${tdir}ga/f
3208         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3209         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3210         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3211         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3212         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3213 }
3214 run_test 31g "cross directory link==============="
3215
3216 test_31h() {
3217         echo "-- cross directory link --"
3218         test_mkdir -c1 $DIR/${tdir}
3219         test_mkdir -c1 $DIR/${tdir}/dir
3220         touch $DIR/${tdir}/f
3221         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3222         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3223         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3224         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3225         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3226 }
3227 run_test 31h "cross directory link under child==============="
3228
3229 test_31i() {
3230         echo "-- cross directory link --"
3231         test_mkdir -c1 $DIR/$tdir
3232         test_mkdir -c1 $DIR/$tdir/dir
3233         touch $DIR/$tdir/dir/f
3234         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3235         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3236         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3237         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3238         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3239 }
3240 run_test 31i "cross directory link under parent==============="
3241
3242 test_31j() {
3243         test_mkdir -c1 -p $DIR/$tdir
3244         test_mkdir -c1 -p $DIR/$tdir/dir1
3245         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3246         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3247         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3248         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3249         return 0
3250 }
3251 run_test 31j "link for directory==============="
3252
3253 test_31k() {
3254         test_mkdir -c1 -p $DIR/$tdir
3255         touch $DIR/$tdir/s
3256         touch $DIR/$tdir/exist
3257         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3258         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3259         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3260         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3261         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3262         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3263         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3264         return 0
3265 }
3266 run_test 31k "link to file: the same, non-existing, dir==============="
3267
3268 test_31m() {
3269         mkdir $DIR/d31m
3270         touch $DIR/d31m/s
3271         mkdir $DIR/d31m2
3272         touch $DIR/d31m2/exist
3273         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3274         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3275         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3276         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3277         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3278         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3279         return 0
3280 }
3281 run_test 31m "link to file: the same, non-existing, dir==============="
3282
3283 test_31n() {
3284         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3285         nlink=$(stat --format=%h $DIR/$tfile)
3286         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3287         local fd=$(free_fd)
3288         local cmd="exec $fd<$DIR/$tfile"
3289         eval $cmd
3290         cmd="exec $fd<&-"
3291         trap "eval $cmd" EXIT
3292         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3293         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3294         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3295         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3296         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3297         eval $cmd
3298 }
3299 run_test 31n "check link count of unlinked file"
3300
3301 link_one() {
3302         local tempfile=$(mktemp $1_XXXXXX)
3303         mlink $tempfile $1 2> /dev/null &&
3304                 echo "$BASHPID: link $tempfile to $1 succeeded"
3305         munlink $tempfile
3306 }
3307
3308 test_31o() { # LU-2901
3309         test_mkdir $DIR/$tdir
3310         for LOOP in $(seq 100); do
3311                 rm -f $DIR/$tdir/$tfile*
3312                 for THREAD in $(seq 8); do
3313                         link_one $DIR/$tdir/$tfile.$LOOP &
3314                 done
3315                 wait
3316                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3317                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3318                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3319                         break || true
3320         done
3321 }
3322 run_test 31o "duplicate hard links with same filename"
3323
3324 test_31p() {
3325         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3326
3327         test_mkdir $DIR/$tdir
3328         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3329         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3330
3331         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3332                 error "open unlink test1 failed"
3333         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3334                 error "open unlink test2 failed"
3335
3336         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3337                 error "test1 still exists"
3338         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3339                 error "test2 still exists"
3340 }
3341 run_test 31p "remove of open striped directory"
3342
3343 cleanup_test32_mount() {
3344         local rc=0
3345         trap 0
3346         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3347         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3348         losetup -d $loopdev || true
3349         rm -rf $DIR/$tdir
3350         return $rc
3351 }
3352
3353 test_32a() {
3354         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3355
3356         echo "== more mountpoints and symlinks ================="
3357         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3358         trap cleanup_test32_mount EXIT
3359         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3360         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3361                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3362         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3363                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3364         cleanup_test32_mount
3365 }
3366 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3367
3368 test_32b() {
3369         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3370
3371         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3372         trap cleanup_test32_mount EXIT
3373         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3374         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3375                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3376         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3377                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3378         cleanup_test32_mount
3379 }
3380 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3381
3382 test_32c() {
3383         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3384
3385         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3386         trap cleanup_test32_mount EXIT
3387         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3388         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3389                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3390         test_mkdir -p $DIR/$tdir/d2/test_dir
3391         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3392                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3393         cleanup_test32_mount
3394 }
3395 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3396
3397 test_32d() {
3398         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3399
3400         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3401         trap cleanup_test32_mount EXIT
3402         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3403         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3404                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3405         test_mkdir -p $DIR/$tdir/d2/test_dir
3406         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3407                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3408         cleanup_test32_mount
3409 }
3410 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3411
3412 test_32e() {
3413         rm -fr $DIR/$tdir
3414         test_mkdir -p $DIR/$tdir/tmp
3415         local tmp_dir=$DIR/$tdir/tmp
3416         ln -s $DIR/$tdir $tmp_dir/symlink11
3417         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3418         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3419         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3420 }
3421 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3422
3423 test_32f() {
3424         rm -fr $DIR/$tdir
3425         test_mkdir -p $DIR/$tdir/tmp
3426         local tmp_dir=$DIR/$tdir/tmp
3427         ln -s $DIR/$tdir $tmp_dir/symlink11
3428         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3429         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3430         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3431 }
3432 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3433
3434 test_32g() {
3435         local tmp_dir=$DIR/$tdir/tmp
3436         test_mkdir -p $tmp_dir
3437         test_mkdir $DIR/${tdir}2
3438         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3439         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3440         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3441         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3442         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3443         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3444 }
3445 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3446
3447 test_32h() {
3448         rm -fr $DIR/$tdir $DIR/${tdir}2
3449         tmp_dir=$DIR/$tdir/tmp
3450         test_mkdir -p $tmp_dir
3451         test_mkdir $DIR/${tdir}2
3452         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3453         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3454         ls $tmp_dir/symlink12 || error "listing symlink12"
3455         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3456 }
3457 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3458
3459 test_32i() {
3460         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3461
3462         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3463         trap cleanup_test32_mount EXIT
3464         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3465         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3466                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3467         touch $DIR/$tdir/test_file
3468         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3469                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3470         cleanup_test32_mount
3471 }
3472 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3473
3474 test_32j() {
3475         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3476
3477         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3478         trap cleanup_test32_mount EXIT
3479         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3480         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3481                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3482         touch $DIR/$tdir/test_file
3483         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3484                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3485         cleanup_test32_mount
3486 }
3487 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3488
3489 test_32k() {
3490         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3491
3492         rm -fr $DIR/$tdir
3493         trap cleanup_test32_mount EXIT
3494         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3495         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3496                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3497         test_mkdir -p $DIR/$tdir/d2
3498         touch $DIR/$tdir/d2/test_file || error "touch failed"
3499         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3500                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3501         cleanup_test32_mount
3502 }
3503 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3504
3505 test_32l() {
3506         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3507
3508         rm -fr $DIR/$tdir
3509         trap cleanup_test32_mount EXIT
3510         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3511         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3512                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3513         test_mkdir -p $DIR/$tdir/d2
3514         touch $DIR/$tdir/d2/test_file || error "touch failed"
3515         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3516                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3517         cleanup_test32_mount
3518 }
3519 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3520
3521 test_32m() {
3522         rm -fr $DIR/d32m
3523         test_mkdir -p $DIR/d32m/tmp
3524         TMP_DIR=$DIR/d32m/tmp
3525         ln -s $DIR $TMP_DIR/symlink11
3526         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3527         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3528                 error "symlink11 not a link"
3529         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3530                 error "symlink01 not a link"
3531 }
3532 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3533
3534 test_32n() {
3535         rm -fr $DIR/d32n
3536         test_mkdir -p $DIR/d32n/tmp
3537         TMP_DIR=$DIR/d32n/tmp
3538         ln -s $DIR $TMP_DIR/symlink11
3539         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3540         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3541         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3542 }
3543 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3544
3545 test_32o() {
3546         touch $DIR/$tfile
3547         test_mkdir -p $DIR/d32o/tmp
3548         TMP_DIR=$DIR/d32o/tmp
3549         ln -s $DIR/$tfile $TMP_DIR/symlink12
3550         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3551         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3552                 error "symlink12 not a link"
3553         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3554         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3555                 error "$DIR/d32o/tmp/symlink12 not file type"
3556         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3557                 error "$DIR/d32o/symlink02 not file type"
3558 }
3559 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3560
3561 test_32p() {
3562         log 32p_1
3563         rm -fr $DIR/d32p
3564         log 32p_2
3565         rm -f $DIR/$tfile
3566         log 32p_3
3567         touch $DIR/$tfile
3568         log 32p_4
3569         test_mkdir -p $DIR/d32p/tmp
3570         log 32p_5
3571         TMP_DIR=$DIR/d32p/tmp
3572         log 32p_6
3573         ln -s $DIR/$tfile $TMP_DIR/symlink12
3574         log 32p_7
3575         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3576         log 32p_8
3577         cat $DIR/d32p/tmp/symlink12 ||
3578                 error "Can't open $DIR/d32p/tmp/symlink12"
3579         log 32p_9
3580         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3581         log 32p_10
3582 }
3583 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3584
3585 test_32q() {
3586         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3587
3588         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3589         trap cleanup_test32_mount EXIT
3590         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3591         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3592         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3593                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3594         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3595         cleanup_test32_mount
3596 }
3597 run_test 32q "stat follows mountpoints in Lustre (should return error)"
3598
3599 test_32r() {
3600         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3601
3602         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3603         trap cleanup_test32_mount EXIT
3604         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3605         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3606         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3607                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3608         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
3609         cleanup_test32_mount
3610 }
3611 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
3612
3613 test_33aa() {
3614         rm -f $DIR/$tfile
3615         touch $DIR/$tfile
3616         chmod 444 $DIR/$tfile
3617         chown $RUNAS_ID $DIR/$tfile
3618         log 33_1
3619         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3620         log 33_2
3621 }
3622 run_test 33aa "write file with mode 444 (should return error)"
3623
3624 test_33a() {
3625         rm -fr $DIR/$tdir
3626         test_mkdir $DIR/$tdir
3627         chown $RUNAS_ID $DIR/$tdir
3628         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
3629                 error "$RUNAS create $tdir/$tfile failed"
3630         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
3631                 error "open RDWR" || true
3632 }
3633 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
3634
3635 test_33b() {
3636         rm -fr $DIR/$tdir
3637         test_mkdir $DIR/$tdir
3638         chown $RUNAS_ID $DIR/$tdir
3639         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
3640 }
3641 run_test 33b "test open file with malformed flags (No panic)"
3642
3643 test_33c() {
3644         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3645         remote_ost_nodsh && skip "remote OST with nodsh"
3646
3647         local ostnum
3648         local ostname
3649         local write_bytes
3650         local all_zeros
3651
3652         all_zeros=:
3653         rm -fr $DIR/$tdir
3654         test_mkdir $DIR/$tdir
3655         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
3656
3657         sync
3658         for ostnum in $(seq $OSTCOUNT); do
3659                 # test-framework's OST numbering is one-based, while Lustre's
3660                 # is zero-based
3661                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3662                 # Parsing llobdstat's output sucks; we could grep the /proc
3663                 # path, but that's likely to not be as portable as using the
3664                 # llobdstat utility.  So we parse lctl output instead.
3665                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3666                         obdfilter/$ostname/stats |
3667                         awk '/^write_bytes/ {print $7}' )
3668                 echo "baseline_write_bytes@$OSTnum/$ostname=$write_bytes"
3669                 if (( ${write_bytes:-0} > 0 ))
3670                 then
3671                         all_zeros=false
3672                         break;
3673                 fi
3674         done
3675
3676         $all_zeros || return 0
3677
3678         # Write four bytes
3679         echo foo > $DIR/$tdir/bar
3680         # Really write them
3681         sync
3682
3683         # Total up write_bytes after writing.  We'd better find non-zeros.
3684         for ostnum in $(seq $OSTCOUNT); do
3685                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3686                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3687                         obdfilter/$ostname/stats |
3688                         awk '/^write_bytes/ {print $7}' )
3689                 echo "write_bytes@$OSTnum/$ostname=$write_bytes"
3690                 if (( ${write_bytes:-0} > 0 ))
3691                 then
3692                         all_zeros=false
3693                         break;
3694                 fi
3695         done
3696
3697         if $all_zeros
3698         then
3699                 for ostnum in $(seq $OSTCOUNT); do
3700                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3701                         echo "Check that write_bytes is present in obdfilter/*/stats:"
3702                         do_facet ost$ostnum lctl get_param -n \
3703                                 obdfilter/$ostname/stats
3704                 done
3705                 error "OST not keeping write_bytes stats (b22312)"
3706         fi
3707 }
3708 run_test 33c "test llobdstat and write_bytes"
3709
3710 test_33d() {
3711         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
3712         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3713
3714         local MDTIDX=1
3715         local remote_dir=$DIR/$tdir/remote_dir
3716
3717         test_mkdir $DIR/$tdir
3718         $LFS mkdir -i $MDTIDX $remote_dir ||
3719                 error "create remote directory failed"
3720
3721         touch $remote_dir/$tfile
3722         chmod 444 $remote_dir/$tfile
3723         chown $RUNAS_ID $remote_dir/$tfile
3724
3725         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3726
3727         chown $RUNAS_ID $remote_dir
3728         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
3729                                         error "create" || true
3730         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
3731                                     error "open RDWR" || true
3732         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
3733 }
3734 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
3735
3736 test_33e() {
3737         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3738
3739         mkdir $DIR/$tdir
3740
3741         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3742         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3743         mkdir $DIR/$tdir/local_dir
3744
3745         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3746         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3747         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3748
3749         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3750                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
3751
3752         rmdir $DIR/$tdir/* || error "rmdir failed"
3753
3754         umask 777
3755         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3756         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3757         mkdir $DIR/$tdir/local_dir
3758
3759         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3760         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3761         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3762
3763         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3764                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
3765
3766         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
3767
3768         umask 000
3769         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3770         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3771         mkdir $DIR/$tdir/local_dir
3772
3773         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3774         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3775         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3776
3777         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3778                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
3779 }
3780 run_test 33e "mkdir and striped directory should have same mode"
3781
3782 cleanup_33f() {
3783         trap 0
3784         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
3785 }
3786
3787 test_33f() {
3788         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3789         remote_mds_nodsh && skip "remote MDS with nodsh"
3790
3791         mkdir $DIR/$tdir
3792         chmod go+rwx $DIR/$tdir
3793         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
3794         trap cleanup_33f EXIT
3795
3796         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
3797                 error "cannot create striped directory"
3798
3799         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
3800                 error "cannot create files in striped directory"
3801
3802         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
3803                 error "cannot remove files in striped directory"
3804
3805         $RUNAS rmdir $DIR/$tdir/striped_dir ||
3806                 error "cannot remove striped directory"
3807
3808         cleanup_33f
3809 }
3810 run_test 33f "nonroot user can create, access, and remove a striped directory"
3811
3812 test_33g() {
3813         mkdir -p $DIR/$tdir/dir2
3814
3815         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
3816         echo $err
3817         [[ $err =~ "exists" ]] || error "Not exists error"
3818 }
3819 run_test 33g "nonroot user create already existing root created file"
3820
3821 test_33h() {
3822         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3823         [ $MDS1_VERSION -lt $(version_code 2.13.50) ] &&
3824                 skip "Need MDS version at least 2.13.50"
3825
3826         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir ||
3827                 error "mkdir $tdir failed"
3828         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
3829
3830         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
3831         local index2
3832
3833         for fname in $DIR/$tdir/$tfile.bak \
3834                      $DIR/$tdir/$tfile.SAV \
3835                      $DIR/$tdir/$tfile.orig \
3836                      $DIR/$tdir/$tfile~; do
3837                 touch $fname  || error "touch $fname failed"
3838                 index2=$($LFS getstripe -m $fname)
3839                 [ $index -eq $index2 ] ||
3840                         error "$fname MDT index mismatch $index != $index2"
3841         done
3842
3843         local failed=0
3844         for i in {1..250}; do
3845                 for fname in $(mktemp -u $DIR/$tdir/.$tfile.XXXXXX) \
3846                              $(mktemp $DIR/$tdir/$tfile.XXXXXXXX); do
3847                         touch $fname  || error "touch $fname failed"
3848                         index2=$($LFS getstripe -m $fname)
3849                         if [[ $index != $index2 ]]; then
3850                                 failed=$((failed + 1))
3851                                 echo "$fname MDT index mismatch $index != $index2"
3852                         fi
3853                 done
3854         done
3855         echo "$failed MDT index mismatches"
3856         (( failed < 20 )) || error "MDT index mismatch $failed times"
3857
3858 }
3859 run_test 33h "temp file is located on the same MDT as target"
3860
3861 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
3862 test_34a() {
3863         rm -f $DIR/f34
3864         $MCREATE $DIR/f34 || error "mcreate failed"
3865         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3866                 error "getstripe failed"
3867         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
3868         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3869                 error "getstripe failed"
3870         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3871                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3872 }
3873 run_test 34a "truncate file that has not been opened ==========="
3874
3875 test_34b() {
3876         [ ! -f $DIR/f34 ] && test_34a
3877         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3878                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3879         $OPENFILE -f O_RDONLY $DIR/f34
3880         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3881                 error "getstripe failed"
3882         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3883                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3884 }
3885 run_test 34b "O_RDONLY opening file doesn't create objects ====="
3886
3887 test_34c() {
3888         [ ! -f $DIR/f34 ] && test_34a
3889         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3890                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3891         $OPENFILE -f O_RDWR $DIR/f34
3892         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
3893                 error "$LFS getstripe failed"
3894         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3895                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3896 }
3897 run_test 34c "O_RDWR opening file-with-size works =============="
3898
3899 test_34d() {
3900         [ ! -f $DIR/f34 ] && test_34a
3901         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
3902                 error "dd failed"
3903         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3904                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3905         rm $DIR/f34
3906 }
3907 run_test 34d "write to sparse file ============================="
3908
3909 test_34e() {
3910         rm -f $DIR/f34e
3911         $MCREATE $DIR/f34e || error "mcreate failed"
3912         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
3913         $CHECKSTAT -s 1000 $DIR/f34e ||
3914                 error "Size of $DIR/f34e not equal to 1000 bytes"
3915         $OPENFILE -f O_RDWR $DIR/f34e
3916         $CHECKSTAT -s 1000 $DIR/f34e ||
3917                 error "Size of $DIR/f34e not equal to 1000 bytes"
3918 }
3919 run_test 34e "create objects, some with size and some without =="
3920
3921 test_34f() { # bug 6242, 6243
3922         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3923
3924         SIZE34F=48000
3925         rm -f $DIR/f34f
3926         $MCREATE $DIR/f34f || error "mcreate failed"
3927         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
3928         dd if=$DIR/f34f of=$TMP/f34f
3929         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
3930         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
3931         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
3932         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
3933         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
3934 }
3935 run_test 34f "read from a file with no objects until EOF ======="
3936
3937 test_34g() {
3938         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3939
3940         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
3941                 error "dd failed"
3942         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
3943         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3944                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
3945         cancel_lru_locks osc
3946         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3947                 error "wrong size after lock cancel"
3948
3949         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
3950         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3951                 error "expanding truncate failed"
3952         cancel_lru_locks osc
3953         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3954                 error "wrong expanded size after lock cancel"
3955 }
3956 run_test 34g "truncate long file ==============================="
3957
3958 test_34h() {
3959         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3960
3961         local gid=10
3962         local sz=1000
3963
3964         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
3965         sync # Flush the cache so that multiop below does not block on cache
3966              # flush when getting the group lock
3967         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
3968         MULTIPID=$!
3969
3970         # Since just timed wait is not good enough, let's do a sync write
3971         # that way we are sure enough time for a roundtrip + processing
3972         # passed + 2 seconds of extra margin.
3973         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
3974         rm $DIR/${tfile}-1
3975         sleep 2
3976
3977         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
3978                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
3979                 kill -9 $MULTIPID
3980         fi
3981         wait $MULTIPID
3982         local nsz=`stat -c %s $DIR/$tfile`
3983         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
3984 }
3985 run_test 34h "ftruncate file under grouplock should not block"
3986
3987 test_35a() {
3988         cp /bin/sh $DIR/f35a
3989         chmod 444 $DIR/f35a
3990         chown $RUNAS_ID $DIR/f35a
3991         $RUNAS $DIR/f35a && error || true
3992         rm $DIR/f35a
3993 }
3994 run_test 35a "exec file with mode 444 (should return and not leak)"
3995
3996 test_36a() {
3997         rm -f $DIR/f36
3998         utime $DIR/f36 || error "utime failed for MDS"
3999 }
4000 run_test 36a "MDS utime check (mknod, utime)"
4001
4002 test_36b() {
4003         echo "" > $DIR/f36
4004         utime $DIR/f36 || error "utime failed for OST"
4005 }
4006 run_test 36b "OST utime check (open, utime)"
4007
4008 test_36c() {
4009         rm -f $DIR/d36/f36
4010         test_mkdir $DIR/d36
4011         chown $RUNAS_ID $DIR/d36
4012         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4013 }
4014 run_test 36c "non-root MDS utime check (mknod, utime)"
4015
4016 test_36d() {
4017         [ ! -d $DIR/d36 ] && test_36c
4018         echo "" > $DIR/d36/f36
4019         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4020 }
4021 run_test 36d "non-root OST utime check (open, utime)"
4022
4023 test_36e() {
4024         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4025
4026         test_mkdir $DIR/$tdir
4027         touch $DIR/$tdir/$tfile
4028         $RUNAS utime $DIR/$tdir/$tfile &&
4029                 error "utime worked, expected failure" || true
4030 }
4031 run_test 36e "utime on non-owned file (should return error)"
4032
4033 subr_36fh() {
4034         local fl="$1"
4035         local LANG_SAVE=$LANG
4036         local LC_LANG_SAVE=$LC_LANG
4037         export LANG=C LC_LANG=C # for date language
4038
4039         DATESTR="Dec 20  2000"
4040         test_mkdir $DIR/$tdir
4041         lctl set_param fail_loc=$fl
4042         date; date +%s
4043         cp /etc/hosts $DIR/$tdir/$tfile
4044         sync & # write RPC generated with "current" inode timestamp, but delayed
4045         sleep 1
4046         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4047         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4048         cancel_lru_locks $OSC
4049         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4050         date; date +%s
4051         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4052                 echo "BEFORE: $LS_BEFORE" && \
4053                 echo "AFTER : $LS_AFTER" && \
4054                 echo "WANT  : $DATESTR" && \
4055                 error "$DIR/$tdir/$tfile timestamps changed" || true
4056
4057         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4058 }
4059
4060 test_36f() {
4061         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4062
4063         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4064         subr_36fh "0x80000214"
4065 }
4066 run_test 36f "utime on file racing with OST BRW write =========="
4067
4068 test_36g() {
4069         remote_ost_nodsh && skip "remote OST with nodsh"
4070         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4071         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4072                 skip "Need MDS version at least 2.12.51"
4073
4074         local fmd_max_age
4075         local fmd
4076         local facet="ost1"
4077         local tgt="obdfilter"
4078
4079         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4080
4081         test_mkdir $DIR/$tdir
4082         fmd_max_age=$(do_facet $facet \
4083                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4084                 head -n 1")
4085
4086         echo "FMD max age: ${fmd_max_age}s"
4087         touch $DIR/$tdir/$tfile
4088         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4089                 gawk '{cnt=cnt+$1}  END{print cnt}')
4090         echo "FMD before: $fmd"
4091         [[ $fmd == 0 ]] &&
4092                 error "FMD wasn't create by touch"
4093         sleep $((fmd_max_age + 12))
4094         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4095                 gawk '{cnt=cnt+$1}  END{print cnt}')
4096         echo "FMD after: $fmd"
4097         [[ $fmd == 0 ]] ||
4098                 error "FMD wasn't expired by ping"
4099 }
4100 run_test 36g "FMD cache expiry ====================="
4101
4102 test_36h() {
4103         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4104
4105         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4106         subr_36fh "0x80000227"
4107 }
4108 run_test 36h "utime on file racing with OST BRW write =========="
4109
4110 test_36i() {
4111         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4112
4113         test_mkdir $DIR/$tdir
4114         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4115
4116         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4117         local new_mtime=$((mtime + 200))
4118
4119         #change Modify time of striped dir
4120         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4121                         error "change mtime failed"
4122
4123         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4124
4125         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4126 }
4127 run_test 36i "change mtime on striped directory"
4128
4129 # test_37 - duplicate with tests 32q 32r
4130
4131 test_38() {
4132         local file=$DIR/$tfile
4133         touch $file
4134         openfile -f O_DIRECTORY $file
4135         local RC=$?
4136         local ENOTDIR=20
4137         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4138         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4139 }
4140 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4141
4142 test_39a() { # was test_39
4143         touch $DIR/$tfile
4144         touch $DIR/${tfile}2
4145 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4146 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4147 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4148         sleep 2
4149         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4150         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4151                 echo "mtime"
4152                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4153                 echo "atime"
4154                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4155                 echo "ctime"
4156                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4157                 error "O_TRUNC didn't change timestamps"
4158         fi
4159 }
4160 run_test 39a "mtime changed on create"
4161
4162 test_39b() {
4163         test_mkdir -c1 $DIR/$tdir
4164         cp -p /etc/passwd $DIR/$tdir/fopen
4165         cp -p /etc/passwd $DIR/$tdir/flink
4166         cp -p /etc/passwd $DIR/$tdir/funlink
4167         cp -p /etc/passwd $DIR/$tdir/frename
4168         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4169
4170         sleep 1
4171         echo "aaaaaa" >> $DIR/$tdir/fopen
4172         echo "aaaaaa" >> $DIR/$tdir/flink
4173         echo "aaaaaa" >> $DIR/$tdir/funlink
4174         echo "aaaaaa" >> $DIR/$tdir/frename
4175
4176         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4177         local link_new=`stat -c %Y $DIR/$tdir/flink`
4178         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4179         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4180
4181         cat $DIR/$tdir/fopen > /dev/null
4182         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4183         rm -f $DIR/$tdir/funlink2
4184         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4185
4186         for (( i=0; i < 2; i++ )) ; do
4187                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4188                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4189                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4190                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4191
4192                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4193                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4194                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4195                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4196
4197                 cancel_lru_locks $OSC
4198                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4199         done
4200 }
4201 run_test 39b "mtime change on open, link, unlink, rename  ======"
4202
4203 # this should be set to past
4204 TEST_39_MTIME=`date -d "1 year ago" +%s`
4205
4206 # bug 11063
4207 test_39c() {
4208         touch $DIR1/$tfile
4209         sleep 2
4210         local mtime0=`stat -c %Y $DIR1/$tfile`
4211
4212         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4213         local mtime1=`stat -c %Y $DIR1/$tfile`
4214         [ "$mtime1" = $TEST_39_MTIME ] || \
4215                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4216
4217         local d1=`date +%s`
4218         echo hello >> $DIR1/$tfile
4219         local d2=`date +%s`
4220         local mtime2=`stat -c %Y $DIR1/$tfile`
4221         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4222                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4223
4224         mv $DIR1/$tfile $DIR1/$tfile-1
4225
4226         for (( i=0; i < 2; i++ )) ; do
4227                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4228                 [ "$mtime2" = "$mtime3" ] || \
4229                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4230
4231                 cancel_lru_locks $OSC
4232                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4233         done
4234 }
4235 run_test 39c "mtime change on rename ==========================="
4236
4237 # bug 21114
4238 test_39d() {
4239         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4240
4241         touch $DIR1/$tfile
4242         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4243
4244         for (( i=0; i < 2; i++ )) ; do
4245                 local mtime=`stat -c %Y $DIR1/$tfile`
4246                 [ $mtime = $TEST_39_MTIME ] || \
4247                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4248
4249                 cancel_lru_locks $OSC
4250                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4251         done
4252 }
4253 run_test 39d "create, utime, stat =============================="
4254
4255 # bug 21114
4256 test_39e() {
4257         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4258
4259         touch $DIR1/$tfile
4260         local mtime1=`stat -c %Y $DIR1/$tfile`
4261
4262         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4263
4264         for (( i=0; i < 2; i++ )) ; do
4265                 local mtime2=`stat -c %Y $DIR1/$tfile`
4266                 [ $mtime2 = $TEST_39_MTIME ] || \
4267                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4268
4269                 cancel_lru_locks $OSC
4270                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4271         done
4272 }
4273 run_test 39e "create, stat, utime, stat ========================"
4274
4275 # bug 21114
4276 test_39f() {
4277         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4278
4279         touch $DIR1/$tfile
4280         mtime1=`stat -c %Y $DIR1/$tfile`
4281
4282         sleep 2
4283         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4284
4285         for (( i=0; i < 2; i++ )) ; do
4286                 local mtime2=`stat -c %Y $DIR1/$tfile`
4287                 [ $mtime2 = $TEST_39_MTIME ] || \
4288                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4289
4290                 cancel_lru_locks $OSC
4291                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4292         done
4293 }
4294 run_test 39f "create, stat, sleep, utime, stat ================="
4295
4296 # bug 11063
4297 test_39g() {
4298         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4299
4300         echo hello >> $DIR1/$tfile
4301         local mtime1=`stat -c %Y $DIR1/$tfile`
4302
4303         sleep 2
4304         chmod o+r $DIR1/$tfile
4305
4306         for (( i=0; i < 2; i++ )) ; do
4307                 local mtime2=`stat -c %Y $DIR1/$tfile`
4308                 [ "$mtime1" = "$mtime2" ] || \
4309                         error "lost mtime: $mtime2, should be $mtime1"
4310
4311                 cancel_lru_locks $OSC
4312                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4313         done
4314 }
4315 run_test 39g "write, chmod, stat ==============================="
4316
4317 # bug 11063
4318 test_39h() {
4319         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4320
4321         touch $DIR1/$tfile
4322         sleep 1
4323
4324         local d1=`date`
4325         echo hello >> $DIR1/$tfile
4326         local mtime1=`stat -c %Y $DIR1/$tfile`
4327
4328         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4329         local d2=`date`
4330         if [ "$d1" != "$d2" ]; then
4331                 echo "write and touch not within one second"
4332         else
4333                 for (( i=0; i < 2; i++ )) ; do
4334                         local mtime2=`stat -c %Y $DIR1/$tfile`
4335                         [ "$mtime2" = $TEST_39_MTIME ] || \
4336                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4337
4338                         cancel_lru_locks $OSC
4339                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4340                 done
4341         fi
4342 }
4343 run_test 39h "write, utime within one second, stat ============="
4344
4345 test_39i() {
4346         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4347
4348         touch $DIR1/$tfile
4349         sleep 1
4350
4351         echo hello >> $DIR1/$tfile
4352         local mtime1=`stat -c %Y $DIR1/$tfile`
4353
4354         mv $DIR1/$tfile $DIR1/$tfile-1
4355
4356         for (( i=0; i < 2; i++ )) ; do
4357                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4358
4359                 [ "$mtime1" = "$mtime2" ] || \
4360                         error "lost mtime: $mtime2, should be $mtime1"
4361
4362                 cancel_lru_locks $OSC
4363                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4364         done
4365 }
4366 run_test 39i "write, rename, stat =============================="
4367
4368 test_39j() {
4369         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4370
4371         start_full_debug_logging
4372         touch $DIR1/$tfile
4373         sleep 1
4374
4375         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4376         lctl set_param fail_loc=0x80000412
4377         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4378                 error "multiop failed"
4379         local multipid=$!
4380         local mtime1=`stat -c %Y $DIR1/$tfile`
4381
4382         mv $DIR1/$tfile $DIR1/$tfile-1
4383
4384         kill -USR1 $multipid
4385         wait $multipid || error "multiop close failed"
4386
4387         for (( i=0; i < 2; i++ )) ; do
4388                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4389                 [ "$mtime1" = "$mtime2" ] ||
4390                         error "mtime is lost on close: $mtime2, " \
4391                               "should be $mtime1"
4392
4393                 cancel_lru_locks
4394                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4395         done
4396         lctl set_param fail_loc=0
4397         stop_full_debug_logging
4398 }
4399 run_test 39j "write, rename, close, stat ======================="
4400
4401 test_39k() {
4402         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4403
4404         touch $DIR1/$tfile
4405         sleep 1
4406
4407         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4408         local multipid=$!
4409         local mtime1=`stat -c %Y $DIR1/$tfile`
4410
4411         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4412
4413         kill -USR1 $multipid
4414         wait $multipid || error "multiop close failed"
4415
4416         for (( i=0; i < 2; i++ )) ; do
4417                 local mtime2=`stat -c %Y $DIR1/$tfile`
4418
4419                 [ "$mtime2" = $TEST_39_MTIME ] || \
4420                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4421
4422                 cancel_lru_locks
4423                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4424         done
4425 }
4426 run_test 39k "write, utime, close, stat ========================"
4427
4428 # this should be set to future
4429 TEST_39_ATIME=`date -d "1 year" +%s`
4430
4431 test_39l() {
4432         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4433         remote_mds_nodsh && skip "remote MDS with nodsh"
4434
4435         local atime_diff=$(do_facet $SINGLEMDS \
4436                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4437         rm -rf $DIR/$tdir
4438         mkdir -p $DIR/$tdir
4439
4440         # test setting directory atime to future
4441         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4442         local atime=$(stat -c %X $DIR/$tdir)
4443         [ "$atime" = $TEST_39_ATIME ] ||
4444                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4445
4446         # test setting directory atime from future to now
4447         local now=$(date +%s)
4448         touch -a -d @$now $DIR/$tdir
4449
4450         atime=$(stat -c %X $DIR/$tdir)
4451         [ "$atime" -eq "$now"  ] ||
4452                 error "atime is not updated from future: $atime, $now"
4453
4454         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4455         sleep 3
4456
4457         # test setting directory atime when now > dir atime + atime_diff
4458         local d1=$(date +%s)
4459         ls $DIR/$tdir
4460         local d2=$(date +%s)
4461         cancel_lru_locks mdc
4462         atime=$(stat -c %X $DIR/$tdir)
4463         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4464                 error "atime is not updated  : $atime, should be $d2"
4465
4466         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4467         sleep 3
4468
4469         # test not setting directory atime when now < dir atime + atime_diff
4470         ls $DIR/$tdir
4471         cancel_lru_locks mdc
4472         atime=$(stat -c %X $DIR/$tdir)
4473         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4474                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4475
4476         do_facet $SINGLEMDS \
4477                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4478 }
4479 run_test 39l "directory atime update ==========================="
4480
4481 test_39m() {
4482         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4483
4484         touch $DIR1/$tfile
4485         sleep 2
4486         local far_past_mtime=$(date -d "May 29 1953" +%s)
4487         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4488
4489         touch -m -d @$far_past_mtime $DIR1/$tfile
4490         touch -a -d @$far_past_atime $DIR1/$tfile
4491
4492         for (( i=0; i < 2; i++ )) ; do
4493                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4494                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4495                         error "atime or mtime set incorrectly"
4496
4497                 cancel_lru_locks $OSC
4498                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4499         done
4500 }
4501 run_test 39m "test atime and mtime before 1970"
4502
4503 test_39n() { # LU-3832
4504         remote_mds_nodsh && skip "remote MDS with nodsh"
4505
4506         local atime_diff=$(do_facet $SINGLEMDS \
4507                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4508         local atime0
4509         local atime1
4510         local atime2
4511
4512         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4513
4514         rm -rf $DIR/$tfile
4515         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4516         atime0=$(stat -c %X $DIR/$tfile)
4517
4518         sleep 5
4519         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4520         atime1=$(stat -c %X $DIR/$tfile)
4521
4522         sleep 5
4523         cancel_lru_locks mdc
4524         cancel_lru_locks osc
4525         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4526         atime2=$(stat -c %X $DIR/$tfile)
4527
4528         do_facet $SINGLEMDS \
4529                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4530
4531         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4532         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4533 }
4534 run_test 39n "check that O_NOATIME is honored"
4535
4536 test_39o() {
4537         TESTDIR=$DIR/$tdir/$tfile
4538         [ -e $TESTDIR ] && rm -rf $TESTDIR
4539         mkdir -p $TESTDIR
4540         cd $TESTDIR
4541         links1=2
4542         ls
4543         mkdir a b
4544         ls
4545         links2=$(stat -c %h .)
4546         [ $(($links1 + 2)) != $links2 ] &&
4547                 error "wrong links count $(($links1 + 2)) != $links2"
4548         rmdir b
4549         links3=$(stat -c %h .)
4550         [ $(($links1 + 1)) != $links3 ] &&
4551                 error "wrong links count $links1 != $links3"
4552         return 0
4553 }
4554 run_test 39o "directory cached attributes updated after create"
4555
4556 test_39p() {
4557         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4558
4559         local MDTIDX=1
4560         TESTDIR=$DIR/$tdir/$tdir
4561         [ -e $TESTDIR ] && rm -rf $TESTDIR
4562         test_mkdir -p $TESTDIR
4563         cd $TESTDIR
4564         links1=2
4565         ls
4566         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4567         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4568         ls
4569         links2=$(stat -c %h .)
4570         [ $(($links1 + 2)) != $links2 ] &&
4571                 error "wrong links count $(($links1 + 2)) != $links2"
4572         rmdir remote_dir2
4573         links3=$(stat -c %h .)
4574         [ $(($links1 + 1)) != $links3 ] &&
4575                 error "wrong links count $links1 != $links3"
4576         return 0
4577 }
4578 run_test 39p "remote directory cached attributes updated after create ========"
4579
4580 test_39r() {
4581         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
4582                 skip "no atime update on old OST"
4583         if [ "$ost1_FSTYPE" != ldiskfs ]; then
4584                 skip_env "ldiskfs only test"
4585         fi
4586
4587         local saved_adiff
4588         saved_adiff=$(do_facet ost1 \
4589                 lctl get_param -n obdfilter.*OST0000.atime_diff)
4590         stack_trap "do_facet ost1 \
4591                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
4592
4593         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
4594
4595         $LFS setstripe -i 0 $DIR/$tfile
4596         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
4597                 error "can't write initial file"
4598         cancel_lru_locks osc
4599
4600         # exceed atime_diff and access file
4601         sleep 6
4602         dd if=$DIR/$tfile of=/dev/null || error "can't udpate atime"
4603
4604         local atime_cli=$(stat -c %X $DIR/$tfile)
4605         echo "client atime: $atime_cli"
4606         # allow atime update to be written to device
4607         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
4608         sleep 5
4609
4610         local ostdev=$(ostdevname 1)
4611         local fid=($(lfs getstripe -y $DIR/$tfile |
4612                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
4613         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
4614         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
4615
4616         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
4617         local atime_ost=$(do_facet ost1 "$cmd" |&
4618                           awk -F'[: ]' '/atime:/ { print $4 }')
4619         (( atime_cli == atime_ost )) ||
4620                 error "atime on client $atime_cli != ost $atime_ost"
4621 }
4622 run_test 39r "lazy atime update on OST"
4623
4624 test_39q() { # LU-8041
4625         local testdir=$DIR/$tdir
4626         mkdir -p $testdir
4627         multiop_bg_pause $testdir D_c || error "multiop failed"
4628         local multipid=$!
4629         cancel_lru_locks mdc
4630         kill -USR1 $multipid
4631         local atime=$(stat -c %X $testdir)
4632         [ "$atime" -ne 0 ] || error "atime is zero"
4633 }
4634 run_test 39q "close won't zero out atime"
4635
4636 test_40() {
4637         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
4638         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
4639                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
4640         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
4641                 error "$tfile is not 4096 bytes in size"
4642 }
4643 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
4644
4645 test_41() {
4646         # bug 1553
4647         small_write $DIR/f41 18
4648 }
4649 run_test 41 "test small file write + fstat ====================="
4650
4651 count_ost_writes() {
4652         lctl get_param -n ${OSC}.*.stats |
4653                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
4654                         END { printf("%0.0f", writes) }'
4655 }
4656
4657 # decent default
4658 WRITEBACK_SAVE=500
4659 DIRTY_RATIO_SAVE=40
4660 MAX_DIRTY_RATIO=50
4661 BG_DIRTY_RATIO_SAVE=10
4662 MAX_BG_DIRTY_RATIO=25
4663
4664 start_writeback() {
4665         trap 0
4666         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
4667         # dirty_ratio, dirty_background_ratio
4668         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4669                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
4670                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
4671                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
4672         else
4673                 # if file not here, we are a 2.4 kernel
4674                 kill -CONT `pidof kupdated`
4675         fi
4676 }
4677
4678 stop_writeback() {
4679         # setup the trap first, so someone cannot exit the test at the
4680         # exact wrong time and mess up a machine
4681         trap start_writeback EXIT
4682         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
4683         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4684                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
4685                 sysctl -w vm.dirty_writeback_centisecs=0
4686                 sysctl -w vm.dirty_writeback_centisecs=0
4687                 # save and increase /proc/sys/vm/dirty_ratio
4688                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
4689                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
4690                 # save and increase /proc/sys/vm/dirty_background_ratio
4691                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
4692                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
4693         else
4694                 # if file not here, we are a 2.4 kernel
4695                 kill -STOP `pidof kupdated`
4696         fi
4697 }
4698
4699 # ensure that all stripes have some grant before we test client-side cache
4700 setup_test42() {
4701         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
4702                 dd if=/dev/zero of=$i bs=4k count=1
4703                 rm $i
4704         done
4705 }
4706
4707 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
4708 # file truncation, and file removal.
4709 test_42a() {
4710         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4711
4712         setup_test42
4713         cancel_lru_locks $OSC
4714         stop_writeback
4715         sync; sleep 1; sync # just to be safe
4716         BEFOREWRITES=`count_ost_writes`
4717         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
4718         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
4719         AFTERWRITES=`count_ost_writes`
4720         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
4721                 error "$BEFOREWRITES < $AFTERWRITES"
4722         start_writeback
4723 }
4724 run_test 42a "ensure that we don't flush on close"
4725
4726 test_42b() {
4727         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4728
4729         setup_test42
4730         cancel_lru_locks $OSC
4731         stop_writeback
4732         sync
4733         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
4734         BEFOREWRITES=$(count_ost_writes)
4735         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
4736         AFTERWRITES=$(count_ost_writes)
4737         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4738                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
4739         fi
4740         BEFOREWRITES=$(count_ost_writes)
4741         sync || error "sync: $?"
4742         AFTERWRITES=$(count_ost_writes)
4743         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4744                 error "$BEFOREWRITES < $AFTERWRITES on sync"
4745         fi
4746         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
4747         start_writeback
4748         return 0
4749 }
4750 run_test 42b "test destroy of file with cached dirty data ======"
4751
4752 # if these tests just want to test the effect of truncation,
4753 # they have to be very careful.  consider:
4754 # - the first open gets a {0,EOF}PR lock
4755 # - the first write conflicts and gets a {0, count-1}PW
4756 # - the rest of the writes are under {count,EOF}PW
4757 # - the open for truncate tries to match a {0,EOF}PR
4758 #   for the filesize and cancels the PWs.
4759 # any number of fixes (don't get {0,EOF} on open, match
4760 # composite locks, do smarter file size management) fix
4761 # this, but for now we want these tests to verify that
4762 # the cancellation with truncate intent works, so we
4763 # start the file with a full-file pw lock to match against
4764 # until the truncate.
4765 trunc_test() {
4766         test=$1
4767         file=$DIR/$test
4768         offset=$2
4769         cancel_lru_locks $OSC
4770         stop_writeback
4771         # prime the file with 0,EOF PW to match
4772         touch $file
4773         $TRUNCATE $file 0
4774         sync; sync
4775         # now the real test..
4776         dd if=/dev/zero of=$file bs=1024 count=100
4777         BEFOREWRITES=`count_ost_writes`
4778         $TRUNCATE $file $offset
4779         cancel_lru_locks $OSC
4780         AFTERWRITES=`count_ost_writes`
4781         start_writeback
4782 }
4783
4784 test_42c() {
4785         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4786
4787         trunc_test 42c 1024
4788         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
4789                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
4790         rm $file
4791 }
4792 run_test 42c "test partial truncate of file with cached dirty data"
4793
4794 test_42d() {
4795         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4796
4797         trunc_test 42d 0
4798         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
4799                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
4800         rm $file
4801 }
4802 run_test 42d "test complete truncate of file with cached dirty data"
4803
4804 test_42e() { # bug22074
4805         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4806
4807         local TDIR=$DIR/${tdir}e
4808         local pages=16 # hardcoded 16 pages, don't change it.
4809         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
4810         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
4811         local max_dirty_mb
4812         local warmup_files
4813
4814         test_mkdir $DIR/${tdir}e
4815         $LFS setstripe -c 1 $TDIR
4816         createmany -o $TDIR/f $files
4817
4818         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
4819
4820         # we assume that with $OSTCOUNT files, at least one of them will
4821         # be allocated on OST0.
4822         warmup_files=$((OSTCOUNT * max_dirty_mb))
4823         createmany -o $TDIR/w $warmup_files
4824
4825         # write a large amount of data into one file and sync, to get good
4826         # avail_grant number from OST.
4827         for ((i=0; i<$warmup_files; i++)); do
4828                 idx=$($LFS getstripe -i $TDIR/w$i)
4829                 [ $idx -ne 0 ] && continue
4830                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
4831                 break
4832         done
4833         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
4834         sync
4835         $LCTL get_param $proc_osc0/cur_dirty_bytes
4836         $LCTL get_param $proc_osc0/cur_grant_bytes
4837
4838         # create as much dirty pages as we can while not to trigger the actual
4839         # RPCs directly. but depends on the env, VFS may trigger flush during this
4840         # period, hopefully we are good.
4841         for ((i=0; i<$warmup_files; i++)); do
4842                 idx=$($LFS getstripe -i $TDIR/w$i)
4843                 [ $idx -ne 0 ] && continue
4844                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
4845         done
4846         $LCTL get_param $proc_osc0/cur_dirty_bytes
4847         $LCTL get_param $proc_osc0/cur_grant_bytes
4848
4849         # perform the real test
4850         $LCTL set_param $proc_osc0/rpc_stats 0
4851         for ((;i<$files; i++)); do
4852                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
4853                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
4854         done
4855         sync
4856         $LCTL get_param $proc_osc0/rpc_stats
4857
4858         local percent=0
4859         local have_ppr=false
4860         $LCTL get_param $proc_osc0/rpc_stats |
4861                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
4862                         # skip lines until we are at the RPC histogram data
4863                         [ "$PPR" == "pages" ] && have_ppr=true && continue
4864                         $have_ppr || continue
4865
4866                         # we only want the percent stat for < 16 pages
4867                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
4868
4869                         percent=$((percent + WPCT))
4870                         if [[ $percent -gt 15 ]]; then
4871                                 error "less than 16-pages write RPCs" \
4872                                       "$percent% > 15%"
4873                                 break
4874                         fi
4875                 done
4876         rm -rf $TDIR
4877 }
4878 run_test 42e "verify sub-RPC writes are not done synchronously"
4879
4880 test_43A() { # was test_43
4881         test_mkdir $DIR/$tdir
4882         cp -p /bin/ls $DIR/$tdir/$tfile
4883         $MULTIOP $DIR/$tdir/$tfile Ow_c &
4884         pid=$!
4885         # give multiop a chance to open
4886         sleep 1
4887
4888         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
4889         kill -USR1 $pid
4890         # Wait for multiop to exit
4891         wait $pid
4892 }
4893 run_test 43A "execution of file opened for write should return -ETXTBSY"
4894
4895 test_43a() {
4896         test_mkdir $DIR/$tdir
4897         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4898         $DIR/$tdir/sleep 60 &
4899         SLEEP_PID=$!
4900         # Make sure exec of $tdir/sleep wins race with truncate
4901         sleep 1
4902         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
4903         kill $SLEEP_PID
4904 }
4905 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
4906
4907 test_43b() {
4908         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4909
4910         test_mkdir $DIR/$tdir
4911         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4912         $DIR/$tdir/sleep 60 &
4913         SLEEP_PID=$!
4914         # Make sure exec of $tdir/sleep wins race with truncate
4915         sleep 1
4916         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
4917         kill $SLEEP_PID
4918 }
4919 run_test 43b "truncate of file being executed should return -ETXTBSY"
4920
4921 test_43c() {
4922         local testdir="$DIR/$tdir"
4923         test_mkdir $testdir
4924         cp $SHELL $testdir/
4925         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
4926                 ( cd $testdir && md5sum -c )
4927 }
4928 run_test 43c "md5sum of copy into lustre"
4929
4930 test_44A() { # was test_44
4931         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4932
4933         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
4934         dd if=$DIR/f1 bs=4k count=1 > /dev/null
4935 }
4936 run_test 44A "zero length read from a sparse stripe"
4937
4938 test_44a() {
4939         local nstripe=$($LCTL lov_getconfig $DIR | grep default_stripe_count: |
4940                 awk '{ print $2 }')
4941         [ -z "$nstripe" ] && skip "can't get stripe info"
4942         [[ $nstripe -gt $OSTCOUNT ]] &&
4943                 skip "Wrong default_stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
4944
4945         local stride=$($LCTL lov_getconfig $DIR | grep default_stripe_size: |
4946                 awk '{ print $2 }')
4947         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
4948                 nstripe=$($LCTL lov_getconfig $DIR | grep obd_count: |
4949                         awk '{ print $2 }')
4950         fi
4951
4952         OFFSETS="0 $((stride/2)) $((stride-1))"
4953         for offset in $OFFSETS; do
4954                 for i in $(seq 0 $((nstripe-1))); do
4955                         local GLOBALOFFSETS=""
4956                         # size in Bytes
4957                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
4958                         local myfn=$DIR/d44a-$size
4959                         echo "--------writing $myfn at $size"
4960                         ll_sparseness_write $myfn $size ||
4961                                 error "ll_sparseness_write"
4962                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
4963                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4964                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4965
4966                         for j in $(seq 0 $((nstripe-1))); do
4967                                 # size in Bytes
4968                                 size=$((((j + $nstripe )*$stride + $offset)))
4969                                 ll_sparseness_write $myfn $size ||
4970                                         error "ll_sparseness_write"
4971                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
4972                         done
4973                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4974                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4975                         rm -f $myfn
4976                 done
4977         done
4978 }
4979 run_test 44a "test sparse pwrite ==============================="
4980
4981 dirty_osc_total() {
4982         tot=0
4983         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
4984                 tot=$(($tot + $d))
4985         done
4986         echo $tot
4987 }
4988 do_dirty_record() {
4989         before=`dirty_osc_total`
4990         echo executing "\"$*\""
4991         eval $*
4992         after=`dirty_osc_total`
4993         echo before $before, after $after
4994 }
4995 test_45() {
4996         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4997
4998         f="$DIR/f45"
4999         # Obtain grants from OST if it supports it
5000         echo blah > ${f}_grant
5001         stop_writeback
5002         sync
5003         do_dirty_record "echo blah > $f"
5004         [[ $before -eq $after ]] && error "write wasn't cached"
5005         do_dirty_record "> $f"
5006         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5007         do_dirty_record "echo blah > $f"
5008         [[ $before -eq $after ]] && error "write wasn't cached"
5009         do_dirty_record "sync"
5010         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5011         do_dirty_record "echo blah > $f"
5012         [[ $before -eq $after ]] && error "write wasn't cached"
5013         do_dirty_record "cancel_lru_locks osc"
5014         [[ $before -gt $after ]] ||
5015                 error "lock cancellation didn't lower dirty count"
5016         start_writeback
5017 }
5018 run_test 45 "osc io page accounting ============================"
5019
5020 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5021 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5022 # objects offset and an assert hit when an rpc was built with 1023's mapped
5023 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5024 test_46() {
5025         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5026
5027         f="$DIR/f46"
5028         stop_writeback
5029         sync
5030         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5031         sync
5032         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5033         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5034         sync
5035         start_writeback
5036 }
5037 run_test 46 "dirtying a previously written page ================"
5038
5039 # test_47 is removed "Device nodes check" is moved to test_28
5040
5041 test_48a() { # bug 2399
5042         [ "$mds1_FSTYPE" = "zfs" ] &&
5043         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5044                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5045
5046         test_mkdir $DIR/$tdir
5047         cd $DIR/$tdir
5048         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5049         test_mkdir $DIR/$tdir
5050         touch foo || error "'touch foo' failed after recreating cwd"
5051         test_mkdir bar
5052         touch .foo || error "'touch .foo' failed after recreating cwd"
5053         test_mkdir .bar
5054         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5055         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5056         cd . || error "'cd .' failed after recreating cwd"
5057         mkdir . && error "'mkdir .' worked after recreating cwd"
5058         rmdir . && error "'rmdir .' worked after recreating cwd"
5059         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5060         cd .. || error "'cd ..' failed after recreating cwd"
5061 }
5062 run_test 48a "Access renamed working dir (should return errors)="
5063
5064 test_48b() { # bug 2399
5065         rm -rf $DIR/$tdir
5066         test_mkdir $DIR/$tdir
5067         cd $DIR/$tdir
5068         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5069         touch foo && error "'touch foo' worked after removing cwd"
5070         mkdir foo && error "'mkdir foo' worked after removing cwd"
5071         touch .foo && error "'touch .foo' worked after removing cwd"
5072         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5073         ls . > /dev/null && error "'ls .' worked after removing cwd"
5074         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5075         mkdir . && error "'mkdir .' worked after removing cwd"
5076         rmdir . && error "'rmdir .' worked after removing cwd"
5077         ln -s . foo && error "'ln -s .' worked after removing cwd"
5078         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5079 }
5080 run_test 48b "Access removed working dir (should return errors)="
5081
5082 test_48c() { # bug 2350
5083         #lctl set_param debug=-1
5084         #set -vx
5085         rm -rf $DIR/$tdir
5086         test_mkdir -p $DIR/$tdir/dir
5087         cd $DIR/$tdir/dir
5088         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5089         $TRACE touch foo && error "touch foo worked after removing cwd"
5090         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5091         touch .foo && error "touch .foo worked after removing cwd"
5092         mkdir .foo && error "mkdir .foo worked after removing cwd"
5093         $TRACE ls . && error "'ls .' worked after removing cwd"
5094         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5095         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5096         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5097         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5098         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5099 }
5100 run_test 48c "Access removed working subdir (should return errors)"
5101
5102 test_48d() { # bug 2350
5103         #lctl set_param debug=-1
5104         #set -vx
5105         rm -rf $DIR/$tdir
5106         test_mkdir -p $DIR/$tdir/dir
5107         cd $DIR/$tdir/dir
5108         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5109         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5110         $TRACE touch foo && error "'touch foo' worked after removing parent"
5111         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5112         touch .foo && error "'touch .foo' worked after removing parent"
5113         mkdir .foo && error "mkdir .foo worked after removing parent"
5114         $TRACE ls . && error "'ls .' worked after removing parent"
5115         $TRACE ls .. && error "'ls ..' worked after removing parent"
5116         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5117         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5118         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5119         true
5120 }
5121 run_test 48d "Access removed parent subdir (should return errors)"
5122
5123 test_48e() { # bug 4134
5124         #lctl set_param debug=-1
5125         #set -vx
5126         rm -rf $DIR/$tdir
5127         test_mkdir -p $DIR/$tdir/dir
5128         cd $DIR/$tdir/dir
5129         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5130         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5131         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5132         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5133         # On a buggy kernel addition of "touch foo" after cd .. will
5134         # produce kernel oops in lookup_hash_it
5135         touch ../foo && error "'cd ..' worked after recreate parent"
5136         cd $DIR
5137         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5138 }
5139 run_test 48e "Access to recreated parent subdir (should return errors)"
5140
5141 test_48f() {
5142         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5143                 skip "need MDS >= 2.13.55"
5144         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5145         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5146                 skip "needs different host for mdt1 mdt2"
5147         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5148
5149         $LFS mkdir -i0 $DIR/$tdir
5150         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5151
5152         for d in sub1 sub2 sub3; do
5153                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5154                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5155                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5156         done
5157
5158         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5159 }
5160 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5161
5162 test_49() { # LU-1030
5163         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5164         remote_ost_nodsh && skip "remote OST with nodsh"
5165
5166         # get ost1 size - $FSNAME-OST0000
5167         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5168                 awk '{ print $4 }')
5169         # write 800M at maximum
5170         [[ $ost1_size -lt 2 ]] && ost1_size=2
5171         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5172
5173         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5174         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5175         local dd_pid=$!
5176
5177         # change max_pages_per_rpc while writing the file
5178         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5179         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5180         # loop until dd process exits
5181         while ps ax -opid | grep -wq $dd_pid; do
5182                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5183                 sleep $((RANDOM % 5 + 1))
5184         done
5185         # restore original max_pages_per_rpc
5186         $LCTL set_param $osc1_mppc=$orig_mppc
5187         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5188 }
5189 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5190
5191 test_50() {
5192         # bug 1485
5193         test_mkdir $DIR/$tdir
5194         cd $DIR/$tdir
5195         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5196 }
5197 run_test 50 "special situations: /proc symlinks  ==============="
5198
5199 test_51a() {    # was test_51
5200         # bug 1516 - create an empty entry right after ".." then split dir
5201         test_mkdir -c1 $DIR/$tdir
5202         touch $DIR/$tdir/foo
5203         $MCREATE $DIR/$tdir/bar
5204         rm $DIR/$tdir/foo
5205         createmany -m $DIR/$tdir/longfile 201
5206         FNUM=202
5207         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5208                 $MCREATE $DIR/$tdir/longfile$FNUM
5209                 FNUM=$(($FNUM + 1))
5210                 echo -n "+"
5211         done
5212         echo
5213         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5214 }
5215 run_test 51a "special situations: split htree with empty entry =="
5216
5217 cleanup_print_lfs_df () {
5218         trap 0
5219         $LFS df
5220         $LFS df -i
5221 }
5222
5223 test_51b() {
5224         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5225
5226         local dir=$DIR/$tdir
5227         local nrdirs=$((65536 + 100))
5228
5229         # cleanup the directory
5230         rm -fr $dir
5231
5232         test_mkdir -c1 $dir
5233
5234         $LFS df
5235         $LFS df -i
5236         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5237         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5238         [[ $numfree -lt $nrdirs ]] &&
5239                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5240
5241         # need to check free space for the directories as well
5242         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5243         numfree=$(( blkfree / $(fs_inode_ksize) ))
5244         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5245
5246         trap cleanup_print_lfs_df EXIT
5247
5248         # create files
5249         createmany -d $dir/d $nrdirs || {
5250                 unlinkmany $dir/d $nrdirs
5251                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5252         }
5253
5254         # really created :
5255         nrdirs=$(ls -U $dir | wc -l)
5256
5257         # unlink all but 100 subdirectories, then check it still works
5258         local left=100
5259         local delete=$((nrdirs - left))
5260
5261         $LFS df
5262         $LFS df -i
5263
5264         # for ldiskfs the nlink count should be 1, but this is OSD specific
5265         # and so this is listed for informational purposes only
5266         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5267         unlinkmany -d $dir/d $delete ||
5268                 error "unlink of first $delete subdirs failed"
5269
5270         echo "nlink between: $(stat -c %h $dir)"
5271         local found=$(ls -U $dir | wc -l)
5272         [ $found -ne $left ] &&
5273                 error "can't find subdirs: found only $found, expected $left"
5274
5275         unlinkmany -d $dir/d $delete $left ||
5276                 error "unlink of second $left subdirs failed"
5277         # regardless of whether the backing filesystem tracks nlink accurately
5278         # or not, the nlink count shouldn't be more than "." and ".." here
5279         local after=$(stat -c %h $dir)
5280         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5281                 echo "nlink after: $after"
5282
5283         cleanup_print_lfs_df
5284 }
5285 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5286
5287 test_51d() {
5288         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5289         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5290
5291         test_mkdir $DIR/$tdir
5292         createmany -o $DIR/$tdir/t- 1000
5293         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5294         for N in $(seq 0 $((OSTCOUNT - 1))); do
5295                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
5296                         END { printf("%0.0f", objs) }' $TMP/$tfile)
5297                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5298                         '($1 == '$N') { objs += 1 } \
5299                         END { printf("%0.0f", objs) }')
5300                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
5301         done
5302         unlinkmany $DIR/$tdir/t- 1000
5303
5304         NLAST=0
5305         for N in $(seq 1 $((OSTCOUNT - 1))); do
5306                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
5307                         error "OST $N has less objects vs OST $NLAST" \
5308                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5309                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
5310                         error "OST $N has less objects vs OST $NLAST" \
5311                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5312
5313                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
5314                         error "OST $N has less #0 objects vs OST $NLAST" \
5315                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5316                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
5317                         error "OST $N has less #0 objects vs OST $NLAST" \
5318                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5319                 NLAST=$N
5320         done
5321         rm -f $TMP/$tfile
5322 }
5323 run_test 51d "check object distribution"
5324
5325 test_51e() {
5326         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5327                 skip_env "ldiskfs only test"
5328         fi
5329
5330         test_mkdir -c1 $DIR/$tdir
5331         test_mkdir -c1 $DIR/$tdir/d0
5332
5333         touch $DIR/$tdir/d0/foo
5334         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5335                 error "file exceed 65000 nlink limit!"
5336         unlinkmany $DIR/$tdir/d0/f- 65001
5337         return 0
5338 }
5339 run_test 51e "check file nlink limit"
5340
5341 test_51f() {
5342         test_mkdir $DIR/$tdir
5343
5344         local max=100000
5345         local ulimit_old=$(ulimit -n)
5346         local spare=20 # number of spare fd's for scripts/libraries, etc.
5347         local mdt=$($LFS getstripe -m $DIR/$tdir)
5348         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5349
5350         echo "MDT$mdt numfree=$numfree, max=$max"
5351         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5352         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5353                 while ! ulimit -n $((numfree + spare)); do
5354                         numfree=$((numfree * 3 / 4))
5355                 done
5356                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5357         else
5358                 echo "left ulimit at $ulimit_old"
5359         fi
5360
5361         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5362                 unlinkmany $DIR/$tdir/f $numfree
5363                 error "create+open $numfree files in $DIR/$tdir failed"
5364         }
5365         ulimit -n $ulimit_old
5366
5367         # if createmany exits at 120s there will be fewer than $numfree files
5368         unlinkmany $DIR/$tdir/f $numfree || true
5369 }
5370 run_test 51f "check many open files limit"
5371
5372 test_52a() {
5373         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5374         test_mkdir $DIR/$tdir
5375         touch $DIR/$tdir/foo
5376         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5377         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5378         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5379         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5380         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5381                                         error "link worked"
5382         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5383         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5384         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5385                                                      error "lsattr"
5386         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5387         cp -r $DIR/$tdir $TMP/
5388         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5389 }
5390 run_test 52a "append-only flag test (should return errors)"
5391
5392 test_52b() {
5393         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5394         test_mkdir $DIR/$tdir
5395         touch $DIR/$tdir/foo
5396         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5397         cat test > $DIR/$tdir/foo && error "cat test worked"
5398         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5399         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5400         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5401                                         error "link worked"
5402         echo foo >> $DIR/$tdir/foo && error "echo worked"
5403         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5404         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5405         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5406         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5407                                                         error "lsattr"
5408         chattr -i $DIR/$tdir/foo || error "chattr failed"
5409
5410         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5411 }
5412 run_test 52b "immutable flag test (should return errors) ======="
5413
5414 test_53() {
5415         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5416         remote_mds_nodsh && skip "remote MDS with nodsh"
5417         remote_ost_nodsh && skip "remote OST with nodsh"
5418
5419         local param
5420         local param_seq
5421         local ostname
5422         local mds_last
5423         local mds_last_seq
5424         local ost_last
5425         local ost_last_seq
5426         local ost_last_id
5427         local ostnum
5428         local node
5429         local found=false
5430         local support_last_seq=true
5431
5432         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5433                 support_last_seq=false
5434
5435         # only test MDT0000
5436         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5437         local value
5438         for value in $(do_facet $SINGLEMDS \
5439                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5440                 param=$(echo ${value[0]} | cut -d "=" -f1)
5441                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5442
5443                 if $support_last_seq; then
5444                         param_seq=$(echo $param |
5445                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5446                         mds_last_seq=$(do_facet $SINGLEMDS \
5447                                        $LCTL get_param -n $param_seq)
5448                 fi
5449                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5450
5451                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5452                 node=$(facet_active_host ost$((ostnum+1)))
5453                 param="obdfilter.$ostname.last_id"
5454                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5455                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5456                         ost_last_id=$ost_last
5457
5458                         if $support_last_seq; then
5459                                 ost_last_id=$(echo $ost_last |
5460                                               awk -F':' '{print $2}' |
5461                                               sed -e "s/^0x//g")
5462                                 ost_last_seq=$(echo $ost_last |
5463                                                awk -F':' '{print $1}')
5464                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5465                         fi
5466
5467                         if [[ $ost_last_id != $mds_last ]]; then
5468                                 error "$ost_last_id != $mds_last"
5469                         else
5470                                 found=true
5471                                 break
5472                         fi
5473                 done
5474         done
5475         $found || error "can not match last_seq/last_id for $mdtosc"
5476         return 0
5477 }
5478 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5479
5480 test_54a() {
5481         perl -MSocket -e ';' || skip "no Socket perl module installed"
5482
5483         $SOCKETSERVER $DIR/socket ||
5484                 error "$SOCKETSERVER $DIR/socket failed: $?"
5485         $SOCKETCLIENT $DIR/socket ||
5486                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5487         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5488 }
5489 run_test 54a "unix domain socket test =========================="
5490
5491 test_54b() {
5492         f="$DIR/f54b"
5493         mknod $f c 1 3
5494         chmod 0666 $f
5495         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5496 }
5497 run_test 54b "char device works in lustre ======================"
5498
5499 find_loop_dev() {
5500         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5501         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5502         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5503
5504         for i in $(seq 3 7); do
5505                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5506                 LOOPDEV=$LOOPBASE$i
5507                 LOOPNUM=$i
5508                 break
5509         done
5510 }
5511
5512 cleanup_54c() {
5513         local rc=0
5514         loopdev="$DIR/loop54c"
5515
5516         trap 0
5517         $UMOUNT $DIR/$tdir || rc=$?
5518         losetup -d $loopdev || true
5519         losetup -d $LOOPDEV || true
5520         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5521         return $rc
5522 }
5523
5524 test_54c() {
5525         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5526
5527         loopdev="$DIR/loop54c"
5528
5529         find_loop_dev
5530         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5531         trap cleanup_54c EXIT
5532         mknod $loopdev b 7 $LOOPNUM
5533         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5534         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5535         losetup $loopdev $DIR/$tfile ||
5536                 error "can't set up $loopdev for $DIR/$tfile"
5537         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5538         test_mkdir $DIR/$tdir
5539         mount -t ext2 $loopdev $DIR/$tdir ||
5540                 error "error mounting $loopdev on $DIR/$tdir"
5541         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5542                 error "dd write"
5543         df $DIR/$tdir
5544         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5545                 error "dd read"
5546         cleanup_54c
5547 }
5548 run_test 54c "block device works in lustre ====================="
5549
5550 test_54d() {
5551         f="$DIR/f54d"
5552         string="aaaaaa"
5553         mknod $f p
5554         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5555 }
5556 run_test 54d "fifo device works in lustre ======================"
5557
5558 test_54e() {
5559         f="$DIR/f54e"
5560         string="aaaaaa"
5561         cp -aL /dev/console $f
5562         echo $string > $f || error "echo $string to $f failed"
5563 }
5564 run_test 54e "console/tty device works in lustre ======================"
5565
5566 test_56a() {
5567         local numfiles=3
5568         local dir=$DIR/$tdir
5569
5570         rm -rf $dir
5571         test_mkdir -p $dir/dir
5572         for i in $(seq $numfiles); do
5573                 touch $dir/file$i
5574                 touch $dir/dir/file$i
5575         done
5576
5577         local numcomp=$($LFS getstripe --component-count $dir)
5578
5579         [[ $numcomp == 0 ]] && numcomp=1
5580
5581         # test lfs getstripe with --recursive
5582         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5583
5584         [[ $filenum -eq $((numfiles * 2)) ]] ||
5585                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5586         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5587         [[ $filenum -eq $numfiles ]] ||
5588                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5589         echo "$LFS getstripe showed obdidx or l_ost_idx"
5590
5591         # test lfs getstripe with file instead of dir
5592         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5593         [[ $filenum -eq 1 ]] ||
5594                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5595         echo "$LFS getstripe file1 passed"
5596
5597         #test lfs getstripe with --verbose
5598         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5599         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5600                 error "$LFS getstripe --verbose $dir: "\
5601                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5602         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5603                 error "$LFS getstripe $dir: showed lmm_magic"
5604
5605         #test lfs getstripe with -v prints lmm_fid
5606         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5607         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5608                 error "$LFS getstripe -v $dir: "\
5609                       "got $filenum want $((numfiles * numcomp)) lmm_fid"
5610         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5611                 error "$LFS getstripe $dir: showed lmm_fid by default"
5612         echo "$LFS getstripe --verbose passed"
5613
5614         #check for FID information
5615         local fid1=$($LFS getstripe --fid $dir/file1)
5616         local fid2=$($LFS getstripe --verbose $dir/file1 |
5617                      awk '/lmm_fid: / { print $2; exit; }')
5618         local fid3=$($LFS path2fid $dir/file1)
5619
5620         [ "$fid1" != "$fid2" ] &&
5621                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5622         [ "$fid1" != "$fid3" ] &&
5623                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5624         echo "$LFS getstripe --fid passed"
5625
5626         #test lfs getstripe with --obd
5627         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
5628                 error "$LFS getstripe --obd wrong_uuid: should return error"
5629
5630         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5631
5632         local ostidx=1
5633         local obduuid=$(ostuuid_from_index $ostidx)
5634         local found=$($LFS getstripe -r --obd $obduuid $dir |
5635                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
5636
5637         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
5638         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
5639                 ((filenum--))
5640         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
5641                 ((filenum--))
5642
5643         [[ $found -eq $filenum ]] ||
5644                 error "$LFS getstripe --obd: found $found expect $filenum"
5645         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
5646                 sed '/^[         ]*'${ostidx}'[  ]/d' |
5647                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
5648                 error "$LFS getstripe --obd: should not show file on other obd"
5649         echo "$LFS getstripe --obd passed"
5650 }
5651 run_test 56a "check $LFS getstripe"
5652
5653 test_56b() {
5654         local dir=$DIR/$tdir
5655         local numdirs=3
5656
5657         test_mkdir $dir
5658         for i in $(seq $numdirs); do
5659                 test_mkdir $dir/dir$i
5660         done
5661
5662         # test lfs getdirstripe default mode is non-recursion, which is
5663         # different from lfs getstripe
5664         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
5665
5666         [[ $dircnt -eq 1 ]] ||
5667                 error "$LFS getdirstripe: found $dircnt, not 1"
5668         dircnt=$($LFS getdirstripe --recursive $dir |
5669                 grep -c lmv_stripe_count)
5670         [[ $dircnt -eq $((numdirs + 1)) ]] ||
5671                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
5672 }
5673 run_test 56b "check $LFS getdirstripe"
5674
5675 test_56c() {
5676         remote_ost_nodsh && skip "remote OST with nodsh"
5677
5678         local ost_idx=0
5679         local ost_name=$(ostname_from_index $ost_idx)
5680         local old_status=$(ost_dev_status $ost_idx)
5681         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
5682
5683         [[ -z "$old_status" ]] ||
5684                 skip_env "OST $ost_name is in $old_status status"
5685
5686         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
5687         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
5688                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
5689         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
5690                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
5691                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
5692         fi
5693
5694         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
5695                 error "$LFS df -v showing inactive devices"
5696         sleep_maxage
5697
5698         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
5699
5700         [[ "$new_status" =~ "D" ]] ||
5701                 error "$ost_name status is '$new_status', missing 'D'"
5702         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
5703                 [[ "$new_status" =~ "N" ]] ||
5704                         error "$ost_name status is '$new_status', missing 'N'"
5705         fi
5706         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
5707                 [[ "$new_status" =~ "f" ]] ||
5708                         error "$ost_name status is '$new_status', missing 'f'"
5709         fi
5710
5711         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
5712         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
5713                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
5714         [[ -z "$p" ]] && restore_lustre_params < $p || true
5715         sleep_maxage
5716
5717         new_status=$(ost_dev_status $ost_idx)
5718         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
5719                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
5720         # can't check 'f' as devices may actually be on flash
5721 }
5722 run_test 56c "check 'lfs df' showing device status"
5723
5724 test_56d() {
5725         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
5726         local osts=$($LFS df -v $MOUNT | grep -c OST)
5727
5728         $LFS df $MOUNT
5729
5730         (( mdts == MDSCOUNT )) ||
5731                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
5732         (( osts == OSTCOUNT )) ||
5733                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
5734 }
5735 run_test 56d "'lfs df -v' prints only configured devices"
5736
5737 NUMFILES=3
5738 NUMDIRS=3
5739 setup_56() {
5740         local local_tdir="$1"
5741         local local_numfiles="$2"
5742         local local_numdirs="$3"
5743         local dir_params="$4"
5744         local dir_stripe_params="$5"
5745
5746         if [ ! -d "$local_tdir" ] ; then
5747                 test_mkdir -p $dir_stripe_params $local_tdir
5748                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
5749                 for i in $(seq $local_numfiles) ; do
5750                         touch $local_tdir/file$i
5751                 done
5752                 for i in $(seq $local_numdirs) ; do
5753                         test_mkdir $dir_stripe_params $local_tdir/dir$i
5754                         for j in $(seq $local_numfiles) ; do
5755                                 touch $local_tdir/dir$i/file$j
5756                         done
5757                 done
5758         fi
5759 }
5760
5761 setup_56_special() {
5762         local local_tdir=$1
5763         local local_numfiles=$2
5764         local local_numdirs=$3
5765
5766         setup_56 $local_tdir $local_numfiles $local_numdirs
5767
5768         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
5769                 for i in $(seq $local_numfiles) ; do
5770                         mknod $local_tdir/loop${i}b b 7 $i
5771                         mknod $local_tdir/null${i}c c 1 3
5772                         ln -s $local_tdir/file1 $local_tdir/link${i}
5773                 done
5774                 for i in $(seq $local_numdirs) ; do
5775                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
5776                         mknod $local_tdir/dir$i/null${i}c c 1 3
5777                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
5778                 done
5779         fi
5780 }
5781
5782 test_56g() {
5783         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5784         local expected=$(($NUMDIRS + 2))
5785
5786         setup_56 $dir $NUMFILES $NUMDIRS
5787
5788         # test lfs find with -name
5789         for i in $(seq $NUMFILES) ; do
5790                 local nums=$($LFS find -name "*$i" $dir | wc -l)
5791
5792                 [ $nums -eq $expected ] ||
5793                         error "lfs find -name '*$i' $dir wrong: "\
5794                               "found $nums, expected $expected"
5795         done
5796 }
5797 run_test 56g "check lfs find -name"
5798
5799 test_56h() {
5800         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5801         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
5802
5803         setup_56 $dir $NUMFILES $NUMDIRS
5804
5805         # test lfs find with ! -name
5806         for i in $(seq $NUMFILES) ; do
5807                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
5808
5809                 [ $nums -eq $expected ] ||
5810                         error "lfs find ! -name '*$i' $dir wrong: "\
5811                               "found $nums, expected $expected"
5812         done
5813 }
5814 run_test 56h "check lfs find ! -name"
5815
5816 test_56i() {
5817         local dir=$DIR/$tdir
5818
5819         test_mkdir $dir
5820
5821         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
5822         local out=$($cmd)
5823
5824         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
5825 }
5826 run_test 56i "check 'lfs find -ost UUID' skips directories"
5827
5828 test_56j() {
5829         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5830
5831         setup_56_special $dir $NUMFILES $NUMDIRS
5832
5833         local expected=$((NUMDIRS + 1))
5834         local cmd="$LFS find -type d $dir"
5835         local nums=$($cmd | wc -l)
5836
5837         [ $nums -eq $expected ] ||
5838                 error "'$cmd' wrong: found $nums, expected $expected"
5839 }
5840 run_test 56j "check lfs find -type d"
5841
5842 test_56k() {
5843         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5844
5845         setup_56_special $dir $NUMFILES $NUMDIRS
5846
5847         local expected=$(((NUMDIRS + 1) * NUMFILES))
5848         local cmd="$LFS find -type f $dir"
5849         local nums=$($cmd | wc -l)
5850
5851         [ $nums -eq $expected ] ||
5852                 error "'$cmd' wrong: found $nums, expected $expected"
5853 }
5854 run_test 56k "check lfs find -type f"
5855
5856 test_56l() {
5857         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5858
5859         setup_56_special $dir $NUMFILES $NUMDIRS
5860
5861         local expected=$((NUMDIRS + NUMFILES))
5862         local cmd="$LFS find -type b $dir"
5863         local nums=$($cmd | wc -l)
5864
5865         [ $nums -eq $expected ] ||
5866                 error "'$cmd' wrong: found $nums, expected $expected"
5867 }
5868 run_test 56l "check lfs find -type b"
5869
5870 test_56m() {
5871         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5872
5873         setup_56_special $dir $NUMFILES $NUMDIRS
5874
5875         local expected=$((NUMDIRS + NUMFILES))
5876         local cmd="$LFS find -type c $dir"
5877         local nums=$($cmd | wc -l)
5878         [ $nums -eq $expected ] ||
5879                 error "'$cmd' wrong: found $nums, expected $expected"
5880 }
5881 run_test 56m "check lfs find -type c"
5882
5883 test_56n() {
5884         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5885         setup_56_special $dir $NUMFILES $NUMDIRS
5886
5887         local expected=$((NUMDIRS + NUMFILES))
5888         local cmd="$LFS find -type l $dir"
5889         local nums=$($cmd | wc -l)
5890
5891         [ $nums -eq $expected ] ||
5892                 error "'$cmd' wrong: found $nums, expected $expected"
5893 }
5894 run_test 56n "check lfs find -type l"
5895
5896 test_56o() {
5897         local dir=$DIR/$tdir
5898
5899         setup_56 $dir $NUMFILES $NUMDIRS
5900         utime $dir/file1 > /dev/null || error "utime (1)"
5901         utime $dir/file2 > /dev/null || error "utime (2)"
5902         utime $dir/dir1 > /dev/null || error "utime (3)"
5903         utime $dir/dir2 > /dev/null || error "utime (4)"
5904         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
5905         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
5906
5907         local expected=4
5908         local nums=$($LFS find -mtime +0 $dir | wc -l)
5909
5910         [ $nums -eq $expected ] ||
5911                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
5912
5913         expected=12
5914         cmd="$LFS find -mtime 0 $dir"
5915         nums=$($cmd | wc -l)
5916         [ $nums -eq $expected ] ||
5917                 error "'$cmd' wrong: found $nums, expected $expected"
5918 }
5919 run_test 56o "check lfs find -mtime for old files"
5920
5921 test_56ob() {
5922         local dir=$DIR/$tdir
5923         local expected=1
5924         local count=0
5925
5926         # just to make sure there is something that won't be found
5927         test_mkdir $dir
5928         touch $dir/$tfile.now
5929
5930         for age in year week day hour min; do
5931                 count=$((count + 1))
5932
5933                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
5934                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
5935                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
5936
5937                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
5938                 local nums=$($cmd | wc -l)
5939                 [ $nums -eq $expected ] ||
5940                         error "'$cmd' wrong: found $nums, expected $expected"
5941
5942                 cmd="$LFS find $dir -atime $count${age:0:1}"
5943                 nums=$($cmd | wc -l)
5944                 [ $nums -eq $expected ] ||
5945                         error "'$cmd' wrong: found $nums, expected $expected"
5946         done
5947
5948         sleep 2
5949         cmd="$LFS find $dir -ctime +1s -type f"
5950         nums=$($cmd | wc -l)
5951         (( $nums == $count * 2 + 1)) ||
5952                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
5953 }
5954 run_test 56ob "check lfs find -atime -mtime -ctime with units"
5955
5956 test_newerXY_base() {
5957         local x=$1
5958         local y=$2
5959         local dir=$DIR/$tdir
5960         local ref
5961         local negref
5962
5963         if [ $y == "t" ]; then
5964                 if [ $x == "b" ]; then
5965                         ref="\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\""
5966                 else
5967                         ref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
5968                 fi
5969         else
5970                 ref=$DIR/$tfile.newer.$x$y
5971                 touch $ref || error "touch $ref failed"
5972         fi
5973         sleep 2
5974         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
5975         sleep 2
5976         if [ $y == "t" ]; then
5977                 if [ $x == "b" ]; then
5978                         negref="\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\""
5979                 else
5980                         negref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
5981                 fi
5982         else
5983                 negref=$DIR/$tfile.negnewer.$x$y
5984                 touch $negref || error "touch $negref failed"
5985         fi
5986
5987         local cmd="$LFS find $dir -newer$x$y $ref"
5988         local nums=$(eval $cmd | wc -l)
5989         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
5990
5991         [ $nums -eq $expected ] ||
5992                 error "'$cmd' wrong: found $nums, expected $expected"
5993
5994         cmd="$LFS find $dir ! -newer$x$y $negref"
5995         nums=$(eval $cmd | wc -l)
5996         [ $nums -eq $expected ] ||
5997                 error "'$cmd' wrong: found $nums, expected $expected"
5998
5999         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6000         nums=$(eval $cmd | wc -l)
6001         [ $nums -eq $expected ] ||
6002                 error "'$cmd' wrong: found $nums, expected $expected"
6003
6004         rm -rf $DIR/*
6005 }
6006
6007 test_56oc() {
6008         test_newerXY_base "b" "t"
6009         test_newerXY_base "a" "a"
6010         test_newerXY_base "a" "m"
6011         test_newerXY_base "a" "c"
6012         test_newerXY_base "m" "a"
6013         test_newerXY_base "m" "m"
6014         test_newerXY_base "m" "c"
6015         test_newerXY_base "c" "a"
6016         test_newerXY_base "c" "m"
6017         test_newerXY_base "c" "c"
6018         test_newerXY_base "b" "b"
6019         test_newerXY_base "a" "t"
6020         test_newerXY_base "m" "t"
6021         test_newerXY_base "c" "t"
6022         test_newerXY_base "b" "t"
6023 }
6024 run_test 56oc "check lfs find -newerXY work"
6025
6026 btime_supported() {
6027         local dir=$DIR/$tdir
6028         local rc
6029
6030         mkdir -p $dir
6031         touch $dir/$tfile
6032         $LFS find $dir -btime -1d -type f
6033         rc=$?
6034         rm -rf $dir
6035         return $rc
6036 }
6037
6038 test_56od() {
6039         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6040                 ! btime_supported && skip "btime unsupported on MDS"
6041
6042         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6043                 ! btime_supported && skip "btime unsupported on clients"
6044
6045         local dir=$DIR/$tdir
6046         local ref=$DIR/$tfile.ref
6047         local negref=$DIR/$tfile.negref
6048
6049         mkdir $dir || error "mkdir $dir failed"
6050         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6051         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6052         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6053         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6054         touch $ref || error "touch $ref failed"
6055         # sleep 3 seconds at least
6056         sleep 3
6057
6058         local before=$(do_facet mds1 date +%s)
6059         local skew=$(($(date +%s) - before + 1))
6060
6061         if (( skew < 0 && skew > -5 )); then
6062                 sleep $((0 - skew + 1))
6063                 skew=0
6064         fi
6065
6066         # Set the dir stripe params to limit files all on MDT0,
6067         # otherwise we need to calc the max clock skew between
6068         # the client and MDTs.
6069         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6070         sleep 2
6071         touch $negref || error "touch $negref failed"
6072
6073         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6074         local nums=$($cmd | wc -l)
6075         local expected=$(((NUMFILES + 1) * NUMDIRS))
6076
6077         [ $nums -eq $expected ] ||
6078                 error "'$cmd' wrong: found $nums, expected $expected"
6079
6080         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6081         nums=$($cmd | wc -l)
6082         expected=$((NUMFILES + 1))
6083         [ $nums -eq $expected ] ||
6084                 error "'$cmd' wrong: found $nums, expected $expected"
6085
6086         [ $skew -lt 0 ] && return
6087
6088         local after=$(do_facet mds1 date +%s)
6089         local age=$((after - before + 1 + skew))
6090
6091         cmd="$LFS find $dir -btime -${age}s -type f"
6092         nums=$($cmd | wc -l)
6093         expected=$(((NUMFILES + 1) * NUMDIRS))
6094
6095         echo "Clock skew between client and server: $skew, age:$age"
6096         [ $nums -eq $expected ] ||
6097                 error "'$cmd' wrong: found $nums, expected $expected"
6098
6099         expected=$(($NUMDIRS + 1))
6100         cmd="$LFS find $dir -btime -${age}s -type d"
6101         nums=$($cmd | wc -l)
6102         [ $nums -eq $expected ] ||
6103                 error "'$cmd' wrong: found $nums, expected $expected"
6104         rm -f $ref $negref || error "Failed to remove $ref $negref"
6105 }
6106 run_test 56od "check lfs find -btime with units"
6107
6108 test_56p() {
6109         [ $RUNAS_ID -eq $UID ] &&
6110                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6111
6112         local dir=$DIR/$tdir
6113
6114         setup_56 $dir $NUMFILES $NUMDIRS
6115         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6116
6117         local expected=$NUMFILES
6118         local cmd="$LFS find -uid $RUNAS_ID $dir"
6119         local nums=$($cmd | wc -l)
6120
6121         [ $nums -eq $expected ] ||
6122                 error "'$cmd' wrong: found $nums, expected $expected"
6123
6124         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6125         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6126         nums=$($cmd | wc -l)
6127         [ $nums -eq $expected ] ||
6128                 error "'$cmd' wrong: found $nums, expected $expected"
6129 }
6130 run_test 56p "check lfs find -uid and ! -uid"
6131
6132 test_56q() {
6133         [ $RUNAS_ID -eq $UID ] &&
6134                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6135
6136         local dir=$DIR/$tdir
6137
6138         setup_56 $dir $NUMFILES $NUMDIRS
6139         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6140
6141         local expected=$NUMFILES
6142         local cmd="$LFS find -gid $RUNAS_GID $dir"
6143         local nums=$($cmd | wc -l)
6144
6145         [ $nums -eq $expected ] ||
6146                 error "'$cmd' wrong: found $nums, expected $expected"
6147
6148         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6149         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6150         nums=$($cmd | wc -l)
6151         [ $nums -eq $expected ] ||
6152                 error "'$cmd' wrong: found $nums, expected $expected"
6153 }
6154 run_test 56q "check lfs find -gid and ! -gid"
6155
6156 test_56r() {
6157         local dir=$DIR/$tdir
6158
6159         setup_56 $dir $NUMFILES $NUMDIRS
6160
6161         local expected=12
6162         local cmd="$LFS find -size 0 -type f -lazy $dir"
6163         local nums=$($cmd | wc -l)
6164
6165         [ $nums -eq $expected ] ||
6166                 error "'$cmd' wrong: found $nums, expected $expected"
6167         cmd="$LFS find -size 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         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6174         nums=$($cmd | wc -l)
6175         [ $nums -eq $expected ] ||
6176                 error "'$cmd' wrong: found $nums, expected $expected"
6177         cmd="$LFS find ! -size 0 -type f $dir"
6178         nums=$($cmd | wc -l)
6179         [ $nums -eq $expected ] ||
6180                 error "'$cmd' wrong: found $nums, expected $expected"
6181
6182         echo "test" > $dir/$tfile
6183         echo "test2" > $dir/$tfile.2 && sync
6184         expected=1
6185         cmd="$LFS find -size 5 -type f -lazy $dir"
6186         nums=$($cmd | wc -l)
6187         [ $nums -eq $expected ] ||
6188                 error "'$cmd' wrong: found $nums, expected $expected"
6189         cmd="$LFS find -size 5 -type f $dir"
6190         nums=$($cmd | wc -l)
6191         [ $nums -eq $expected ] ||
6192                 error "'$cmd' wrong: found $nums, expected $expected"
6193
6194         expected=1
6195         cmd="$LFS find -size +5 -type f -lazy $dir"
6196         nums=$($cmd | wc -l)
6197         [ $nums -eq $expected ] ||
6198                 error "'$cmd' wrong: found $nums, expected $expected"
6199         cmd="$LFS find -size +5 -type f $dir"
6200         nums=$($cmd | wc -l)
6201         [ $nums -eq $expected ] ||
6202                 error "'$cmd' wrong: found $nums, expected $expected"
6203
6204         expected=2
6205         cmd="$LFS find -size +0 -type f -lazy $dir"
6206         nums=$($cmd | wc -l)
6207         [ $nums -eq $expected ] ||
6208                 error "'$cmd' wrong: found $nums, expected $expected"
6209         cmd="$LFS find -size +0 -type f $dir"
6210         nums=$($cmd | wc -l)
6211         [ $nums -eq $expected ] ||
6212                 error "'$cmd' wrong: found $nums, expected $expected"
6213
6214         expected=2
6215         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6216         nums=$($cmd | wc -l)
6217         [ $nums -eq $expected ] ||
6218                 error "'$cmd' wrong: found $nums, expected $expected"
6219         cmd="$LFS find ! -size -5 -type f $dir"
6220         nums=$($cmd | wc -l)
6221         [ $nums -eq $expected ] ||
6222                 error "'$cmd' wrong: found $nums, expected $expected"
6223
6224         expected=12
6225         cmd="$LFS find -size -5 -type f -lazy $dir"
6226         nums=$($cmd | wc -l)
6227         [ $nums -eq $expected ] ||
6228                 error "'$cmd' wrong: found $nums, expected $expected"
6229         cmd="$LFS find -size -5 -type f $dir"
6230         nums=$($cmd | wc -l)
6231         [ $nums -eq $expected ] ||
6232                 error "'$cmd' wrong: found $nums, expected $expected"
6233 }
6234 run_test 56r "check lfs find -size works"
6235
6236 test_56ra_sub() {
6237         local expected=$1
6238         local glimpses=$2
6239         local cmd="$3"
6240
6241         cancel_lru_locks $OSC
6242
6243         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6244         local nums=$($cmd | wc -l)
6245
6246         [ $nums -eq $expected ] ||
6247                 error "'$cmd' wrong: found $nums, expected $expected"
6248
6249         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6250
6251         if (( rpcs_before + glimpses != rpcs_after )); then
6252                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6253                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6254
6255                 if [[ $glimpses == 0 ]]; then
6256                         error "'$cmd' should not send glimpse RPCs to OST"
6257                 else
6258                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6259                 fi
6260         fi
6261 }
6262
6263 test_56ra() {
6264         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6265                 skip "MDS < 2.12.58 doesn't return LSOM data"
6266         local dir=$DIR/$tdir
6267         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6268
6269         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6270
6271         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6272         $LCTL set_param -n llite.*.statahead_agl=0
6273         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6274
6275         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6276         # open and close all files to ensure LSOM is updated
6277         cancel_lru_locks $OSC
6278         find $dir -type f | xargs cat > /dev/null
6279
6280         #   expect_found  glimpse_rpcs  command_to_run
6281         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6282         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6283         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6284         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6285
6286         echo "test" > $dir/$tfile
6287         echo "test2" > $dir/$tfile.2 && sync
6288         cancel_lru_locks $OSC
6289         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6290
6291         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6292         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6293         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6294         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6295
6296         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6297         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6298         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6299         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6300         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6301         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6302 }
6303 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6304
6305 test_56rb() {
6306         local dir=$DIR/$tdir
6307         local tmp=$TMP/$tfile.log
6308         local mdt_idx;
6309
6310         test_mkdir -p $dir || error "failed to mkdir $dir"
6311         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6312                 error "failed to setstripe $dir/$tfile"
6313         mdt_idx=$($LFS getdirstripe -i $dir)
6314         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6315
6316         stack_trap "rm -f $tmp" EXIT
6317         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6318         ! grep -q obd_uuid $tmp ||
6319                 error "failed to find --size +100K --ost 0 $dir"
6320         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6321         ! grep -q obd_uuid $tmp ||
6322                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6323 }
6324 run_test 56rb "check lfs find --size --ost/--mdt works"
6325
6326 test_56s() { # LU-611 #LU-9369
6327         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6328
6329         local dir=$DIR/$tdir
6330         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6331
6332         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6333         for i in $(seq $NUMDIRS); do
6334                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6335         done
6336
6337         local expected=$NUMDIRS
6338         local cmd="$LFS find -c $OSTCOUNT $dir"
6339         local nums=$($cmd | wc -l)
6340
6341         [ $nums -eq $expected ] || {
6342                 $LFS getstripe -R $dir
6343                 error "'$cmd' wrong: found $nums, expected $expected"
6344         }
6345
6346         expected=$((NUMDIRS + onestripe))
6347         cmd="$LFS find -stripe-count +0 -type f $dir"
6348         nums=$($cmd | wc -l)
6349         [ $nums -eq $expected ] || {
6350                 $LFS getstripe -R $dir
6351                 error "'$cmd' wrong: found $nums, expected $expected"
6352         }
6353
6354         expected=$onestripe
6355         cmd="$LFS find -stripe-count 1 -type f $dir"
6356         nums=$($cmd | wc -l)
6357         [ $nums -eq $expected ] || {
6358                 $LFS getstripe -R $dir
6359                 error "'$cmd' wrong: found $nums, expected $expected"
6360         }
6361
6362         cmd="$LFS find -stripe-count -2 -type f $dir"
6363         nums=$($cmd | wc -l)
6364         [ $nums -eq $expected ] || {
6365                 $LFS getstripe -R $dir
6366                 error "'$cmd' wrong: found $nums, expected $expected"
6367         }
6368
6369         expected=0
6370         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6371         nums=$($cmd | wc -l)
6372         [ $nums -eq $expected ] || {
6373                 $LFS getstripe -R $dir
6374                 error "'$cmd' wrong: found $nums, expected $expected"
6375         }
6376 }
6377 run_test 56s "check lfs find -stripe-count works"
6378
6379 test_56t() { # LU-611 #LU-9369
6380         local dir=$DIR/$tdir
6381
6382         setup_56 $dir 0 $NUMDIRS
6383         for i in $(seq $NUMDIRS); do
6384                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6385         done
6386
6387         local expected=$NUMDIRS
6388         local cmd="$LFS find -S 8M $dir"
6389         local nums=$($cmd | wc -l)
6390
6391         [ $nums -eq $expected ] || {
6392                 $LFS getstripe -R $dir
6393                 error "'$cmd' wrong: found $nums, expected $expected"
6394         }
6395         rm -rf $dir
6396
6397         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6398
6399         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6400
6401         expected=$(((NUMDIRS + 1) * NUMFILES))
6402         cmd="$LFS find -stripe-size 512k -type f $dir"
6403         nums=$($cmd | wc -l)
6404         [ $nums -eq $expected ] ||
6405                 error "'$cmd' wrong: found $nums, expected $expected"
6406
6407         cmd="$LFS find -stripe-size +320k -type f $dir"
6408         nums=$($cmd | wc -l)
6409         [ $nums -eq $expected ] ||
6410                 error "'$cmd' wrong: found $nums, expected $expected"
6411
6412         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6413         cmd="$LFS find -stripe-size +200k -type f $dir"
6414         nums=$($cmd | wc -l)
6415         [ $nums -eq $expected ] ||
6416                 error "'$cmd' wrong: found $nums, expected $expected"
6417
6418         cmd="$LFS find -stripe-size -640k -type f $dir"
6419         nums=$($cmd | wc -l)
6420         [ $nums -eq $expected ] ||
6421                 error "'$cmd' wrong: found $nums, expected $expected"
6422
6423         expected=4
6424         cmd="$LFS find -stripe-size 256k -type f $dir"
6425         nums=$($cmd | wc -l)
6426         [ $nums -eq $expected ] ||
6427                 error "'$cmd' wrong: found $nums, expected $expected"
6428
6429         cmd="$LFS find -stripe-size -320k -type f $dir"
6430         nums=$($cmd | wc -l)
6431         [ $nums -eq $expected ] ||
6432                 error "'$cmd' wrong: found $nums, expected $expected"
6433
6434         expected=0
6435         cmd="$LFS find -stripe-size 1024k -type f $dir"
6436         nums=$($cmd | wc -l)
6437         [ $nums -eq $expected ] ||
6438                 error "'$cmd' wrong: found $nums, expected $expected"
6439 }
6440 run_test 56t "check lfs find -stripe-size works"
6441
6442 test_56u() { # LU-611
6443         local dir=$DIR/$tdir
6444
6445         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6446
6447         if [[ $OSTCOUNT -gt 1 ]]; then
6448                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6449                 onestripe=4
6450         else
6451                 onestripe=0
6452         fi
6453
6454         local expected=$(((NUMDIRS + 1) * NUMFILES))
6455         local cmd="$LFS find -stripe-index 0 -type f $dir"
6456         local nums=$($cmd | wc -l)
6457
6458         [ $nums -eq $expected ] ||
6459                 error "'$cmd' wrong: found $nums, expected $expected"
6460
6461         expected=$onestripe
6462         cmd="$LFS find -stripe-index 1 -type f $dir"
6463         nums=$($cmd | wc -l)
6464         [ $nums -eq $expected ] ||
6465                 error "'$cmd' wrong: found $nums, expected $expected"
6466
6467         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6468         nums=$($cmd | wc -l)
6469         [ $nums -eq $expected ] ||
6470                 error "'$cmd' wrong: found $nums, expected $expected"
6471
6472         expected=0
6473         # This should produce an error and not return any files
6474         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
6475         nums=$($cmd 2>/dev/null | wc -l)
6476         [ $nums -eq $expected ] ||
6477                 error "'$cmd' wrong: found $nums, expected $expected"
6478
6479         if [[ $OSTCOUNT -gt 1 ]]; then
6480                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
6481                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
6482                 nums=$($cmd | wc -l)
6483                 [ $nums -eq $expected ] ||
6484                         error "'$cmd' wrong: found $nums, expected $expected"
6485         fi
6486 }
6487 run_test 56u "check lfs find -stripe-index works"
6488
6489 test_56v() {
6490         local mdt_idx=0
6491         local dir=$DIR/$tdir
6492
6493         setup_56 $dir $NUMFILES $NUMDIRS
6494
6495         UUID=$(mdtuuid_from_index $mdt_idx $dir)
6496         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
6497
6498         for file in $($LFS find -m $UUID $dir); do
6499                 file_midx=$($LFS getstripe -m $file)
6500                 [ $file_midx -eq $mdt_idx ] ||
6501                         error "lfs find -m $UUID != getstripe -m $file_midx"
6502         done
6503 }
6504 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
6505
6506 test_56w() {
6507         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6508         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6509
6510         local dir=$DIR/$tdir
6511
6512         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
6513
6514         local stripe_size=$($LFS getstripe -S -d $dir) ||
6515                 error "$LFS getstripe -S -d $dir failed"
6516         stripe_size=${stripe_size%% *}
6517
6518         local file_size=$((stripe_size * OSTCOUNT))
6519         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
6520         local required_space=$((file_num * file_size))
6521         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
6522                            head -n1)
6523         [[ $free_space -le $((required_space / 1024)) ]] &&
6524                 skip_env "need $required_space, have $free_space kbytes"
6525
6526         local dd_bs=65536
6527         local dd_count=$((file_size / dd_bs))
6528
6529         # write data into the files
6530         local i
6531         local j
6532         local file
6533
6534         for i in $(seq $NUMFILES); do
6535                 file=$dir/file$i
6536                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6537                         error "write data into $file failed"
6538         done
6539         for i in $(seq $NUMDIRS); do
6540                 for j in $(seq $NUMFILES); do
6541                         file=$dir/dir$i/file$j
6542                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6543                                 error "write data into $file failed"
6544                 done
6545         done
6546
6547         # $LFS_MIGRATE will fail if hard link migration is unsupported
6548         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
6549                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
6550                         error "creating links to $dir/dir1/file1 failed"
6551         fi
6552
6553         local expected=-1
6554
6555         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
6556
6557         # lfs_migrate file
6558         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
6559
6560         echo "$cmd"
6561         eval $cmd || error "$cmd failed"
6562
6563         check_stripe_count $dir/file1 $expected
6564
6565         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
6566         then
6567                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
6568                 # OST 1 if it is on OST 0. This file is small enough to
6569                 # be on only one stripe.
6570                 file=$dir/migr_1_ost
6571                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
6572                         error "write data into $file failed"
6573                 local obdidx=$($LFS getstripe -i $file)
6574                 local oldmd5=$(md5sum $file)
6575                 local newobdidx=0
6576
6577                 [[ $obdidx -eq 0 ]] && newobdidx=1
6578                 cmd="$LFS migrate -i $newobdidx $file"
6579                 echo $cmd
6580                 eval $cmd || error "$cmd failed"
6581
6582                 local realobdix=$($LFS getstripe -i $file)
6583                 local newmd5=$(md5sum $file)
6584
6585                 [[ $newobdidx -ne $realobdix ]] &&
6586                         error "new OST is different (was=$obdidx, "\
6587                               "wanted=$newobdidx, got=$realobdix)"
6588                 [[ "$oldmd5" != "$newmd5" ]] &&
6589                         error "md5sum differ: $oldmd5, $newmd5"
6590         fi
6591
6592         # lfs_migrate dir
6593         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
6594         echo "$cmd"
6595         eval $cmd || error "$cmd failed"
6596
6597         for j in $(seq $NUMFILES); do
6598                 check_stripe_count $dir/dir1/file$j $expected
6599         done
6600
6601         # lfs_migrate works with lfs find
6602         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
6603              $LFS_MIGRATE -y -c $expected"
6604         echo "$cmd"
6605         eval $cmd || error "$cmd failed"
6606
6607         for i in $(seq 2 $NUMFILES); do
6608                 check_stripe_count $dir/file$i $expected
6609         done
6610         for i in $(seq 2 $NUMDIRS); do
6611                 for j in $(seq $NUMFILES); do
6612                 check_stripe_count $dir/dir$i/file$j $expected
6613                 done
6614         done
6615 }
6616 run_test 56w "check lfs_migrate -c stripe_count works"
6617
6618 test_56wb() {
6619         local file1=$DIR/$tdir/file1
6620         local create_pool=false
6621         local initial_pool=$($LFS getstripe -p $DIR)
6622         local pool_list=()
6623         local pool=""
6624
6625         echo -n "Creating test dir..."
6626         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6627         echo "done."
6628
6629         echo -n "Creating test file..."
6630         touch $file1 || error "cannot create file"
6631         echo "done."
6632
6633         echo -n "Detecting existing pools..."
6634         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
6635
6636         if [ ${#pool_list[@]} -gt 0 ]; then
6637                 echo "${pool_list[@]}"
6638                 for thispool in "${pool_list[@]}"; do
6639                         if [[ -z "$initial_pool" ||
6640                               "$initial_pool" != "$thispool" ]]; then
6641                                 pool="$thispool"
6642                                 echo "Using existing pool '$pool'"
6643                                 break
6644                         fi
6645                 done
6646         else
6647                 echo "none detected."
6648         fi
6649         if [ -z "$pool" ]; then
6650                 pool=${POOL:-testpool}
6651                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
6652                 echo -n "Creating pool '$pool'..."
6653                 create_pool=true
6654                 pool_add $pool &> /dev/null ||
6655                         error "pool_add failed"
6656                 echo "done."
6657
6658                 echo -n "Adding target to pool..."
6659                 pool_add_targets $pool 0 0 1 &> /dev/null ||
6660                         error "pool_add_targets failed"
6661                 echo "done."
6662         fi
6663
6664         echo -n "Setting pool using -p option..."
6665         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
6666                 error "migrate failed rc = $?"
6667         echo "done."
6668
6669         echo -n "Verifying test file is in pool after migrating..."
6670         [ "$($LFS getstripe -p $file1)" = $pool ] ||
6671                 error "file was not migrated to pool $pool"
6672         echo "done."
6673
6674         echo -n "Removing test file from pool '$pool'..."
6675         # "lfs migrate $file" won't remove the file from the pool
6676         # until some striping information is changed.
6677         $LFS migrate -c 1 $file1 &> /dev/null ||
6678                 error "cannot remove from pool"
6679         [ "$($LFS getstripe -p $file1)" ] &&
6680                 error "pool still set"
6681         echo "done."
6682
6683         echo -n "Setting pool using --pool option..."
6684         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
6685                 error "migrate failed rc = $?"
6686         echo "done."
6687
6688         # Clean up
6689         rm -f $file1
6690         if $create_pool; then
6691                 destroy_test_pools 2> /dev/null ||
6692                         error "destroy test pools failed"
6693         fi
6694 }
6695 run_test 56wb "check lfs_migrate pool support"
6696
6697 test_56wc() {
6698         local file1="$DIR/$tdir/file1"
6699         local parent_ssize
6700         local parent_scount
6701         local cur_ssize
6702         local cur_scount
6703         local orig_ssize
6704
6705         echo -n "Creating test dir..."
6706         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6707         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
6708                 error "cannot set stripe by '-S 1M -c 1'"
6709         echo "done"
6710
6711         echo -n "Setting initial stripe for test file..."
6712         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
6713                 error "cannot set stripe"
6714         cur_ssize=$($LFS getstripe -S "$file1")
6715         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
6716         echo "done."
6717
6718         # File currently set to -S 512K -c 1
6719
6720         # Ensure -c and -S options are rejected when -R is set
6721         echo -n "Verifying incompatible options are detected..."
6722         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
6723                 error "incompatible -c and -R options not detected"
6724         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
6725                 error "incompatible -S and -R options not detected"
6726         echo "done."
6727
6728         # Ensure unrecognized options are passed through to 'lfs migrate'
6729         echo -n "Verifying -S option is passed through to lfs migrate..."
6730         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
6731                 error "migration failed"
6732         cur_ssize=$($LFS getstripe -S "$file1")
6733         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
6734         echo "done."
6735
6736         # File currently set to -S 1M -c 1
6737
6738         # Ensure long options are supported
6739         echo -n "Verifying long options supported..."
6740         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
6741                 error "long option without argument not supported"
6742         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
6743                 error "long option with argument not supported"
6744         cur_ssize=$($LFS getstripe -S "$file1")
6745         [ $cur_ssize -eq 524288 ] ||
6746                 error "migrate --stripe-size $cur_ssize != 524288"
6747         echo "done."
6748
6749         # File currently set to -S 512K -c 1
6750
6751         if [ "$OSTCOUNT" -gt 1 ]; then
6752                 echo -n "Verifying explicit stripe count can be set..."
6753                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
6754                         error "migrate failed"
6755                 cur_scount=$($LFS getstripe -c "$file1")
6756                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
6757                 echo "done."
6758         fi
6759
6760         # File currently set to -S 512K -c 1 or -S 512K -c 2
6761
6762         # Ensure parent striping is used if -R is set, and no stripe
6763         # count or size is specified
6764         echo -n "Setting stripe for parent directory..."
6765         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6766                 error "cannot set stripe '-S 2M -c 1'"
6767         echo "done."
6768
6769         echo -n "Verifying restripe option uses parent stripe settings..."
6770         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
6771         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
6772         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
6773                 error "migrate failed"
6774         cur_ssize=$($LFS getstripe -S "$file1")
6775         [ $cur_ssize -eq $parent_ssize ] ||
6776                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
6777         cur_scount=$($LFS getstripe -c "$file1")
6778         [ $cur_scount -eq $parent_scount ] ||
6779                 error "migrate -R stripe_count $cur_scount != $parent_scount"
6780         echo "done."
6781
6782         # File currently set to -S 1M -c 1
6783
6784         # Ensure striping is preserved if -R is not set, and no stripe
6785         # count or size is specified
6786         echo -n "Verifying striping size preserved when not specified..."
6787         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
6788         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6789                 error "cannot set stripe on parent directory"
6790         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6791                 error "migrate failed"
6792         cur_ssize=$($LFS getstripe -S "$file1")
6793         [ $cur_ssize -eq $orig_ssize ] ||
6794                 error "migrate by default $cur_ssize != $orig_ssize"
6795         echo "done."
6796
6797         # Ensure file name properly detected when final option has no argument
6798         echo -n "Verifying file name properly detected..."
6799         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6800                 error "file name interpreted as option argument"
6801         echo "done."
6802
6803         # Clean up
6804         rm -f "$file1"
6805 }
6806 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
6807
6808 test_56wd() {
6809         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6810
6811         local file1=$DIR/$tdir/file1
6812
6813         echo -n "Creating test dir..."
6814         test_mkdir $DIR/$tdir || error "cannot create dir"
6815         echo "done."
6816
6817         echo -n "Creating test file..."
6818         touch $file1
6819         echo "done."
6820
6821         # Ensure 'lfs migrate' will fail by using a non-existent option,
6822         # and make sure rsync is not called to recover
6823         echo -n "Make sure --no-rsync option works..."
6824         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
6825                 grep -q 'refusing to fall back to rsync' ||
6826                 error "rsync was called with --no-rsync set"
6827         echo "done."
6828
6829         # Ensure rsync is called without trying 'lfs migrate' first
6830         echo -n "Make sure --rsync option works..."
6831         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
6832                 grep -q 'falling back to rsync' &&
6833                 error "lfs migrate was called with --rsync set"
6834         echo "done."
6835
6836         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
6837         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
6838                 grep -q 'at the same time' ||
6839                 error "--rsync and --no-rsync accepted concurrently"
6840         echo "done."
6841
6842         # Clean up
6843         rm -f $file1
6844 }
6845 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
6846
6847 test_56we() {
6848         local td=$DIR/$tdir
6849         local tf=$td/$tfile
6850
6851         test_mkdir $td || error "cannot create $td"
6852         touch $tf || error "cannot touch $tf"
6853
6854         echo -n "Make sure --non-direct|-D works..."
6855         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
6856                 grep -q "lfs migrate --non-direct" ||
6857                 error "--non-direct option cannot work correctly"
6858         $LFS_MIGRATE -y -D -v $tf 2>&1 |
6859                 grep -q "lfs migrate -D" ||
6860                 error "-D option cannot work correctly"
6861         echo "done."
6862 }
6863 run_test 56we "check lfs_migrate --non-direct|-D support"
6864
6865 test_56x() {
6866         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6867         check_swap_layouts_support
6868
6869         local dir=$DIR/$tdir
6870         local ref1=/etc/passwd
6871         local file1=$dir/file1
6872
6873         test_mkdir $dir || error "creating dir $dir"
6874         $LFS setstripe -c 2 $file1
6875         cp $ref1 $file1
6876         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
6877         stripe=$($LFS getstripe -c $file1)
6878         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6879         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6880
6881         # clean up
6882         rm -f $file1
6883 }
6884 run_test 56x "lfs migration support"
6885
6886 test_56xa() {
6887         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6888         check_swap_layouts_support
6889
6890         local dir=$DIR/$tdir/$testnum
6891
6892         test_mkdir -p $dir
6893
6894         local ref1=/etc/passwd
6895         local file1=$dir/file1
6896
6897         $LFS setstripe -c 2 $file1
6898         cp $ref1 $file1
6899         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
6900
6901         local stripe=$($LFS getstripe -c $file1)
6902
6903         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6904         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6905
6906         # clean up
6907         rm -f $file1
6908 }
6909 run_test 56xa "lfs migration --block support"
6910
6911 check_migrate_links() {
6912         local dir="$1"
6913         local file1="$dir/file1"
6914         local begin="$2"
6915         local count="$3"
6916         local runas="$4"
6917         local total_count=$(($begin + $count - 1))
6918         local symlink_count=10
6919         local uniq_count=10
6920
6921         if [ ! -f "$file1" ]; then
6922                 echo -n "creating initial file..."
6923                 $LFS setstripe -c 1 -S "512k" "$file1" ||
6924                         error "cannot setstripe initial file"
6925                 echo "done"
6926
6927                 echo -n "creating symlinks..."
6928                 for s in $(seq 1 $symlink_count); do
6929                         ln -s "$file1" "$dir/slink$s" ||
6930                                 error "cannot create symlinks"
6931                 done
6932                 echo "done"
6933
6934                 echo -n "creating nonlinked files..."
6935                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
6936                         error "cannot create nonlinked files"
6937                 echo "done"
6938         fi
6939
6940         # create hard links
6941         if [ ! -f "$dir/file$total_count" ]; then
6942                 echo -n "creating hard links $begin:$total_count..."
6943                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
6944                         /dev/null || error "cannot create hard links"
6945                 echo "done"
6946         fi
6947
6948         echo -n "checking number of hard links listed in xattrs..."
6949         local fid=$($LFS getstripe -F "$file1")
6950         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
6951
6952         echo "${#paths[*]}"
6953         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
6954                         skip "hard link list has unexpected size, skipping test"
6955         fi
6956         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
6957                         error "link names should exceed xattrs size"
6958         fi
6959
6960         echo -n "migrating files..."
6961         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
6962         local rc=$?
6963         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
6964         echo "done"
6965
6966         # make sure all links have been properly migrated
6967         echo -n "verifying files..."
6968         fid=$($LFS getstripe -F "$file1") ||
6969                 error "cannot get fid for file $file1"
6970         for i in $(seq 2 $total_count); do
6971                 local fid2=$($LFS getstripe -F $dir/file$i)
6972
6973                 [ "$fid2" == "$fid" ] ||
6974                         error "migrated hard link has mismatched FID"
6975         done
6976
6977         # make sure hard links were properly detected, and migration was
6978         # performed only once for the entire link set; nonlinked files should
6979         # also be migrated
6980         local actual=$(grep -c 'done' <<< "$migrate_out")
6981         local expected=$(($uniq_count + 1))
6982
6983         [ "$actual" -eq  "$expected" ] ||
6984                 error "hard links individually migrated ($actual != $expected)"
6985
6986         # make sure the correct number of hard links are present
6987         local hardlinks=$(stat -c '%h' "$file1")
6988
6989         [ $hardlinks -eq $total_count ] ||
6990                 error "num hard links $hardlinks != $total_count"
6991         echo "done"
6992
6993         return 0
6994 }
6995
6996 test_56xb() {
6997         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
6998                 skip "Need MDS version at least 2.10.55"
6999
7000         local dir="$DIR/$tdir"
7001
7002         test_mkdir "$dir" || error "cannot create dir $dir"
7003
7004         echo "testing lfs migrate mode when all links fit within xattrs"
7005         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7006
7007         echo "testing rsync mode when all links fit within xattrs"
7008         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7009
7010         echo "testing lfs migrate mode when all links do not fit within xattrs"
7011         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7012
7013         echo "testing rsync mode when all links do not fit within xattrs"
7014         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7015
7016         chown -R $RUNAS_ID $dir
7017         echo "testing non-root lfs migrate mode when not all links are in xattr"
7018         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7019
7020         # clean up
7021         rm -rf $dir
7022 }
7023 run_test 56xb "lfs migration hard link support"
7024
7025 test_56xc() {
7026         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7027
7028         local dir="$DIR/$tdir"
7029
7030         test_mkdir "$dir" || error "cannot create dir $dir"
7031
7032         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7033         echo -n "Setting initial stripe for 20MB test file..."
7034         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7035                 error "cannot setstripe 20MB file"
7036         echo "done"
7037         echo -n "Sizing 20MB test file..."
7038         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7039         echo "done"
7040         echo -n "Verifying small file autostripe count is 1..."
7041         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7042                 error "cannot migrate 20MB file"
7043         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7044                 error "cannot get stripe for $dir/20mb"
7045         [ $stripe_count -eq 1 ] ||
7046                 error "unexpected stripe count $stripe_count for 20MB file"
7047         rm -f "$dir/20mb"
7048         echo "done"
7049
7050         # Test 2: File is small enough to fit within the available space on
7051         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7052         # have at least an additional 1KB for each desired stripe for test 3
7053         echo -n "Setting stripe for 1GB test file..."
7054         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7055         echo "done"
7056         echo -n "Sizing 1GB test file..."
7057         # File size is 1GB + 3KB
7058         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7059         echo "done"
7060
7061         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7062         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7063         if (( avail > 524288 * OSTCOUNT )); then
7064                 echo -n "Migrating 1GB file..."
7065                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7066                         error "cannot migrate 1GB file"
7067                 echo "done"
7068                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7069                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7070                         error "cannot getstripe for 1GB file"
7071                 [ $stripe_count -eq 2 ] ||
7072                         error "unexpected stripe count $stripe_count != 2"
7073                 echo "done"
7074         fi
7075
7076         # Test 3: File is too large to fit within the available space on
7077         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7078         if [ $OSTCOUNT -ge 3 ]; then
7079                 # The required available space is calculated as
7080                 # file size (1GB + 3KB) / OST count (3).
7081                 local kb_per_ost=349526
7082
7083                 echo -n "Migrating 1GB file with limit..."
7084                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7085                         error "cannot migrate 1GB file with limit"
7086                 echo "done"
7087
7088                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7089                 echo -n "Verifying 1GB autostripe count with limited space..."
7090                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7091                         error "unexpected stripe count $stripe_count (min 3)"
7092                 echo "done"
7093         fi
7094
7095         # clean up
7096         rm -rf $dir
7097 }
7098 run_test 56xc "lfs migration autostripe"
7099
7100 test_56xd() {
7101         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7102
7103         local dir=$DIR/$tdir
7104         local f_mgrt=$dir/$tfile.mgrt
7105         local f_yaml=$dir/$tfile.yaml
7106         local f_copy=$dir/$tfile.copy
7107         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7108         local layout_copy="-c 2 -S 2M -i 1"
7109         local yamlfile=$dir/yamlfile
7110         local layout_before;
7111         local layout_after;
7112
7113         test_mkdir "$dir" || error "cannot create dir $dir"
7114         $LFS setstripe $layout_yaml $f_yaml ||
7115                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7116         $LFS getstripe --yaml $f_yaml > $yamlfile
7117         $LFS setstripe $layout_copy $f_copy ||
7118                 error "cannot setstripe $f_copy with layout $layout_copy"
7119         touch $f_mgrt
7120         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7121
7122         # 1. test option --yaml
7123         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7124                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7125         layout_before=$(get_layout_param $f_yaml)
7126         layout_after=$(get_layout_param $f_mgrt)
7127         [ "$layout_after" == "$layout_before" ] ||
7128                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7129
7130         # 2. test option --copy
7131         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7132                 error "cannot migrate $f_mgrt with --copy $f_copy"
7133         layout_before=$(get_layout_param $f_copy)
7134         layout_after=$(get_layout_param $f_mgrt)
7135         [ "$layout_after" == "$layout_before" ] ||
7136                 error "lfs_migrate --copy: $layout_after != $layout_before"
7137 }
7138 run_test 56xd "check lfs_migrate --yaml and --copy support"
7139
7140 test_56xe() {
7141         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7142
7143         local dir=$DIR/$tdir
7144         local f_comp=$dir/$tfile
7145         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7146         local layout_before=""
7147         local layout_after=""
7148
7149         test_mkdir "$dir" || error "cannot create dir $dir"
7150         $LFS setstripe $layout $f_comp ||
7151                 error "cannot setstripe $f_comp with layout $layout"
7152         layout_before=$(get_layout_param $f_comp)
7153         dd if=/dev/zero of=$f_comp bs=1M count=4
7154
7155         # 1. migrate a comp layout file by lfs_migrate
7156         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7157         layout_after=$(get_layout_param $f_comp)
7158         [ "$layout_before" == "$layout_after" ] ||
7159                 error "lfs_migrate: $layout_before != $layout_after"
7160
7161         # 2. migrate a comp layout file by lfs migrate
7162         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7163         layout_after=$(get_layout_param $f_comp)
7164         [ "$layout_before" == "$layout_after" ] ||
7165                 error "lfs migrate: $layout_before != $layout_after"
7166 }
7167 run_test 56xe "migrate a composite layout file"
7168
7169 test_56xf() {
7170         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7171
7172         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7173                 skip "Need server version at least 2.13.53"
7174
7175         local dir=$DIR/$tdir
7176         local f_comp=$dir/$tfile
7177         local layout="-E 1M -c1 -E -1 -c2"
7178         local fid_before=""
7179         local fid_after=""
7180
7181         test_mkdir "$dir" || error "cannot create dir $dir"
7182         $LFS setstripe $layout $f_comp ||
7183                 error "cannot setstripe $f_comp with layout $layout"
7184         fid_before=$($LFS getstripe --fid $f_comp)
7185         dd if=/dev/zero of=$f_comp bs=1M count=4
7186
7187         # 1. migrate a comp layout file to a comp layout
7188         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7189         fid_after=$($LFS getstripe --fid $f_comp)
7190         [ "$fid_before" == "$fid_after" ] ||
7191                 error "comp-to-comp migrate: $fid_before != $fid_after"
7192
7193         # 2. migrate a comp layout file to a plain layout
7194         $LFS migrate -c2 $f_comp ||
7195                 error "cannot migrate $f_comp by lfs migrate"
7196         fid_after=$($LFS getstripe --fid $f_comp)
7197         [ "$fid_before" == "$fid_after" ] ||
7198                 error "comp-to-plain migrate: $fid_before != $fid_after"
7199
7200         # 3. migrate a plain layout file to a comp layout
7201         $LFS migrate $layout $f_comp ||
7202                 error "cannot migrate $f_comp by lfs migrate"
7203         fid_after=$($LFS getstripe --fid $f_comp)
7204         [ "$fid_before" == "$fid_after" ] ||
7205                 error "plain-to-comp migrate: $fid_before != $fid_after"
7206 }
7207 run_test 56xf "FID is not lost during migration of a composite layout file"
7208
7209 test_56y() {
7210         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7211                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7212
7213         local res=""
7214         local dir=$DIR/$tdir
7215         local f1=$dir/file1
7216         local f2=$dir/file2
7217
7218         test_mkdir -p $dir || error "creating dir $dir"
7219         touch $f1 || error "creating std file $f1"
7220         $MULTIOP $f2 H2c || error "creating released file $f2"
7221
7222         # a directory can be raid0, so ask only for files
7223         res=$($LFS find $dir -L raid0 -type f | wc -l)
7224         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7225
7226         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7227         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7228
7229         # only files can be released, so no need to force file search
7230         res=$($LFS find $dir -L released)
7231         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7232
7233         res=$($LFS find $dir -type f \! -L released)
7234         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7235 }
7236 run_test 56y "lfs find -L raid0|released"
7237
7238 test_56z() { # LU-4824
7239         # This checks to make sure 'lfs find' continues after errors
7240         # There are two classes of errors that should be caught:
7241         # - If multiple paths are provided, all should be searched even if one
7242         #   errors out
7243         # - If errors are encountered during the search, it should not terminate
7244         #   early
7245         local dir=$DIR/$tdir
7246         local i
7247
7248         test_mkdir $dir
7249         for i in d{0..9}; do
7250                 test_mkdir $dir/$i
7251                 touch $dir/$i/$tfile
7252         done
7253         $LFS find $DIR/non_existent_dir $dir &&
7254                 error "$LFS find did not return an error"
7255         # Make a directory unsearchable. This should NOT be the last entry in
7256         # directory order.  Arbitrarily pick the 6th entry
7257         chmod 700 $($LFS find $dir -type d | sed '6!d')
7258
7259         $RUNAS $LFS find $DIR/non_existent $dir
7260         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7261
7262         # The user should be able to see 10 directories and 9 files
7263         (( count == 19 )) ||
7264                 error "$LFS find found $count != 19 entries after error"
7265 }
7266 run_test 56z "lfs find should continue after an error"
7267
7268 test_56aa() { # LU-5937
7269         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7270
7271         local dir=$DIR/$tdir
7272
7273         mkdir $dir
7274         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7275
7276         createmany -o $dir/striped_dir/${tfile}- 1024
7277         local dirs=$($LFS find --size +8k $dir/)
7278
7279         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7280 }
7281 run_test 56aa "lfs find --size under striped dir"
7282
7283 test_56ab() { # LU-10705
7284         test_mkdir $DIR/$tdir
7285         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7286         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7287         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7288         # Flush writes to ensure valid blocks.  Need to be more thorough for
7289         # ZFS, since blocks are not allocated/returned to client immediately.
7290         sync_all_data
7291         wait_zfs_commit ost1 2
7292         cancel_lru_locks osc
7293         ls -ls $DIR/$tdir
7294
7295         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7296
7297         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7298
7299         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7300         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7301
7302         rm -f $DIR/$tdir/$tfile.[123]
7303 }
7304 run_test 56ab "lfs find --blocks"
7305
7306 test_56ba() {
7307         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
7308                 skip "Need MDS version at least 2.10.50"
7309
7310         # Create composite files with one component
7311         local dir=$DIR/$tdir
7312
7313         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
7314         # Create composite files with three components
7315         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
7316         # Create non-composite files
7317         createmany -o $dir/${tfile}- 10
7318
7319         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
7320
7321         [[ $nfiles == 10 ]] ||
7322                 error "lfs find -E 1M found $nfiles != 10 files"
7323
7324         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
7325         [[ $nfiles == 25 ]] ||
7326                 error "lfs find ! -E 1M found $nfiles != 25 files"
7327
7328         # All files have a component that starts at 0
7329         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
7330         [[ $nfiles == 35 ]] ||
7331                 error "lfs find --component-start 0 - $nfiles != 35 files"
7332
7333         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
7334         [[ $nfiles == 15 ]] ||
7335                 error "lfs find --component-start 2M - $nfiles != 15 files"
7336
7337         # All files created here have a componenet that does not starts at 2M
7338         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
7339         [[ $nfiles == 35 ]] ||
7340                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
7341
7342         # Find files with a specified number of components
7343         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
7344         [[ $nfiles == 15 ]] ||
7345                 error "lfs find --component-count 3 - $nfiles != 15 files"
7346
7347         # Remember non-composite files have a component count of zero
7348         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
7349         [[ $nfiles == 10 ]] ||
7350                 error "lfs find --component-count 0 - $nfiles != 10 files"
7351
7352         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
7353         [[ $nfiles == 20 ]] ||
7354                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
7355
7356         # All files have a flag called "init"
7357         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
7358         [[ $nfiles == 35 ]] ||
7359                 error "lfs find --component-flags init - $nfiles != 35 files"
7360
7361         # Multi-component files will have a component not initialized
7362         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
7363         [[ $nfiles == 15 ]] ||
7364                 error "lfs find !--component-flags init - $nfiles != 15 files"
7365
7366         rm -rf $dir
7367
7368 }
7369 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
7370
7371 test_56ca() {
7372         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
7373                 skip "Need MDS version at least 2.10.57"
7374
7375         local td=$DIR/$tdir
7376         local tf=$td/$tfile
7377         local dir
7378         local nfiles
7379         local cmd
7380         local i
7381         local j
7382
7383         # create mirrored directories and mirrored files
7384         mkdir $td || error "mkdir $td failed"
7385         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
7386         createmany -o $tf- 10 || error "create $tf- failed"
7387
7388         for i in $(seq 2); do
7389                 dir=$td/dir$i
7390                 mkdir $dir || error "mkdir $dir failed"
7391                 $LFS mirror create -N$((3 + i)) $dir ||
7392                         error "create mirrored dir $dir failed"
7393                 createmany -o $dir/$tfile- 10 ||
7394                         error "create $dir/$tfile- failed"
7395         done
7396
7397         # change the states of some mirrored files
7398         echo foo > $tf-6
7399         for i in $(seq 2); do
7400                 dir=$td/dir$i
7401                 for j in $(seq 4 9); do
7402                         echo foo > $dir/$tfile-$j
7403                 done
7404         done
7405
7406         # find mirrored files with specific mirror count
7407         cmd="$LFS find --mirror-count 3 --type f $td"
7408         nfiles=$($cmd | wc -l)
7409         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
7410
7411         cmd="$LFS find ! --mirror-count 3 --type f $td"
7412         nfiles=$($cmd | wc -l)
7413         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
7414
7415         cmd="$LFS find --mirror-count +2 --type f $td"
7416         nfiles=$($cmd | wc -l)
7417         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7418
7419         cmd="$LFS find --mirror-count -6 --type f $td"
7420         nfiles=$($cmd | wc -l)
7421         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7422
7423         # find mirrored files with specific file state
7424         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
7425         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
7426
7427         cmd="$LFS find --mirror-state=ro --type f $td"
7428         nfiles=$($cmd | wc -l)
7429         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
7430
7431         cmd="$LFS find ! --mirror-state=ro --type f $td"
7432         nfiles=$($cmd | wc -l)
7433         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7434
7435         cmd="$LFS find --mirror-state=wp --type f $td"
7436         nfiles=$($cmd | wc -l)
7437         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7438
7439         cmd="$LFS find ! --mirror-state=sp --type f $td"
7440         nfiles=$($cmd | wc -l)
7441         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7442 }
7443 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
7444
7445 test_57a() {
7446         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7447         # note test will not do anything if MDS is not local
7448         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7449                 skip_env "ldiskfs only test"
7450         fi
7451         remote_mds_nodsh && skip "remote MDS with nodsh"
7452
7453         local MNTDEV="osd*.*MDT*.mntdev"
7454         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
7455         [ -z "$DEV" ] && error "can't access $MNTDEV"
7456         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
7457                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
7458                         error "can't access $DEV"
7459                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
7460                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
7461                 rm $TMP/t57a.dump
7462         done
7463 }
7464 run_test 57a "verify MDS filesystem created with large inodes =="
7465
7466 test_57b() {
7467         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7468         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7469                 skip_env "ldiskfs only test"
7470         fi
7471         remote_mds_nodsh && skip "remote MDS with nodsh"
7472
7473         local dir=$DIR/$tdir
7474         local filecount=100
7475         local file1=$dir/f1
7476         local fileN=$dir/f$filecount
7477
7478         rm -rf $dir || error "removing $dir"
7479         test_mkdir -c1 $dir
7480         local mdtidx=$($LFS getstripe -m $dir)
7481         local mdtname=MDT$(printf %04x $mdtidx)
7482         local facet=mds$((mdtidx + 1))
7483
7484         echo "mcreating $filecount files"
7485         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
7486
7487         # verify that files do not have EAs yet
7488         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
7489                 error "$file1 has an EA"
7490         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
7491                 error "$fileN has an EA"
7492
7493         sync
7494         sleep 1
7495         df $dir  #make sure we get new statfs data
7496         local mdsfree=$(do_facet $facet \
7497                         lctl get_param -n osd*.*$mdtname.kbytesfree)
7498         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7499         local file
7500
7501         echo "opening files to create objects/EAs"
7502         for file in $(seq -f $dir/f%g 1 $filecount); do
7503                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
7504                         error "opening $file"
7505         done
7506
7507         # verify that files have EAs now
7508         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
7509         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
7510
7511         sleep 1  #make sure we get new statfs data
7512         df $dir
7513         local mdsfree2=$(do_facet $facet \
7514                          lctl get_param -n osd*.*$mdtname.kbytesfree)
7515         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7516
7517         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
7518                 if [ "$mdsfree" != "$mdsfree2" ]; then
7519                         error "MDC before $mdcfree != after $mdcfree2"
7520                 else
7521                         echo "MDC before $mdcfree != after $mdcfree2"
7522                         echo "unable to confirm if MDS has large inodes"
7523                 fi
7524         fi
7525         rm -rf $dir
7526 }
7527 run_test 57b "default LOV EAs are stored inside large inodes ==="
7528
7529 test_58() {
7530         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7531         [ -z "$(which wiretest 2>/dev/null)" ] &&
7532                         skip_env "could not find wiretest"
7533
7534         wiretest
7535 }
7536 run_test 58 "verify cross-platform wire constants =============="
7537
7538 test_59() {
7539         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7540
7541         echo "touch 130 files"
7542         createmany -o $DIR/f59- 130
7543         echo "rm 130 files"
7544         unlinkmany $DIR/f59- 130
7545         sync
7546         # wait for commitment of removal
7547         wait_delete_completed
7548 }
7549 run_test 59 "verify cancellation of llog records async ========="
7550
7551 TEST60_HEAD="test_60 run $RANDOM"
7552 test_60a() {
7553         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7554         remote_mgs_nodsh && skip "remote MGS with nodsh"
7555         do_facet mgs "! which run-llog.sh &> /dev/null" &&
7556                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
7557                         skip_env "missing subtest run-llog.sh"
7558
7559         log "$TEST60_HEAD - from kernel mode"
7560         do_facet mgs "$LCTL dk > /dev/null"
7561         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
7562         do_facet mgs $LCTL dk > $TMP/$tfile
7563
7564         # LU-6388: test llog_reader
7565         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
7566         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
7567         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
7568                         skip_env "missing llog_reader"
7569         local fstype=$(facet_fstype mgs)
7570         [ $fstype != ldiskfs -a $fstype != zfs ] &&
7571                 skip_env "Only for ldiskfs or zfs type mgs"
7572
7573         local mntpt=$(facet_mntpt mgs)
7574         local mgsdev=$(mgsdevname 1)
7575         local fid_list
7576         local fid
7577         local rec_list
7578         local rec
7579         local rec_type
7580         local obj_file
7581         local path
7582         local seq
7583         local oid
7584         local pass=true
7585
7586         #get fid and record list
7587         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
7588                 tail -n 4))
7589         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
7590                 tail -n 4))
7591         #remount mgs as ldiskfs or zfs type
7592         stop mgs || error "stop mgs failed"
7593         mount_fstype mgs || error "remount mgs failed"
7594         for ((i = 0; i < ${#fid_list[@]}; i++)); do
7595                 fid=${fid_list[i]}
7596                 rec=${rec_list[i]}
7597                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
7598                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
7599                 oid=$((16#$oid))
7600
7601                 case $fstype in
7602                         ldiskfs )
7603                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
7604                         zfs )
7605                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
7606                 esac
7607                 echo "obj_file is $obj_file"
7608                 do_facet mgs $llog_reader $obj_file
7609
7610                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
7611                         awk '{ print $3 }' | sed -e "s/^type=//g")
7612                 if [ $rec_type != $rec ]; then
7613                         echo "FAILED test_60a wrong record type $rec_type," \
7614                               "should be $rec"
7615                         pass=false
7616                         break
7617                 fi
7618
7619                 #check obj path if record type is LLOG_LOGID_MAGIC
7620                 if [ "$rec" == "1064553b" ]; then
7621                         path=$(do_facet mgs $llog_reader $obj_file |
7622                                 grep "path=" | awk '{ print $NF }' |
7623                                 sed -e "s/^path=//g")
7624                         if [ $obj_file != $mntpt/$path ]; then
7625                                 echo "FAILED test_60a wrong obj path" \
7626                                       "$montpt/$path, should be $obj_file"
7627                                 pass=false
7628                                 break
7629                         fi
7630                 fi
7631         done
7632         rm -f $TMP/$tfile
7633         #restart mgs before "error", otherwise it will block the next test
7634         stop mgs || error "stop mgs failed"
7635         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
7636         $pass || error "test failed, see FAILED test_60a messages for specifics"
7637 }
7638 run_test 60a "llog_test run from kernel module and test llog_reader"
7639
7640 test_60b() { # bug 6411
7641         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7642
7643         dmesg > $DIR/$tfile
7644         LLOG_COUNT=$(do_facet mgs dmesg |
7645                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
7646                           /llog_[a-z]*.c:[0-9]/ {
7647                                 if (marker)
7648                                         from_marker++
7649                                 from_begin++
7650                           }
7651                           END {
7652                                 if (marker)
7653                                         print from_marker
7654                                 else
7655                                         print from_begin
7656                           }")
7657
7658         [[ $LLOG_COUNT -gt 120 ]] &&
7659                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
7660 }
7661 run_test 60b "limit repeated messages from CERROR/CWARN"
7662
7663 test_60c() {
7664         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7665
7666         echo "create 5000 files"
7667         createmany -o $DIR/f60c- 5000
7668 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
7669         lctl set_param fail_loc=0x80000137
7670         unlinkmany $DIR/f60c- 5000
7671         lctl set_param fail_loc=0
7672 }
7673 run_test 60c "unlink file when mds full"
7674
7675 test_60d() {
7676         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7677
7678         SAVEPRINTK=$(lctl get_param -n printk)
7679         # verify "lctl mark" is even working"
7680         MESSAGE="test message ID $RANDOM $$"
7681         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7682         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
7683
7684         lctl set_param printk=0 || error "set lnet.printk failed"
7685         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
7686         MESSAGE="new test message ID $RANDOM $$"
7687         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
7688         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7689         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
7690
7691         lctl set_param -n printk="$SAVEPRINTK"
7692 }
7693 run_test 60d "test printk console message masking"
7694
7695 test_60e() {
7696         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7697         remote_mds_nodsh && skip "remote MDS with nodsh"
7698
7699         touch $DIR/$tfile
7700 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
7701         do_facet mds1 lctl set_param fail_loc=0x15b
7702         rm $DIR/$tfile
7703 }
7704 run_test 60e "no space while new llog is being created"
7705
7706 test_60g() {
7707         local pid
7708         local i
7709
7710         test_mkdir -c $MDSCOUNT $DIR/$tdir
7711
7712         (
7713                 local index=0
7714                 while true; do
7715                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
7716                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
7717                                 2>/dev/null
7718                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
7719                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
7720                         index=$((index + 1))
7721                 done
7722         ) &
7723
7724         pid=$!
7725
7726         for i in {0..100}; do
7727                 # define OBD_FAIL_OSD_TXN_START    0x19a
7728                 local index=$((i % MDSCOUNT + 1))
7729
7730                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
7731                         > /dev/null
7732                 sleep 0.01
7733         done
7734
7735         kill -9 $pid
7736
7737         for i in $(seq $MDSCOUNT); do
7738                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
7739         done
7740
7741         mkdir $DIR/$tdir/new || error "mkdir failed"
7742         rmdir $DIR/$tdir/new || error "rmdir failed"
7743
7744         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
7745                 -t namespace
7746         for i in $(seq $MDSCOUNT); do
7747                 wait_update_facet mds$i "$LCTL get_param -n \
7748                         mdd.$(facet_svc mds$i).lfsck_namespace |
7749                         awk '/^status/ { print \\\$2 }'" "completed"
7750         done
7751
7752         ls -R $DIR/$tdir || error "ls failed"
7753         rm -rf $DIR/$tdir || error "rmdir failed"
7754 }
7755 run_test 60g "transaction abort won't cause MDT hung"
7756
7757 test_60h() {
7758         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
7759                 skip "Need MDS version at least 2.12.52"
7760         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
7761
7762         local f
7763
7764         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
7765         #define OBD_FAIL_MDS_STRIPE_FID          0x189
7766         for fail_loc in 0x80000188 0x80000189; do
7767                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
7768                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
7769                         error "mkdir $dir-$fail_loc failed"
7770                 for i in {0..10}; do
7771                         # create may fail on missing stripe
7772                         echo $i > $DIR/$tdir-$fail_loc/$i
7773                 done
7774                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7775                         error "getdirstripe $tdir-$fail_loc failed"
7776                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
7777                         error "migrate $tdir-$fail_loc failed"
7778                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7779                         error "getdirstripe $tdir-$fail_loc failed"
7780                 pushd $DIR/$tdir-$fail_loc
7781                 for f in *; do
7782                         echo $f | cmp $f - || error "$f data mismatch"
7783                 done
7784                 popd
7785                 rm -rf $DIR/$tdir-$fail_loc
7786         done
7787 }
7788 run_test 60h "striped directory with missing stripes can be accessed"
7789
7790 test_61a() {
7791         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7792
7793         f="$DIR/f61"
7794         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
7795         cancel_lru_locks osc
7796         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
7797         sync
7798 }
7799 run_test 61a "mmap() writes don't make sync hang ================"
7800
7801 test_61b() {
7802         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
7803 }
7804 run_test 61b "mmap() of unstriped file is successful"
7805
7806 # bug 2330 - insufficient obd_match error checking causes LBUG
7807 test_62() {
7808         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7809
7810         f="$DIR/f62"
7811         echo foo > $f
7812         cancel_lru_locks osc
7813         lctl set_param fail_loc=0x405
7814         cat $f && error "cat succeeded, expect -EIO"
7815         lctl set_param fail_loc=0
7816 }
7817 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
7818 # match every page all of the time.
7819 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
7820
7821 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
7822 # Though this test is irrelevant anymore, it helped to reveal some
7823 # other grant bugs (LU-4482), let's keep it.
7824 test_63a() {   # was test_63
7825         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7826
7827         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
7828
7829         for i in `seq 10` ; do
7830                 dd if=/dev/zero of=$DIR/f63 bs=8k &
7831                 sleep 5
7832                 kill $!
7833                 sleep 1
7834         done
7835
7836         rm -f $DIR/f63 || true
7837 }
7838 run_test 63a "Verify oig_wait interruption does not crash ======="
7839
7840 # bug 2248 - async write errors didn't return to application on sync
7841 # bug 3677 - async write errors left page locked
7842 test_63b() {
7843         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7844
7845         debugsave
7846         lctl set_param debug=-1
7847
7848         # ensure we have a grant to do async writes
7849         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
7850         rm $DIR/$tfile
7851
7852         sync    # sync lest earlier test intercept the fail_loc
7853
7854         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
7855         lctl set_param fail_loc=0x80000406
7856         $MULTIOP $DIR/$tfile Owy && \
7857                 error "sync didn't return ENOMEM"
7858         sync; sleep 2; sync     # do a real sync this time to flush page
7859         lctl get_param -n llite.*.dump_page_cache | grep locked && \
7860                 error "locked page left in cache after async error" || true
7861         debugrestore
7862 }
7863 run_test 63b "async write errors should be returned to fsync ==="
7864
7865 test_64a () {
7866         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7867
7868         lfs df $DIR
7869         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
7870 }
7871 run_test 64a "verify filter grant calculations (in kernel) ====="
7872
7873 test_64b () {
7874         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7875
7876         sh oos.sh $MOUNT || error "oos.sh failed: $?"
7877 }
7878 run_test 64b "check out-of-space detection on client"
7879
7880 test_64c() {
7881         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
7882 }
7883 run_test 64c "verify grant shrink"
7884
7885 import_param() {
7886         local tgt=$1
7887         local param=$2
7888
7889         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
7890 }
7891
7892 # this does exactly what osc_request.c:osc_announce_cached() does in
7893 # order to calculate max amount of grants to ask from server
7894 want_grant() {
7895         local tgt=$1
7896
7897         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
7898         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
7899
7900         ((rpc_in_flight++));
7901         nrpages=$((nrpages * rpc_in_flight))
7902
7903         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
7904
7905         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
7906
7907         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
7908         local undirty=$((nrpages * PAGE_SIZE))
7909
7910         local max_extent_pages
7911         max_extent_pages=$(import_param $tgt grant_max_extent_size)
7912         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
7913         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
7914         local grant_extent_tax
7915         grant_extent_tax=$(import_param $tgt grant_extent_tax)
7916
7917         undirty=$((undirty + nrextents * grant_extent_tax))
7918
7919         echo $undirty
7920 }
7921
7922 # this is size of unit for grant allocation. It should be equal to
7923 # what tgt_grant.c:tgt_grant_chunk() calculates
7924 grant_chunk() {
7925         local tgt=$1
7926         local max_brw_size
7927         local grant_extent_tax
7928
7929         max_brw_size=$(import_param $tgt max_brw_size)
7930
7931         grant_extent_tax=$(import_param $tgt grant_extent_tax)
7932
7933         echo $(((max_brw_size + grant_extent_tax) * 2))
7934 }
7935
7936 test_64d() {
7937         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
7938                 skip "OST < 2.10.55 doesn't limit grants enough"
7939
7940         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
7941
7942         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
7943                 skip "no grant_param connect flag"
7944
7945         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
7946
7947         $LCTL set_param -n -n debug="$OLDDEBUG" || true
7948         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
7949
7950
7951         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
7952         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
7953
7954         $LFS setstripe $DIR/$tfile -i 0 -c 1
7955         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
7956         ddpid=$!
7957
7958         while kill -0 $ddpid; do
7959                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
7960
7961                 if [[ $cur_grant -gt $max_cur_granted ]]; then
7962                         kill $ddpid
7963                         error "cur_grant $cur_grant > $max_cur_granted"
7964                 fi
7965
7966                 sleep 1
7967         done
7968 }
7969 run_test 64d "check grant limit exceed"
7970
7971 check_grants() {
7972         local tgt=$1
7973         local expected=$2
7974         local msg=$3
7975         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
7976
7977         ((cur_grants == expected)) ||
7978                 error "$msg: grants mismatch: $cur_grants, expected $expected"
7979 }
7980
7981 round_up_p2() {
7982         echo $((($1 + $2 - 1) & ~($2 - 1)))
7983 }
7984
7985 test_64e() {
7986         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7987         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
7988                 skip "Need OSS version at least 2.11.56"
7989
7990         # Remount client to reset grant
7991         remount_client $MOUNT || error "failed to remount client"
7992         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
7993
7994         local init_grants=$(import_param $osc_tgt initial_grant)
7995
7996         check_grants $osc_tgt $init_grants "init grants"
7997
7998         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
7999         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8000         local gbs=$(import_param $osc_tgt grant_block_size)
8001
8002         # write random number of bytes from max_brw_size / 4 to max_brw_size
8003         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8004         # align for direct io
8005         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8006         # round to grant consumption unit
8007         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8008
8009         local grants=$((wb_round_up + extent_tax))
8010
8011         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
8012
8013         # define OBD_FAIL_TGT_NO_GRANT 0x725
8014         # make the server not grant more back
8015         do_facet ost1 $LCTL set_param fail_loc=0x725
8016         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
8017
8018         do_facet ost1 $LCTL set_param fail_loc=0
8019
8020         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
8021
8022         rm -f $DIR/$tfile || error "rm failed"
8023
8024         # Remount client to reset grant
8025         remount_client $MOUNT || error "failed to remount client"
8026         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8027
8028         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8029
8030         # define OBD_FAIL_TGT_NO_GRANT 0x725
8031         # make the server not grant more back
8032         do_facet ost1 $LCTL set_param fail_loc=0x725
8033         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
8034         do_facet ost1 $LCTL set_param fail_loc=0
8035
8036         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8037 }
8038 run_test 64e "check grant consumption (no grant allocation)"
8039
8040 test_64f() {
8041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8042
8043         # Remount client to reset grant
8044         remount_client $MOUNT || error "failed to remount client"
8045         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8046
8047         local init_grants=$(import_param $osc_tgt initial_grant)
8048         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8049         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8050         local gbs=$(import_param $osc_tgt grant_block_size)
8051         local chunk=$(grant_chunk $osc_tgt)
8052
8053         # write random number of bytes from max_brw_size / 4 to max_brw_size
8054         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8055         # align for direct io
8056         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8057         # round to grant consumption unit
8058         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8059
8060         local grants=$((wb_round_up + extent_tax))
8061
8062         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8063         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8064                 error "error writing to $DIR/$tfile"
8065
8066         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8067                 "direct io with grant allocation"
8068
8069         rm -f $DIR/$tfile || error "rm failed"
8070
8071         # Remount client to reset grant
8072         remount_client $MOUNT || error "failed to remount client"
8073         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8074
8075         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8076
8077         local cmd="oO_WRONLY:w${write_bytes}_yc"
8078
8079         $MULTIOP $DIR/$tfile $cmd &
8080         MULTIPID=$!
8081         sleep 1
8082
8083         check_grants $osc_tgt $((init_grants - grants)) \
8084                 "buffered io, not write rpc"
8085
8086         kill -USR1 $MULTIPID
8087         wait
8088
8089         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8090                 "buffered io, one RPC"
8091 }
8092 run_test 64f "check grant consumption (with grant allocation)"
8093
8094 # bug 1414 - set/get directories' stripe info
8095 test_65a() {
8096         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8097
8098         test_mkdir $DIR/$tdir
8099         touch $DIR/$tdir/f1
8100         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
8101 }
8102 run_test 65a "directory with no stripe info"
8103
8104 test_65b() {
8105         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8106
8107         test_mkdir $DIR/$tdir
8108         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8109
8110         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8111                                                 error "setstripe"
8112         touch $DIR/$tdir/f2
8113         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
8114 }
8115 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
8116
8117 test_65c() {
8118         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8119         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
8120
8121         test_mkdir $DIR/$tdir
8122         local stripesize=$($LFS getstripe -S $DIR/$tdir)
8123
8124         $LFS setstripe -S $((stripesize * 4)) -i 1 \
8125                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
8126         touch $DIR/$tdir/f3
8127         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
8128 }
8129 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
8130
8131 test_65d() {
8132         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8133
8134         test_mkdir $DIR/$tdir
8135         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
8136         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8137
8138         if [[ $STRIPECOUNT -le 0 ]]; then
8139                 sc=1
8140         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
8141                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
8142                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
8143         else
8144                 sc=$(($STRIPECOUNT - 1))
8145         fi
8146         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
8147         touch $DIR/$tdir/f4 $DIR/$tdir/f5
8148         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
8149                 error "lverify failed"
8150 }
8151 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
8152
8153 test_65e() {
8154         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8155
8156         test_mkdir $DIR/$tdir
8157
8158         $LFS setstripe $DIR/$tdir || error "setstripe"
8159         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8160                                         error "no stripe info failed"
8161         touch $DIR/$tdir/f6
8162         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
8163 }
8164 run_test 65e "directory setstripe defaults"
8165
8166 test_65f() {
8167         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8168
8169         test_mkdir $DIR/${tdir}f
8170         $RUNAS $LFS setstripe $DIR/${tdir}f &&
8171                 error "setstripe succeeded" || true
8172 }
8173 run_test 65f "dir setstripe permission (should return error) ==="
8174
8175 test_65g() {
8176         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8177
8178         test_mkdir $DIR/$tdir
8179         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8180
8181         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8182                 error "setstripe -S failed"
8183         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
8184         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8185                 error "delete default stripe failed"
8186 }
8187 run_test 65g "directory setstripe -d"
8188
8189 test_65h() {
8190         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8191
8192         test_mkdir $DIR/$tdir
8193         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8194
8195         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8196                 error "setstripe -S failed"
8197         test_mkdir $DIR/$tdir/dd1
8198         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
8199                 error "stripe info inherit failed"
8200 }
8201 run_test 65h "directory stripe info inherit ===================="
8202
8203 test_65i() {
8204         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8205
8206         save_layout_restore_at_exit $MOUNT
8207
8208         # bug6367: set non-default striping on root directory
8209         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
8210
8211         # bug12836: getstripe on -1 default directory striping
8212         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
8213
8214         # bug12836: getstripe -v on -1 default directory striping
8215         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
8216
8217         # bug12836: new find on -1 default directory striping
8218         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
8219 }
8220 run_test 65i "various tests to set root directory striping"
8221
8222 test_65j() { # bug6367
8223         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8224
8225         sync; sleep 1
8226
8227         # if we aren't already remounting for each test, do so for this test
8228         if [ "$I_MOUNTED" = "yes" ]; then
8229                 cleanup || error "failed to unmount"
8230                 setup
8231         fi
8232
8233         save_layout_restore_at_exit $MOUNT
8234
8235         $LFS setstripe -d $MOUNT || error "setstripe failed"
8236 }
8237 run_test 65j "set default striping on root directory (bug 6367)="
8238
8239 cleanup_65k() {
8240         rm -rf $DIR/$tdir
8241         wait_delete_completed
8242         do_facet $SINGLEMDS "lctl set_param -n \
8243                 osp.$ost*MDT0000.max_create_count=$max_count"
8244         do_facet $SINGLEMDS "lctl set_param -n \
8245                 osp.$ost*MDT0000.create_count=$count"
8246         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8247         echo $INACTIVE_OSC "is Activate"
8248
8249         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8250 }
8251
8252 test_65k() { # bug11679
8253         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8254         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8255         remote_mds_nodsh && skip "remote MDS with nodsh"
8256
8257         local disable_precreate=true
8258         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
8259                 disable_precreate=false
8260
8261         echo "Check OST status: "
8262         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
8263                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
8264
8265         for OSC in $MDS_OSCS; do
8266                 echo $OSC "is active"
8267                 do_facet $SINGLEMDS lctl --device %$OSC activate
8268         done
8269
8270         for INACTIVE_OSC in $MDS_OSCS; do
8271                 local ost=$(osc_to_ost $INACTIVE_OSC)
8272                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
8273                                lov.*md*.target_obd |
8274                                awk -F: /$ost/'{ print $1 }' | head -n 1)
8275
8276                 mkdir -p $DIR/$tdir
8277                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
8278                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
8279
8280                 echo "Deactivate: " $INACTIVE_OSC
8281                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
8282
8283                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
8284                               osp.$ost*MDT0000.create_count")
8285                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
8286                                   osp.$ost*MDT0000.max_create_count")
8287                 $disable_precreate &&
8288                         do_facet $SINGLEMDS "lctl set_param -n \
8289                                 osp.$ost*MDT0000.max_create_count=0"
8290
8291                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
8292                         [ -f $DIR/$tdir/$idx ] && continue
8293                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
8294                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
8295                                 { cleanup_65k;
8296                                   error "setstripe $idx should succeed"; }
8297                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
8298                 done
8299                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
8300                 rmdir $DIR/$tdir
8301
8302                 do_facet $SINGLEMDS "lctl set_param -n \
8303                         osp.$ost*MDT0000.max_create_count=$max_count"
8304                 do_facet $SINGLEMDS "lctl set_param -n \
8305                         osp.$ost*MDT0000.create_count=$count"
8306                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8307                 echo $INACTIVE_OSC "is Activate"
8308
8309                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8310         done
8311 }
8312 run_test 65k "validate manual striping works properly with deactivated OSCs"
8313
8314 test_65l() { # bug 12836
8315         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8316
8317         test_mkdir -p $DIR/$tdir/test_dir
8318         $LFS setstripe -c -1 $DIR/$tdir/test_dir
8319         $LFS find -mtime -1 $DIR/$tdir >/dev/null
8320 }
8321 run_test 65l "lfs find on -1 stripe dir ========================"
8322
8323 test_65m() {
8324         local layout=$(save_layout $MOUNT)
8325         $RUNAS $LFS setstripe -c 2 $MOUNT && {
8326                 restore_layout $MOUNT $layout
8327                 error "setstripe should fail by non-root users"
8328         }
8329         true
8330 }
8331 run_test 65m "normal user can't set filesystem default stripe"
8332
8333 test_65n() {
8334         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
8335         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
8336                 skip "Need MDS version at least 2.12.50"
8337         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8338
8339         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8340         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
8341         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
8342
8343         local root_layout=$(save_layout $MOUNT)
8344         stack_trap "restore_layout $MOUNT $root_layout" EXIT
8345
8346         # new subdirectory under root directory should not inherit
8347         # the default layout from root
8348         local dir1=$MOUNT/$tdir-1
8349         mkdir $dir1 || error "mkdir $dir1 failed"
8350         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
8351                 error "$dir1 shouldn't have LOV EA"
8352
8353         # delete the default layout on root directory
8354         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
8355
8356         local dir2=$MOUNT/$tdir-2
8357         mkdir $dir2 || error "mkdir $dir2 failed"
8358         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
8359                 error "$dir2 shouldn't have LOV EA"
8360
8361         # set a new striping pattern on root directory
8362         local def_stripe_size=$($LFS getstripe -S $MOUNT)
8363         local new_def_stripe_size=$((def_stripe_size * 2))
8364         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
8365                 error "set stripe size on $MOUNT failed"
8366
8367         # new file created in $dir2 should inherit the new stripe size from
8368         # the filesystem default
8369         local file2=$dir2/$tfile-2
8370         touch $file2 || error "touch $file2 failed"
8371
8372         local file2_stripe_size=$($LFS getstripe -S $file2)
8373         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
8374                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
8375
8376         local dir3=$MOUNT/$tdir-3
8377         mkdir $dir3 || error "mkdir $dir3 failed"
8378         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
8379         # the root layout, which is the actual default layout that will be used
8380         # when new files are created in $dir3.
8381         local dir3_layout=$(get_layout_param $dir3)
8382         local root_dir_layout=$(get_layout_param $MOUNT)
8383         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
8384                 error "$dir3 should show the default layout from $MOUNT"
8385
8386         # set OST pool on root directory
8387         local pool=$TESTNAME
8388         pool_add $pool || error "add $pool failed"
8389         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8390                 error "add targets to $pool failed"
8391
8392         $LFS setstripe -p $pool $MOUNT ||
8393                 error "set OST pool on $MOUNT failed"
8394
8395         # new file created in $dir3 should inherit the pool from
8396         # the filesystem default
8397         local file3=$dir3/$tfile-3
8398         touch $file3 || error "touch $file3 failed"
8399
8400         local file3_pool=$($LFS getstripe -p $file3)
8401         [[ "$file3_pool" = "$pool" ]] ||
8402                 error "$file3 didn't inherit OST pool $pool"
8403
8404         local dir4=$MOUNT/$tdir-4
8405         mkdir $dir4 || error "mkdir $dir4 failed"
8406         local dir4_layout=$(get_layout_param $dir4)
8407         root_dir_layout=$(get_layout_param $MOUNT)
8408         echo "$LFS getstripe -d $dir4"
8409         $LFS getstripe -d $dir4
8410         echo "$LFS getstripe -d $MOUNT"
8411         $LFS getstripe -d $MOUNT
8412         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
8413                 error "$dir4 should show the default layout from $MOUNT"
8414
8415         # new file created in $dir4 should inherit the pool from
8416         # the filesystem default
8417         local file4=$dir4/$tfile-4
8418         touch $file4 || error "touch $file4 failed"
8419
8420         local file4_pool=$($LFS getstripe -p $file4)
8421         [[ "$file4_pool" = "$pool" ]] ||
8422                 error "$file4 didn't inherit OST pool $pool"
8423
8424         # new subdirectory under non-root directory should inherit
8425         # the default layout from its parent directory
8426         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
8427                 error "set directory layout on $dir4 failed"
8428
8429         local dir5=$dir4/$tdir-5
8430         mkdir $dir5 || error "mkdir $dir5 failed"
8431
8432         dir4_layout=$(get_layout_param $dir4)
8433         local dir5_layout=$(get_layout_param $dir5)
8434         [[ "$dir4_layout" = "$dir5_layout" ]] ||
8435                 error "$dir5 should inherit the default layout from $dir4"
8436
8437         # though subdir under ROOT doesn't inherit default layout, but
8438         # its sub dir/file should be created with default layout.
8439         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
8440         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
8441                 skip "Need MDS version at least 2.12.59"
8442
8443         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
8444         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
8445         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
8446
8447         if [ $default_lmv_hash == "none" ]; then
8448                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
8449         else
8450                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
8451                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
8452         fi
8453
8454         $LFS setdirstripe -D -c 2 $MOUNT ||
8455                 error "setdirstripe -D -c 2 failed"
8456         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
8457         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
8458         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
8459 }
8460 run_test 65n "don't inherit default layout from root for new subdirectories"
8461
8462 # bug 2543 - update blocks count on client
8463 test_66() {
8464         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8465
8466         COUNT=${COUNT:-8}
8467         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
8468         sync; sync_all_data; sync; sync_all_data
8469         cancel_lru_locks osc
8470         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
8471         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
8472 }
8473 run_test 66 "update inode blocks count on client ==============="
8474
8475 meminfo() {
8476         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
8477 }
8478
8479 swap_used() {
8480         swapon -s | awk '($1 == "'$1'") { print $4 }'
8481 }
8482
8483 # bug5265, obdfilter oa2dentry return -ENOENT
8484 # #define OBD_FAIL_SRV_ENOENT 0x217
8485 test_69() {
8486         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8487         remote_ost_nodsh && skip "remote OST with nodsh"
8488
8489         f="$DIR/$tfile"
8490         $LFS setstripe -c 1 -i 0 $f
8491
8492         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
8493
8494         do_facet ost1 lctl set_param fail_loc=0x217
8495         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
8496         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
8497
8498         do_facet ost1 lctl set_param fail_loc=0
8499         $DIRECTIO write $f 0 2 || error "write error"
8500
8501         cancel_lru_locks osc
8502         $DIRECTIO read $f 0 1 || error "read error"
8503
8504         do_facet ost1 lctl set_param fail_loc=0x217
8505         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
8506
8507         do_facet ost1 lctl set_param fail_loc=0
8508         rm -f $f
8509 }
8510 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
8511
8512 test_71() {
8513         test_mkdir $DIR/$tdir
8514         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
8515         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
8516 }
8517 run_test 71 "Running dbench on lustre (don't segment fault) ===="
8518
8519 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
8520         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8521         [ "$RUNAS_ID" = "$UID" ] &&
8522                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8523         # Check that testing environment is properly set up. Skip if not
8524         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
8525                 skip_env "User $RUNAS_ID does not exist - skipping"
8526
8527         touch $DIR/$tfile
8528         chmod 777 $DIR/$tfile
8529         chmod ug+s $DIR/$tfile
8530         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
8531                 error "$RUNAS dd $DIR/$tfile failed"
8532         # See if we are still setuid/sgid
8533         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8534                 error "S/gid is not dropped on write"
8535         # Now test that MDS is updated too
8536         cancel_lru_locks mdc
8537         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8538                 error "S/gid is not dropped on MDS"
8539         rm -f $DIR/$tfile
8540 }
8541 run_test 72a "Test that remove suid works properly (bug5695) ===="
8542
8543 test_72b() { # bug 24226 -- keep mode setting when size is not changing
8544         local perm
8545
8546         [ "$RUNAS_ID" = "$UID" ] &&
8547                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8548         [ "$RUNAS_ID" -eq 0 ] &&
8549                 skip_env "RUNAS_ID = 0 -- skipping"
8550         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8551         # Check that testing environment is properly set up. Skip if not
8552         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
8553                 skip_env "User $RUNAS_ID does not exist - skipping"
8554
8555         touch $DIR/${tfile}-f{g,u}
8556         test_mkdir $DIR/${tfile}-dg
8557         test_mkdir $DIR/${tfile}-du
8558         chmod 770 $DIR/${tfile}-{f,d}{g,u}
8559         chmod g+s $DIR/${tfile}-{f,d}g
8560         chmod u+s $DIR/${tfile}-{f,d}u
8561         for perm in 777 2777 4777; do
8562                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
8563                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
8564                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
8565                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
8566         done
8567         true
8568 }
8569 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
8570
8571 # bug 3462 - multiple simultaneous MDC requests
8572 test_73() {
8573         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8574
8575         test_mkdir $DIR/d73-1
8576         test_mkdir $DIR/d73-2
8577         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
8578         pid1=$!
8579
8580         lctl set_param fail_loc=0x80000129
8581         $MULTIOP $DIR/d73-1/f73-2 Oc &
8582         sleep 1
8583         lctl set_param fail_loc=0
8584
8585         $MULTIOP $DIR/d73-2/f73-3 Oc &
8586         pid3=$!
8587
8588         kill -USR1 $pid1
8589         wait $pid1 || return 1
8590
8591         sleep 25
8592
8593         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
8594         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
8595         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
8596
8597         rm -rf $DIR/d73-*
8598 }
8599 run_test 73 "multiple MDC requests (should not deadlock)"
8600
8601 test_74a() { # bug 6149, 6184
8602         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8603
8604         touch $DIR/f74a
8605         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8606         #
8607         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8608         # will spin in a tight reconnection loop
8609         $LCTL set_param fail_loc=0x8000030e
8610         # get any lock that won't be difficult - lookup works.
8611         ls $DIR/f74a
8612         $LCTL set_param fail_loc=0
8613         rm -f $DIR/f74a
8614         true
8615 }
8616 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
8617
8618 test_74b() { # bug 13310
8619         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8620
8621         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8622         #
8623         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8624         # will spin in a tight reconnection loop
8625         $LCTL set_param fail_loc=0x8000030e
8626         # get a "difficult" lock
8627         touch $DIR/f74b
8628         $LCTL set_param fail_loc=0
8629         rm -f $DIR/f74b
8630         true
8631 }
8632 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
8633
8634 test_74c() {
8635         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8636
8637         #define OBD_FAIL_LDLM_NEW_LOCK
8638         $LCTL set_param fail_loc=0x319
8639         touch $DIR/$tfile && error "touch successful"
8640         $LCTL set_param fail_loc=0
8641         true
8642 }
8643 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
8644
8645 slab_lic=/sys/kernel/slab/lustre_inode_cache
8646 num_objects() {
8647         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
8648         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
8649                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
8650 }
8651
8652 test_76a() { # Now for b=20433, added originally in b=1443
8653         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8654
8655         cancel_lru_locks osc
8656         # there may be some slab objects cached per core
8657         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
8658         local before=$(num_objects)
8659         local count=$((512 * cpus))
8660         [ "$SLOW" = "no" ] && count=$((128 * cpus))
8661         local margin=$((count / 10))
8662         if [[ -f $slab_lic/aliases ]]; then
8663                 local aliases=$(cat $slab_lic/aliases)
8664                 (( aliases > 0 )) && margin=$((margin * aliases))
8665         fi
8666
8667         echo "before slab objects: $before"
8668         for i in $(seq $count); do
8669                 touch $DIR/$tfile
8670                 rm -f $DIR/$tfile
8671         done
8672         cancel_lru_locks osc
8673         local after=$(num_objects)
8674         echo "created: $count, after slab objects: $after"
8675         # shared slab counts are not very accurate, allow significant margin
8676         # the main goal is that the cache growth is not permanently > $count
8677         while (( after > before + margin )); do
8678                 sleep 1
8679                 after=$(num_objects)
8680                 wait=$((wait + 1))
8681                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
8682                 if (( wait > 60 )); then
8683                         error "inode slab grew from $before+$margin to $after"
8684                 fi
8685         done
8686 }
8687 run_test 76a "confirm clients recycle inodes properly ===="
8688
8689 test_76b() {
8690         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8691         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
8692
8693         local count=512
8694         local before=$(num_objects)
8695
8696         for i in $(seq $count); do
8697                 mkdir $DIR/$tdir
8698                 rmdir $DIR/$tdir
8699         done
8700
8701         local after=$(num_objects)
8702         local wait=0
8703
8704         while (( after > before )); do
8705                 sleep 1
8706                 after=$(num_objects)
8707                 wait=$((wait + 1))
8708                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
8709                 if (( wait > 60 )); then
8710                         error "inode slab grew from $before to $after"
8711                 fi
8712         done
8713
8714         echo "slab objects before: $before, after: $after"
8715 }
8716 run_test 76b "confirm clients recycle directory inodes properly ===="
8717
8718 export ORIG_CSUM=""
8719 set_checksums()
8720 {
8721         # Note: in sptlrpc modes which enable its own bulk checksum, the
8722         # original crc32_le bulk checksum will be automatically disabled,
8723         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
8724         # will be checked by sptlrpc code against sptlrpc bulk checksum.
8725         # In this case set_checksums() will not be no-op, because sptlrpc
8726         # bulk checksum will be enabled all through the test.
8727
8728         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
8729         lctl set_param -n osc.*.checksums $1
8730         return 0
8731 }
8732
8733 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8734                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
8735 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8736                              tr -d [] | head -n1)}
8737 set_checksum_type()
8738 {
8739         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
8740         rc=$?
8741         log "set checksum type to $1, rc = $rc"
8742         return $rc
8743 }
8744
8745 get_osc_checksum_type()
8746 {
8747         # arugment 1: OST name, like OST0000
8748         ost=$1
8749         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
8750                         sed 's/.*\[\(.*\)\].*/\1/g')
8751         rc=$?
8752         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
8753         echo $checksum_type
8754 }
8755
8756 F77_TMP=$TMP/f77-temp
8757 F77SZ=8
8758 setup_f77() {
8759         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
8760                 error "error writing to $F77_TMP"
8761 }
8762
8763 test_77a() { # bug 10889
8764         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8765         $GSS && skip_env "could not run with gss"
8766
8767         [ ! -f $F77_TMP ] && setup_f77
8768         set_checksums 1
8769         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
8770         set_checksums 0
8771         rm -f $DIR/$tfile
8772 }
8773 run_test 77a "normal checksum read/write operation"
8774
8775 test_77b() { # bug 10889
8776         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8777         $GSS && skip_env "could not run with gss"
8778
8779         [ ! -f $F77_TMP ] && setup_f77
8780         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8781         $LCTL set_param fail_loc=0x80000409
8782         set_checksums 1
8783
8784         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8785                 error "dd error: $?"
8786         $LCTL set_param fail_loc=0
8787
8788         for algo in $CKSUM_TYPES; do
8789                 cancel_lru_locks osc
8790                 set_checksum_type $algo
8791                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8792                 $LCTL set_param fail_loc=0x80000408
8793                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
8794                 $LCTL set_param fail_loc=0
8795         done
8796         set_checksums 0
8797         set_checksum_type $ORIG_CSUM_TYPE
8798         rm -f $DIR/$tfile
8799 }
8800 run_test 77b "checksum error on client write, read"
8801
8802 cleanup_77c() {
8803         trap 0
8804         set_checksums 0
8805         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
8806         $check_ost &&
8807                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
8808         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
8809         $check_ost && [ -n "$ost_file_prefix" ] &&
8810                 do_facet ost1 rm -f ${ost_file_prefix}\*
8811 }
8812
8813 test_77c() {
8814         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8815         $GSS && skip_env "could not run with gss"
8816         remote_ost_nodsh && skip "remote OST with nodsh"
8817
8818         local bad1
8819         local osc_file_prefix
8820         local osc_file
8821         local check_ost=false
8822         local ost_file_prefix
8823         local ost_file
8824         local orig_cksum
8825         local dump_cksum
8826         local fid
8827
8828         # ensure corruption will occur on first OSS/OST
8829         $LFS setstripe -i 0 $DIR/$tfile
8830
8831         [ ! -f $F77_TMP ] && setup_f77
8832         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8833                 error "dd write error: $?"
8834         fid=$($LFS path2fid $DIR/$tfile)
8835
8836         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
8837         then
8838                 check_ost=true
8839                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
8840                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
8841         else
8842                 echo "OSS do not support bulk pages dump upon error"
8843         fi
8844
8845         osc_file_prefix=$($LCTL get_param -n debug_path)
8846         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
8847
8848         trap cleanup_77c EXIT
8849
8850         set_checksums 1
8851         # enable bulk pages dump upon error on Client
8852         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
8853         # enable bulk pages dump upon error on OSS
8854         $check_ost &&
8855                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
8856
8857         # flush Client cache to allow next read to reach OSS
8858         cancel_lru_locks osc
8859
8860         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
8861         $LCTL set_param fail_loc=0x80000408
8862         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
8863         $LCTL set_param fail_loc=0
8864
8865         rm -f $DIR/$tfile
8866
8867         # check cksum dump on Client
8868         osc_file=$(ls ${osc_file_prefix}*)
8869         [ -n "$osc_file" ] || error "no checksum dump file on Client"
8870         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
8871         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
8872         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
8873         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
8874                      cksum)
8875         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
8876         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8877                 error "dump content does not match on Client"
8878
8879         $check_ost || skip "No need to check cksum dump on OSS"
8880
8881         # check cksum dump on OSS
8882         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
8883         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
8884         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
8885         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
8886         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8887                 error "dump content does not match on OSS"
8888
8889         cleanup_77c
8890 }
8891 run_test 77c "checksum error on client read with debug"
8892
8893 test_77d() { # bug 10889
8894         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8895         $GSS && skip_env "could not run with gss"
8896
8897         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8898         $LCTL set_param fail_loc=0x80000409
8899         set_checksums 1
8900         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8901                 error "direct write: rc=$?"
8902         $LCTL set_param fail_loc=0
8903         set_checksums 0
8904
8905         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8906         $LCTL set_param fail_loc=0x80000408
8907         set_checksums 1
8908         cancel_lru_locks osc
8909         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8910                 error "direct read: rc=$?"
8911         $LCTL set_param fail_loc=0
8912         set_checksums 0
8913 }
8914 run_test 77d "checksum error on OST direct write, read"
8915
8916 test_77f() { # bug 10889
8917         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8918         $GSS && skip_env "could not run with gss"
8919
8920         set_checksums 1
8921         for algo in $CKSUM_TYPES; do
8922                 cancel_lru_locks osc
8923                 set_checksum_type $algo
8924                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8925                 $LCTL set_param fail_loc=0x409
8926                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
8927                         error "direct write succeeded"
8928                 $LCTL set_param fail_loc=0
8929         done
8930         set_checksum_type $ORIG_CSUM_TYPE
8931         set_checksums 0
8932 }
8933 run_test 77f "repeat checksum error on write (expect error)"
8934
8935 test_77g() { # bug 10889
8936         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8937         $GSS && skip_env "could not run with gss"
8938         remote_ost_nodsh && skip "remote OST with nodsh"
8939
8940         [ ! -f $F77_TMP ] && setup_f77
8941
8942         local file=$DIR/$tfile
8943         stack_trap "rm -f $file" EXIT
8944
8945         $LFS setstripe -c 1 -i 0 $file
8946         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
8947         do_facet ost1 lctl set_param fail_loc=0x8000021a
8948         set_checksums 1
8949         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
8950                 error "write error: rc=$?"
8951         do_facet ost1 lctl set_param fail_loc=0
8952         set_checksums 0
8953
8954         cancel_lru_locks osc
8955         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
8956         do_facet ost1 lctl set_param fail_loc=0x8000021b
8957         set_checksums 1
8958         cmp $F77_TMP $file || error "file compare failed"
8959         do_facet ost1 lctl set_param fail_loc=0
8960         set_checksums 0
8961 }
8962 run_test 77g "checksum error on OST write, read"
8963
8964 test_77k() { # LU-10906
8965         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8966         $GSS && skip_env "could not run with gss"
8967
8968         local cksum_param="osc.$FSNAME*.checksums"
8969         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
8970         local checksum
8971         local i
8972
8973         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
8974         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
8975         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
8976
8977         for i in 0 1; do
8978                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
8979                         error "failed to set checksum=$i on MGS"
8980                 wait_update $HOSTNAME "$get_checksum" $i
8981                 #remount
8982                 echo "remount client, checksum should be $i"
8983                 remount_client $MOUNT || error "failed to remount client"
8984                 checksum=$(eval $get_checksum)
8985                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
8986         done
8987         # remove persistent param to avoid races with checksum mountopt below
8988         do_facet mgs $LCTL set_param -P -d $cksum_param ||
8989                 error "failed to delete checksum on MGS"
8990
8991         for opt in "checksum" "nochecksum"; do
8992                 #remount with mount option
8993                 echo "remount client with option $opt, checksum should be $i"
8994                 umount_client $MOUNT || error "failed to umount client"
8995                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
8996                         error "failed to mount client with option '$opt'"
8997                 checksum=$(eval $get_checksum)
8998                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
8999                 i=$((i - 1))
9000         done
9001
9002         remount_client $MOUNT || error "failed to remount client"
9003 }
9004 run_test 77k "enable/disable checksum correctly"
9005
9006 test_77l() {
9007         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9008         $GSS && skip_env "could not run with gss"
9009
9010         set_checksums 1
9011         stack_trap "set_checksums $ORIG_CSUM" EXIT
9012         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
9013
9014         set_checksum_type invalid && error "unexpected success of invalid checksum type"
9015
9016         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9017         for algo in $CKSUM_TYPES; do
9018                 set_checksum_type $algo || error "fail to set checksum type $algo"
9019                 osc_algo=$(get_osc_checksum_type OST0000)
9020                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
9021
9022                 # no locks, no reqs to let the connection idle
9023                 cancel_lru_locks osc
9024                 lru_resize_disable osc
9025                 wait_osc_import_state client ost1 IDLE
9026
9027                 # ensure ost1 is connected
9028                 stat $DIR/$tfile >/dev/null || error "can't stat"
9029                 wait_osc_import_state client ost1 FULL
9030
9031                 osc_algo=$(get_osc_checksum_type OST0000)
9032                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
9033         done
9034         return 0
9035 }
9036 run_test 77l "preferred checksum type is remembered after reconnected"
9037
9038 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
9039 rm -f $F77_TMP
9040 unset F77_TMP
9041
9042 cleanup_test_78() {
9043         trap 0
9044         rm -f $DIR/$tfile
9045 }
9046
9047 test_78() { # bug 10901
9048         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9049         remote_ost || skip_env "local OST"
9050
9051         NSEQ=5
9052         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
9053         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
9054         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
9055         echo "MemTotal: $MEMTOTAL"
9056
9057         # reserve 256MB of memory for the kernel and other running processes,
9058         # and then take 1/2 of the remaining memory for the read/write buffers.
9059         if [ $MEMTOTAL -gt 512 ] ;then
9060                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
9061         else
9062                 # for those poor memory-starved high-end clusters...
9063                 MEMTOTAL=$((MEMTOTAL / 2))
9064         fi
9065         echo "Mem to use for directio: $MEMTOTAL"
9066
9067         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
9068         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
9069         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
9070         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
9071                 head -n1)
9072         echo "Smallest OST: $SMALLESTOST"
9073         [[ $SMALLESTOST -lt 10240 ]] &&
9074                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
9075
9076         trap cleanup_test_78 EXIT
9077
9078         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
9079                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
9080
9081         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
9082         echo "File size: $F78SIZE"
9083         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
9084         for i in $(seq 1 $NSEQ); do
9085                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
9086                 echo directIO rdwr round $i of $NSEQ
9087                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
9088         done
9089
9090         cleanup_test_78
9091 }
9092 run_test 78 "handle large O_DIRECT writes correctly ============"
9093
9094 test_79() { # bug 12743
9095         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9096
9097         wait_delete_completed
9098
9099         BKTOTAL=$(calc_osc_kbytes kbytestotal)
9100         BKFREE=$(calc_osc_kbytes kbytesfree)
9101         BKAVAIL=$(calc_osc_kbytes kbytesavail)
9102
9103         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
9104         DFTOTAL=`echo $STRING | cut -d, -f1`
9105         DFUSED=`echo $STRING  | cut -d, -f2`
9106         DFAVAIL=`echo $STRING | cut -d, -f3`
9107         DFFREE=$(($DFTOTAL - $DFUSED))
9108
9109         ALLOWANCE=$((64 * $OSTCOUNT))
9110
9111         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
9112            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
9113                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
9114         fi
9115         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
9116            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
9117                 error "df free($DFFREE) mismatch OST free($BKFREE)"
9118         fi
9119         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
9120            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
9121                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
9122         fi
9123 }
9124 run_test 79 "df report consistency check ======================="
9125
9126 test_80() { # bug 10718
9127         remote_ost_nodsh && skip "remote OST with nodsh"
9128         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9129
9130         # relax strong synchronous semantics for slow backends like ZFS
9131         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
9132                 local soc="obdfilter.*.sync_lock_cancel"
9133                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9134
9135                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
9136                 if [ -z "$save" ]; then
9137                         soc="obdfilter.*.sync_on_lock_cancel"
9138                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9139                 fi
9140
9141                 if [ "$save" != "never" ]; then
9142                         local hosts=$(comma_list $(osts_nodes))
9143
9144                         do_nodes $hosts $LCTL set_param $soc=never
9145                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
9146                 fi
9147         fi
9148
9149         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
9150         sync; sleep 1; sync
9151         local before=$(date +%s)
9152         cancel_lru_locks osc
9153         local after=$(date +%s)
9154         local diff=$((after - before))
9155         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
9156
9157         rm -f $DIR/$tfile
9158 }
9159 run_test 80 "Page eviction is equally fast at high offsets too"
9160
9161 test_81a() { # LU-456
9162         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9163         remote_ost_nodsh && skip "remote OST with nodsh"
9164
9165         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9166         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
9167         do_facet ost1 lctl set_param fail_loc=0x80000228
9168
9169         # write should trigger a retry and success
9170         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9171         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9172         RC=$?
9173         if [ $RC -ne 0 ] ; then
9174                 error "write should success, but failed for $RC"
9175         fi
9176 }
9177 run_test 81a "OST should retry write when get -ENOSPC ==============="
9178
9179 test_81b() { # LU-456
9180         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9181         remote_ost_nodsh && skip "remote OST with nodsh"
9182
9183         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9184         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
9185         do_facet ost1 lctl set_param fail_loc=0x228
9186
9187         # write should retry several times and return -ENOSPC finally
9188         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9189         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9190         RC=$?
9191         ENOSPC=28
9192         if [ $RC -ne $ENOSPC ] ; then
9193                 error "dd should fail for -ENOSPC, but succeed."
9194         fi
9195 }
9196 run_test 81b "OST should return -ENOSPC when retry still fails ======="
9197
9198 test_99() {
9199         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
9200
9201         test_mkdir $DIR/$tdir.cvsroot
9202         chown $RUNAS_ID $DIR/$tdir.cvsroot
9203
9204         cd $TMP
9205         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
9206
9207         cd /etc/init.d
9208         # some versions of cvs import exit(1) when asked to import links or
9209         # files they can't read.  ignore those files.
9210         local toignore=$(find . -type l -printf '-I %f\n' -o \
9211                          ! -perm /4 -printf '-I %f\n')
9212         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
9213                 $tdir.reposname vtag rtag
9214
9215         cd $DIR
9216         test_mkdir $DIR/$tdir.reposname
9217         chown $RUNAS_ID $DIR/$tdir.reposname
9218         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
9219
9220         cd $DIR/$tdir.reposname
9221         $RUNAS touch foo99
9222         $RUNAS cvs add -m 'addmsg' foo99
9223         $RUNAS cvs update
9224         $RUNAS cvs commit -m 'nomsg' foo99
9225         rm -fr $DIR/$tdir.cvsroot
9226 }
9227 run_test 99 "cvs strange file/directory operations"
9228
9229 test_100() {
9230         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9231         [[ "$NETTYPE" =~ tcp ]] ||
9232                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
9233         remote_ost_nodsh && skip "remote OST with nodsh"
9234         remote_mds_nodsh && skip "remote MDS with nodsh"
9235         remote_servers ||
9236                 skip "useless for local single node setup"
9237
9238         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
9239                 [ "$PROT" != "tcp" ] && continue
9240                 RPORT=$(echo $REMOTE | cut -d: -f2)
9241                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
9242
9243                 rc=0
9244                 LPORT=`echo $LOCAL | cut -d: -f2`
9245                 if [ $LPORT -ge 1024 ]; then
9246                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
9247                         netstat -tna
9248                         error_exit "local: $LPORT > 1024, remote: $RPORT"
9249                 fi
9250         done
9251         [ "$rc" = 0 ] || error_exit "privileged port not found" )
9252 }
9253 run_test 100 "check local port using privileged port ==========="
9254
9255 function get_named_value()
9256 {
9257     local tag
9258
9259     tag=$1
9260     while read ;do
9261         line=$REPLY
9262         case $line in
9263         $tag*)
9264             echo $line | sed "s/^$tag[ ]*//"
9265             break
9266             ;;
9267         esac
9268     done
9269 }
9270
9271 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
9272                    awk '/^max_cached_mb/ { print $2 }')
9273
9274 cleanup_101a() {
9275         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
9276         trap 0
9277 }
9278
9279 test_101a() {
9280         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9281
9282         local s
9283         local discard
9284         local nreads=10000
9285         local cache_limit=32
9286
9287         $LCTL set_param -n osc.*-osc*.rpc_stats 0
9288         trap cleanup_101a EXIT
9289         $LCTL set_param -n llite.*.read_ahead_stats 0
9290         $LCTL set_param -n llite.*.max_cached_mb $cache_limit
9291
9292         #
9293         # randomly read 10000 of 64K chunks from file 3x 32MB in size
9294         #
9295         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
9296         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
9297
9298         discard=0
9299         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
9300                 get_named_value 'read but discarded' | cut -d" " -f1); do
9301                         discard=$(($discard + $s))
9302         done
9303         cleanup_101a
9304
9305         $LCTL get_param osc.*-osc*.rpc_stats
9306         $LCTL get_param llite.*.read_ahead_stats
9307
9308         # Discard is generally zero, but sometimes a few random reads line up
9309         # and trigger larger readahead, which is wasted & leads to discards.
9310         if [[ $(($discard)) -gt $nreads ]]; then
9311                 error "too many ($discard) discarded pages"
9312         fi
9313         rm -f $DIR/$tfile || true
9314 }
9315 run_test 101a "check read-ahead for random reads"
9316
9317 setup_test101bc() {
9318         test_mkdir $DIR/$tdir
9319         local ssize=$1
9320         local FILE_LENGTH=$2
9321         STRIPE_OFFSET=0
9322
9323         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
9324
9325         local list=$(comma_list $(osts_nodes))
9326         set_osd_param $list '' read_cache_enable 0
9327         set_osd_param $list '' writethrough_cache_enable 0
9328
9329         trap cleanup_test101bc EXIT
9330         # prepare the read-ahead file
9331         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
9332
9333         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
9334                                 count=$FILE_SIZE_MB 2> /dev/null
9335
9336 }
9337
9338 cleanup_test101bc() {
9339         trap 0
9340         rm -rf $DIR/$tdir
9341         rm -f $DIR/$tfile
9342
9343         local list=$(comma_list $(osts_nodes))
9344         set_osd_param $list '' read_cache_enable 1
9345         set_osd_param $list '' writethrough_cache_enable 1
9346 }
9347
9348 calc_total() {
9349         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
9350 }
9351
9352 ra_check_101() {
9353         local READ_SIZE=$1
9354         local STRIPE_SIZE=$2
9355         local FILE_LENGTH=$3
9356         local RA_INC=1048576
9357         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
9358         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
9359                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
9360         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
9361                         get_named_value 'read but discarded' |
9362                         cut -d" " -f1 | calc_total)
9363         if [[ $DISCARD -gt $discard_limit ]]; then
9364                 $LCTL get_param llite.*.read_ahead_stats
9365                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
9366         else
9367                 echo "Read-ahead success for size ${READ_SIZE}"
9368         fi
9369 }
9370
9371 test_101b() {
9372         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9373         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9374
9375         local STRIPE_SIZE=1048576
9376         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
9377
9378         if [ $SLOW == "yes" ]; then
9379                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
9380         else
9381                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
9382         fi
9383
9384         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
9385
9386         # prepare the read-ahead file
9387         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9388         cancel_lru_locks osc
9389         for BIDX in 2 4 8 16 32 64 128 256
9390         do
9391                 local BSIZE=$((BIDX*4096))
9392                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
9393                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
9394                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
9395                 $LCTL set_param -n llite.*.read_ahead_stats 0
9396                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
9397                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
9398                 cancel_lru_locks osc
9399                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
9400         done
9401         cleanup_test101bc
9402         true
9403 }
9404 run_test 101b "check stride-io mode read-ahead ================="
9405
9406 test_101c() {
9407         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9408
9409         local STRIPE_SIZE=1048576
9410         local FILE_LENGTH=$((STRIPE_SIZE*100))
9411         local nreads=10000
9412         local rsize=65536
9413         local osc_rpc_stats
9414
9415         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9416
9417         cancel_lru_locks osc
9418         $LCTL set_param osc.*.rpc_stats 0
9419         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
9420         $LCTL get_param osc.*.rpc_stats
9421         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
9422                 local stats=$($LCTL get_param -n $osc_rpc_stats)
9423                 local lines=$(echo "$stats" | awk 'END {print NR;}')
9424                 local size
9425
9426                 if [ $lines -le 20 ]; then
9427                         echo "continue debug"
9428                         continue
9429                 fi
9430                 for size in 1 2 4 8; do
9431                         local rpc=$(echo "$stats" |
9432                                     awk '($1 == "'$size':") {print $2; exit; }')
9433                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
9434                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
9435                 done
9436                 echo "$osc_rpc_stats check passed!"
9437         done
9438         cleanup_test101bc
9439         true
9440 }
9441 run_test 101c "check stripe_size aligned read-ahead ================="
9442
9443 test_101d() {
9444         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9445
9446         local file=$DIR/$tfile
9447         local sz_MB=${FILESIZE_101d:-80}
9448         local ra_MB=${READAHEAD_MB:-40}
9449
9450         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
9451         [ $free_MB -lt $sz_MB ] &&
9452                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
9453
9454         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
9455         $LFS setstripe -c -1 $file || error "setstripe failed"
9456
9457         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
9458         echo Cancel LRU locks on lustre client to flush the client cache
9459         cancel_lru_locks osc
9460
9461         echo Disable read-ahead
9462         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9463         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9464         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_RA" EXIT
9465         $LCTL get_param -n llite.*.max_read_ahead_mb
9466
9467         echo "Reading the test file $file with read-ahead disabled"
9468         local sz_KB=$((sz_MB * 1024 / 4))
9469         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
9470         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
9471         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9472                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9473
9474         echo "Cancel LRU locks on lustre client to flush the client cache"
9475         cancel_lru_locks osc
9476         echo Enable read-ahead with ${ra_MB}MB
9477         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
9478
9479         echo "Reading the test file $file with read-ahead enabled"
9480         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9481                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9482
9483         echo "read-ahead disabled time read $raOFF"
9484         echo "read-ahead enabled time read $raON"
9485
9486         rm -f $file
9487         wait_delete_completed
9488
9489         # use awk for this check instead of bash because it handles decimals
9490         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
9491                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
9492 }
9493 run_test 101d "file read with and without read-ahead enabled"
9494
9495 test_101e() {
9496         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9497
9498         local file=$DIR/$tfile
9499         local size_KB=500  #KB
9500         local count=100
9501         local bsize=1024
9502
9503         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
9504         local need_KB=$((count * size_KB))
9505         [[ $free_KB -le $need_KB ]] &&
9506                 skip_env "Need free space $need_KB, have $free_KB"
9507
9508         echo "Creating $count ${size_KB}K test files"
9509         for ((i = 0; i < $count; i++)); do
9510                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
9511         done
9512
9513         echo "Cancel LRU locks on lustre client to flush the client cache"
9514         cancel_lru_locks $OSC
9515
9516         echo "Reset readahead stats"
9517         $LCTL set_param -n llite.*.read_ahead_stats 0
9518
9519         for ((i = 0; i < $count; i++)); do
9520                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
9521         done
9522
9523         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9524                      get_named_value 'misses' | cut -d" " -f1 | calc_total)
9525
9526         for ((i = 0; i < $count; i++)); do
9527                 rm -rf $file.$i 2>/dev/null
9528         done
9529
9530         #10000 means 20% reads are missing in readahead
9531         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
9532 }
9533 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
9534
9535 test_101f() {
9536         which iozone || skip_env "no iozone installed"
9537
9538         local old_debug=$($LCTL get_param debug)
9539         old_debug=${old_debug#*=}
9540         $LCTL set_param debug="reada mmap"
9541
9542         # create a test file
9543         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
9544
9545         echo Cancel LRU locks on lustre client to flush the client cache
9546         cancel_lru_locks osc
9547
9548         echo Reset readahead stats
9549         $LCTL set_param -n llite.*.read_ahead_stats 0
9550
9551         echo mmap read the file with small block size
9552         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
9553                 > /dev/null 2>&1
9554
9555         echo checking missing pages
9556         $LCTL get_param llite.*.read_ahead_stats
9557         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9558                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9559
9560         $LCTL set_param debug="$old_debug"
9561         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
9562         rm -f $DIR/$tfile
9563 }
9564 run_test 101f "check mmap read performance"
9565
9566 test_101g_brw_size_test() {
9567         local mb=$1
9568         local pages=$((mb * 1048576 / PAGE_SIZE))
9569         local file=$DIR/$tfile
9570
9571         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
9572                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
9573         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
9574                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
9575                         return 2
9576         done
9577
9578         stack_trap "rm -f $file" EXIT
9579         $LCTL set_param -n osc.*.rpc_stats=0
9580
9581         # 10 RPCs should be enough for the test
9582         local count=10
9583         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
9584                 { error "dd write ${mb} MB blocks failed"; return 3; }
9585         cancel_lru_locks osc
9586         dd of=/dev/null if=$file bs=${mb}M count=$count ||
9587                 { error "dd write ${mb} MB blocks failed"; return 4; }
9588
9589         # calculate number of full-sized read and write RPCs
9590         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
9591                 sed -n '/pages per rpc/,/^$/p' |
9592                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
9593                 END { print reads,writes }'))
9594         # allow one extra full-sized read RPC for async readahead
9595         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
9596                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
9597         [[ ${rpcs[1]} == $count ]] ||
9598                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
9599 }
9600
9601 test_101g() {
9602         remote_ost_nodsh && skip "remote OST with nodsh"
9603
9604         local rpcs
9605         local osts=$(get_facets OST)
9606         local list=$(comma_list $(osts_nodes))
9607         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9608         local brw_size="obdfilter.*.brw_size"
9609
9610         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9611
9612         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
9613
9614         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
9615                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
9616                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
9617            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
9618                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
9619                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
9620
9621                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
9622                         suffix="M"
9623
9624                 if [[ $orig_mb -lt 16 ]]; then
9625                         save_lustre_params $osts "$brw_size" > $p
9626                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
9627                                 error "set 16MB RPC size failed"
9628
9629                         echo "remount client to enable new RPC size"
9630                         remount_client $MOUNT || error "remount_client failed"
9631                 fi
9632
9633                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
9634                 # should be able to set brw_size=12, but no rpc_stats for that
9635                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
9636         fi
9637
9638         test_101g_brw_size_test 4 || error "4MB RPC test failed"
9639
9640         if [[ $orig_mb -lt 16 ]]; then
9641                 restore_lustre_params < $p
9642                 remount_client $MOUNT || error "remount_client restore failed"
9643         fi
9644
9645         rm -f $p $DIR/$tfile
9646 }
9647 run_test 101g "Big bulk(4/16 MiB) readahead"
9648
9649 test_101h() {
9650         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9651
9652         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
9653                 error "dd 70M file failed"
9654         echo Cancel LRU locks on lustre client to flush the client cache
9655         cancel_lru_locks osc
9656
9657         echo "Reset readahead stats"
9658         $LCTL set_param -n llite.*.read_ahead_stats 0
9659
9660         echo "Read 10M of data but cross 64M bundary"
9661         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
9662         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9663                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9664         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
9665         rm -f $p $DIR/$tfile
9666 }
9667 run_test 101h "Readahead should cover current read window"
9668
9669 test_101i() {
9670         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
9671                 error "dd 10M file failed"
9672
9673         local max_per_file_mb=$($LCTL get_param -n \
9674                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
9675         cancel_lru_locks osc
9676         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
9677         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
9678                 error "set max_read_ahead_per_file_mb to 1 failed"
9679
9680         echo "Reset readahead stats"
9681         $LCTL set_param llite.*.read_ahead_stats=0
9682
9683         dd if=$DIR/$tfile of=/dev/null bs=2M
9684
9685         $LCTL get_param llite.*.read_ahead_stats
9686         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9687                      awk '/misses/ { print $2 }')
9688         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
9689         rm -f $DIR/$tfile
9690 }
9691 run_test 101i "allow current readahead to exceed reservation"
9692
9693 test_101j() {
9694         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
9695                 error "setstripe $DIR/$tfile failed"
9696         local file_size=$((1048576 * 16))
9697         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9698         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
9699
9700         echo Disable read-ahead
9701         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9702
9703         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
9704         for blk in $PAGE_SIZE 1048576 $file_size; do
9705                 cancel_lru_locks osc
9706                 echo "Reset readahead stats"
9707                 $LCTL set_param -n llite.*.read_ahead_stats=0
9708                 local count=$(($file_size / $blk))
9709                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
9710                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9711                              get_named_value 'failed to fast read' |
9712                              cut -d" " -f1 | calc_total)
9713                 $LCTL get_param -n llite.*.read_ahead_stats
9714                 [ $miss -eq $count ] || error "expected $count got $miss"
9715         done
9716
9717         rm -f $p $DIR/$tfile
9718 }
9719 run_test 101j "A complete read block should be submitted when no RA"
9720
9721 setup_test102() {
9722         test_mkdir $DIR/$tdir
9723         chown $RUNAS_ID $DIR/$tdir
9724         STRIPE_SIZE=65536
9725         STRIPE_OFFSET=1
9726         STRIPE_COUNT=$OSTCOUNT
9727         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
9728
9729         trap cleanup_test102 EXIT
9730         cd $DIR
9731         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
9732         cd $DIR/$tdir
9733         for num in 1 2 3 4; do
9734                 for count in $(seq 1 $STRIPE_COUNT); do
9735                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
9736                                 local size=`expr $STRIPE_SIZE \* $num`
9737                                 local file=file"$num-$idx-$count"
9738                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
9739                         done
9740                 done
9741         done
9742
9743         cd $DIR
9744         $1 tar cf $TMP/f102.tar $tdir --xattrs
9745 }
9746
9747 cleanup_test102() {
9748         trap 0
9749         rm -f $TMP/f102.tar
9750         rm -rf $DIR/d0.sanity/d102
9751 }
9752
9753 test_102a() {
9754         [ "$UID" != 0 ] && skip "must run as root"
9755         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
9756                 skip_env "must have user_xattr"
9757
9758         [ -z "$(which setfattr 2>/dev/null)" ] &&
9759                 skip_env "could not find setfattr"
9760
9761         local testfile=$DIR/$tfile
9762
9763         touch $testfile
9764         echo "set/get xattr..."
9765         setfattr -n trusted.name1 -v value1 $testfile ||
9766                 error "setfattr -n trusted.name1=value1 $testfile failed"
9767         getfattr -n trusted.name1 $testfile 2> /dev/null |
9768           grep "trusted.name1=.value1" ||
9769                 error "$testfile missing trusted.name1=value1"
9770
9771         setfattr -n user.author1 -v author1 $testfile ||
9772                 error "setfattr -n user.author1=author1 $testfile failed"
9773         getfattr -n user.author1 $testfile 2> /dev/null |
9774           grep "user.author1=.author1" ||
9775                 error "$testfile missing trusted.author1=author1"
9776
9777         echo "listxattr..."
9778         setfattr -n trusted.name2 -v value2 $testfile ||
9779                 error "$testfile unable to set trusted.name2"
9780         setfattr -n trusted.name3 -v value3 $testfile ||
9781                 error "$testfile unable to set trusted.name3"
9782         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
9783             grep "trusted.name" | wc -l) -eq 3 ] ||
9784                 error "$testfile missing 3 trusted.name xattrs"
9785
9786         setfattr -n user.author2 -v author2 $testfile ||
9787                 error "$testfile unable to set user.author2"
9788         setfattr -n user.author3 -v author3 $testfile ||
9789                 error "$testfile unable to set user.author3"
9790         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
9791             grep "user.author" | wc -l) -eq 3 ] ||
9792                 error "$testfile missing 3 user.author xattrs"
9793
9794         echo "remove xattr..."
9795         setfattr -x trusted.name1 $testfile ||
9796                 error "$testfile error deleting trusted.name1"
9797         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
9798                 error "$testfile did not delete trusted.name1 xattr"
9799
9800         setfattr -x user.author1 $testfile ||
9801                 error "$testfile error deleting user.author1"
9802         echo "set lustre special xattr ..."
9803         $LFS setstripe -c1 $testfile
9804         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
9805                 awk -F "=" '/trusted.lov/ { print $2 }' )
9806         setfattr -n "trusted.lov" -v $lovea $testfile ||
9807                 error "$testfile doesn't ignore setting trusted.lov again"
9808         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
9809                 error "$testfile allow setting invalid trusted.lov"
9810         rm -f $testfile
9811 }
9812 run_test 102a "user xattr test =================================="
9813
9814 check_102b_layout() {
9815         local layout="$*"
9816         local testfile=$DIR/$tfile
9817
9818         echo "test layout '$layout'"
9819         $LFS setstripe $layout $testfile || error "setstripe failed"
9820         $LFS getstripe -y $testfile
9821
9822         echo "get/set/list trusted.lov xattr ..." # b=10930
9823         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
9824         [[ "$value" =~ "trusted.lov" ]] ||
9825                 error "can't get trusted.lov from $testfile"
9826         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
9827                 error "getstripe failed"
9828
9829         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
9830
9831         value=$(cut -d= -f2 <<<$value)
9832         # LU-13168: truncated xattr should fail if short lov_user_md header
9833         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
9834                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
9835         for len in $lens; do
9836                 echo "setfattr $len $testfile.2"
9837                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
9838                         [ $len -lt 66 ] && error "short xattr len=$len worked"
9839         done
9840         local stripe_size=$($LFS getstripe -S $testfile.2)
9841         local stripe_count=$($LFS getstripe -c $testfile.2)
9842         [[ $stripe_size -eq 65536 ]] ||
9843                 error "stripe size $stripe_size != 65536"
9844         [[ $stripe_count -eq $stripe_count_orig ]] ||
9845                 error "stripe count $stripe_count != $stripe_count_orig"
9846         rm $testfile $testfile.2
9847 }
9848
9849 test_102b() {
9850         [ -z "$(which setfattr 2>/dev/null)" ] &&
9851                 skip_env "could not find setfattr"
9852         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9853
9854         # check plain layout
9855         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
9856
9857         # and also check composite layout
9858         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
9859
9860 }
9861 run_test 102b "getfattr/setfattr for trusted.lov EAs"
9862
9863 test_102c() {
9864         [ -z "$(which setfattr 2>/dev/null)" ] &&
9865                 skip_env "could not find setfattr"
9866         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9867
9868         # b10930: get/set/list lustre.lov xattr
9869         echo "get/set/list lustre.lov xattr ..."
9870         test_mkdir $DIR/$tdir
9871         chown $RUNAS_ID $DIR/$tdir
9872         local testfile=$DIR/$tdir/$tfile
9873         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
9874                 error "setstripe failed"
9875         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
9876                 error "getstripe failed"
9877         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
9878         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
9879
9880         local testfile2=${testfile}2
9881         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
9882                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
9883
9884         $RUNAS $MCREATE $testfile2
9885         $RUNAS setfattr -n lustre.lov -v $value $testfile2
9886         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
9887         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
9888         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
9889         [ $stripe_count -eq $STRIPECOUNT ] ||
9890                 error "stripe count $stripe_count != $STRIPECOUNT"
9891 }
9892 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
9893
9894 compare_stripe_info1() {
9895         local stripe_index_all_zero=true
9896
9897         for num in 1 2 3 4; do
9898                 for count in $(seq 1 $STRIPE_COUNT); do
9899                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
9900                                 local size=$((STRIPE_SIZE * num))
9901                                 local file=file"$num-$offset-$count"
9902                                 stripe_size=$($LFS getstripe -S $PWD/$file)
9903                                 [[ $stripe_size -ne $size ]] &&
9904                                     error "$file: size $stripe_size != $size"
9905                                 stripe_count=$($LFS getstripe -c $PWD/$file)
9906                                 # allow fewer stripes to be created, ORI-601
9907                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
9908                                     error "$file: count $stripe_count != $count"
9909                                 stripe_index=$($LFS getstripe -i $PWD/$file)
9910                                 [[ $stripe_index -ne 0 ]] &&
9911                                         stripe_index_all_zero=false
9912                         done
9913                 done
9914         done
9915         $stripe_index_all_zero &&
9916                 error "all files are being extracted starting from OST index 0"
9917         return 0
9918 }
9919
9920 have_xattrs_include() {
9921         tar --help | grep -q xattrs-include &&
9922                 echo --xattrs-include="lustre.*"
9923 }
9924
9925 test_102d() {
9926         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9927         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9928
9929         XINC=$(have_xattrs_include)
9930         setup_test102
9931         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
9932         cd $DIR/$tdir/$tdir
9933         compare_stripe_info1
9934 }
9935 run_test 102d "tar restore stripe info from tarfile,not keep osts"
9936
9937 test_102f() {
9938         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9939         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9940
9941         XINC=$(have_xattrs_include)
9942         setup_test102
9943         test_mkdir $DIR/$tdir.restore
9944         cd $DIR
9945         tar cf - --xattrs $tdir | tar xf - \
9946                 -C $DIR/$tdir.restore --xattrs $XINC
9947         cd $DIR/$tdir.restore/$tdir
9948         compare_stripe_info1
9949 }
9950 run_test 102f "tar copy files, not keep osts"
9951
9952 grow_xattr() {
9953         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
9954                 skip "must have user_xattr"
9955         [ -z "$(which setfattr 2>/dev/null)" ] &&
9956                 skip_env "could not find setfattr"
9957         [ -z "$(which getfattr 2>/dev/null)" ] &&
9958                 skip_env "could not find getfattr"
9959
9960         local xsize=${1:-1024}  # in bytes
9961         local file=$DIR/$tfile
9962         local value="$(generate_string $xsize)"
9963         local xbig=trusted.big
9964         local toobig=$2
9965
9966         touch $file
9967         log "save $xbig on $file"
9968         if [ -z "$toobig" ]
9969         then
9970                 setfattr -n $xbig -v $value $file ||
9971                         error "saving $xbig on $file failed"
9972         else
9973                 setfattr -n $xbig -v $value $file &&
9974                         error "saving $xbig on $file succeeded"
9975                 return 0
9976         fi
9977
9978         local orig=$(get_xattr_value $xbig $file)
9979         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
9980
9981         local xsml=trusted.sml
9982         log "save $xsml on $file"
9983         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
9984
9985         local new=$(get_xattr_value $xbig $file)
9986         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
9987
9988         log "grow $xsml on $file"
9989         setfattr -n $xsml -v "$value" $file ||
9990                 error "growing $xsml on $file failed"
9991
9992         new=$(get_xattr_value $xbig $file)
9993         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
9994         log "$xbig still valid after growing $xsml"
9995
9996         rm -f $file
9997 }
9998
9999 test_102h() { # bug 15777
10000         grow_xattr 1024
10001 }
10002 run_test 102h "grow xattr from inside inode to external block"
10003
10004 test_102ha() {
10005         large_xattr_enabled || skip_env "ea_inode feature disabled"
10006
10007         echo "setting xattr of max xattr size: $(max_xattr_size)"
10008         grow_xattr $(max_xattr_size)
10009
10010         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
10011         echo "This should fail:"
10012         grow_xattr $(($(max_xattr_size) + 10)) 1
10013 }
10014 run_test 102ha "grow xattr from inside inode to external inode"
10015
10016 test_102i() { # bug 17038
10017         [ -z "$(which getfattr 2>/dev/null)" ] &&
10018                 skip "could not find getfattr"
10019
10020         touch $DIR/$tfile
10021         ln -s $DIR/$tfile $DIR/${tfile}link
10022         getfattr -n trusted.lov $DIR/$tfile ||
10023                 error "lgetxattr on $DIR/$tfile failed"
10024         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
10025                 grep -i "no such attr" ||
10026                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
10027         rm -f $DIR/$tfile $DIR/${tfile}link
10028 }
10029 run_test 102i "lgetxattr test on symbolic link ============"
10030
10031 test_102j() {
10032         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10033         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10034
10035         XINC=$(have_xattrs_include)
10036         setup_test102 "$RUNAS"
10037         chown $RUNAS_ID $DIR/$tdir
10038         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10039         cd $DIR/$tdir/$tdir
10040         compare_stripe_info1 "$RUNAS"
10041 }
10042 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
10043
10044 test_102k() {
10045         [ -z "$(which setfattr 2>/dev/null)" ] &&
10046                 skip "could not find setfattr"
10047
10048         touch $DIR/$tfile
10049         # b22187 just check that does not crash for regular file.
10050         setfattr -n trusted.lov $DIR/$tfile
10051         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
10052         local test_kdir=$DIR/$tdir
10053         test_mkdir $test_kdir
10054         local default_size=$($LFS getstripe -S $test_kdir)
10055         local default_count=$($LFS getstripe -c $test_kdir)
10056         local default_offset=$($LFS getstripe -i $test_kdir)
10057         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
10058                 error 'dir setstripe failed'
10059         setfattr -n trusted.lov $test_kdir
10060         local stripe_size=$($LFS getstripe -S $test_kdir)
10061         local stripe_count=$($LFS getstripe -c $test_kdir)
10062         local stripe_offset=$($LFS getstripe -i $test_kdir)
10063         [ $stripe_size -eq $default_size ] ||
10064                 error "stripe size $stripe_size != $default_size"
10065         [ $stripe_count -eq $default_count ] ||
10066                 error "stripe count $stripe_count != $default_count"
10067         [ $stripe_offset -eq $default_offset ] ||
10068                 error "stripe offset $stripe_offset != $default_offset"
10069         rm -rf $DIR/$tfile $test_kdir
10070 }
10071 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
10072
10073 test_102l() {
10074         [ -z "$(which getfattr 2>/dev/null)" ] &&
10075                 skip "could not find getfattr"
10076
10077         # LU-532 trusted. xattr is invisible to non-root
10078         local testfile=$DIR/$tfile
10079
10080         touch $testfile
10081
10082         echo "listxattr as user..."
10083         chown $RUNAS_ID $testfile
10084         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
10085             grep -q "trusted" &&
10086                 error "$testfile trusted xattrs are user visible"
10087
10088         return 0;
10089 }
10090 run_test 102l "listxattr size test =================================="
10091
10092 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
10093         local path=$DIR/$tfile
10094         touch $path
10095
10096         listxattr_size_check $path || error "listattr_size_check $path failed"
10097 }
10098 run_test 102m "Ensure listxattr fails on small bufffer ========"
10099
10100 cleanup_test102
10101
10102 getxattr() { # getxattr path name
10103         # Return the base64 encoding of the value of xattr name on path.
10104         local path=$1
10105         local name=$2
10106
10107         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
10108         # file: $path
10109         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10110         #
10111         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10112
10113         getfattr --absolute-names --encoding=base64 --name=$name $path |
10114                 awk -F= -v name=$name '$1 == name {
10115                         print substr($0, index($0, "=") + 1);
10116         }'
10117 }
10118
10119 test_102n() { # LU-4101 mdt: protect internal xattrs
10120         [ -z "$(which setfattr 2>/dev/null)" ] &&
10121                 skip "could not find setfattr"
10122         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
10123         then
10124                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
10125         fi
10126
10127         local file0=$DIR/$tfile.0
10128         local file1=$DIR/$tfile.1
10129         local xattr0=$TMP/$tfile.0
10130         local xattr1=$TMP/$tfile.1
10131         local namelist="lov lma lmv link fid version som hsm"
10132         local name
10133         local value
10134
10135         rm -rf $file0 $file1 $xattr0 $xattr1
10136         touch $file0 $file1
10137
10138         # Get 'before' xattrs of $file1.
10139         getfattr --absolute-names --dump --match=- $file1 > $xattr0
10140
10141         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
10142                 namelist+=" lfsck_namespace"
10143         for name in $namelist; do
10144                 # Try to copy xattr from $file0 to $file1.
10145                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10146
10147                 setfattr --name=trusted.$name --value="$value" $file1 ||
10148                         error "setxattr 'trusted.$name' failed"
10149
10150                 # Try to set a garbage xattr.
10151                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10152
10153                 if [[ x$name == "xlov" ]]; then
10154                         setfattr --name=trusted.lov --value="$value" $file1 &&
10155                         error "setxattr invalid 'trusted.lov' success"
10156                 else
10157                         setfattr --name=trusted.$name --value="$value" $file1 ||
10158                                 error "setxattr invalid 'trusted.$name' failed"
10159                 fi
10160
10161                 # Try to remove the xattr from $file1. We don't care if this
10162                 # appears to succeed or fail, we just don't want there to be
10163                 # any changes or crashes.
10164                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10165         done
10166
10167         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
10168         then
10169                 name="lfsck_ns"
10170                 # Try to copy xattr from $file0 to $file1.
10171                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10172
10173                 setfattr --name=trusted.$name --value="$value" $file1 ||
10174                         error "setxattr 'trusted.$name' failed"
10175
10176                 # Try to set a garbage xattr.
10177                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10178
10179                 setfattr --name=trusted.$name --value="$value" $file1 ||
10180                         error "setxattr 'trusted.$name' failed"
10181
10182                 # Try to remove the xattr from $file1. We don't care if this
10183                 # appears to succeed or fail, we just don't want there to be
10184                 # any changes or crashes.
10185                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10186         fi
10187
10188         # Get 'after' xattrs of file1.
10189         getfattr --absolute-names --dump --match=- $file1 > $xattr1
10190
10191         if ! diff $xattr0 $xattr1; then
10192                 error "before and after xattrs of '$file1' differ"
10193         fi
10194
10195         rm -rf $file0 $file1 $xattr0 $xattr1
10196
10197         return 0
10198 }
10199 run_test 102n "silently ignore setxattr on internal trusted xattrs"
10200
10201 test_102p() { # LU-4703 setxattr did not check ownership
10202         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
10203                 skip "MDS needs to be at least 2.5.56"
10204
10205         local testfile=$DIR/$tfile
10206
10207         touch $testfile
10208
10209         echo "setfacl as user..."
10210         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
10211         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
10212
10213         echo "setfattr as user..."
10214         setfacl -m "u:$RUNAS_ID:---" $testfile
10215         $RUNAS setfattr -x system.posix_acl_access $testfile
10216         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
10217 }
10218 run_test 102p "check setxattr(2) correctly fails without permission"
10219
10220 test_102q() {
10221         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
10222                 skip "MDS needs to be at least 2.6.92"
10223
10224         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
10225 }
10226 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
10227
10228 test_102r() {
10229         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
10230                 skip "MDS needs to be at least 2.6.93"
10231
10232         touch $DIR/$tfile || error "touch"
10233         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
10234         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
10235         rm $DIR/$tfile || error "rm"
10236
10237         #normal directory
10238         mkdir -p $DIR/$tdir || error "mkdir"
10239         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10240         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10241         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10242                 error "$testfile error deleting user.author1"
10243         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10244                 grep "user.$(basename $tdir)" &&
10245                 error "$tdir did not delete user.$(basename $tdir)"
10246         rmdir $DIR/$tdir || error "rmdir"
10247
10248         #striped directory
10249         test_mkdir $DIR/$tdir
10250         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10251         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10252         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10253                 error "$testfile error deleting user.author1"
10254         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10255                 grep "user.$(basename $tdir)" &&
10256                 error "$tdir did not delete user.$(basename $tdir)"
10257         rmdir $DIR/$tdir || error "rm striped dir"
10258 }
10259 run_test 102r "set EAs with empty values"
10260
10261 test_102s() {
10262         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10263                 skip "MDS needs to be at least 2.11.52"
10264
10265         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10266
10267         save_lustre_params client "llite.*.xattr_cache" > $save
10268
10269         for cache in 0 1; do
10270                 lctl set_param llite.*.xattr_cache=$cache
10271
10272                 rm -f $DIR/$tfile
10273                 touch $DIR/$tfile || error "touch"
10274                 for prefix in lustre security system trusted user; do
10275                         # Note getxattr() may fail with 'Operation not
10276                         # supported' or 'No such attribute' depending
10277                         # on prefix and cache.
10278                         getfattr -n $prefix.n102s $DIR/$tfile &&
10279                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
10280                 done
10281         done
10282
10283         restore_lustre_params < $save
10284 }
10285 run_test 102s "getting nonexistent xattrs should fail"
10286
10287 test_102t() {
10288         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10289                 skip "MDS needs to be at least 2.11.52"
10290
10291         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10292
10293         save_lustre_params client "llite.*.xattr_cache" > $save
10294
10295         for cache in 0 1; do
10296                 lctl set_param llite.*.xattr_cache=$cache
10297
10298                 for buf_size in 0 256; do
10299                         rm -f $DIR/$tfile
10300                         touch $DIR/$tfile || error "touch"
10301                         setfattr -n user.multiop $DIR/$tfile
10302                         $MULTIOP $DIR/$tfile oa$buf_size ||
10303                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
10304                 done
10305         done
10306
10307         restore_lustre_params < $save
10308 }
10309 run_test 102t "zero length xattr values handled correctly"
10310
10311 run_acl_subtest()
10312 {
10313     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
10314     return $?
10315 }
10316
10317 test_103a() {
10318         [ "$UID" != 0 ] && skip "must run as root"
10319         $GSS && skip_env "could not run under gss"
10320         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
10321                 skip_env "must have acl enabled"
10322         [ -z "$(which setfacl 2>/dev/null)" ] &&
10323                 skip_env "could not find setfacl"
10324         remote_mds_nodsh && skip "remote MDS with nodsh"
10325
10326         gpasswd -a daemon bin                           # LU-5641
10327         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
10328
10329         declare -a identity_old
10330
10331         for num in $(seq $MDSCOUNT); do
10332                 switch_identity $num true || identity_old[$num]=$?
10333         done
10334
10335         SAVE_UMASK=$(umask)
10336         umask 0022
10337         mkdir -p $DIR/$tdir
10338         cd $DIR/$tdir
10339
10340         echo "performing cp ..."
10341         run_acl_subtest cp || error "run_acl_subtest cp failed"
10342         echo "performing getfacl-noacl..."
10343         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
10344         echo "performing misc..."
10345         run_acl_subtest misc || error  "misc test failed"
10346         echo "performing permissions..."
10347         run_acl_subtest permissions || error "permissions failed"
10348         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
10349         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
10350                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
10351                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
10352         then
10353                 echo "performing permissions xattr..."
10354                 run_acl_subtest permissions_xattr ||
10355                         error "permissions_xattr failed"
10356         fi
10357         echo "performing setfacl..."
10358         run_acl_subtest setfacl || error  "setfacl test failed"
10359
10360         # inheritance test got from HP
10361         echo "performing inheritance..."
10362         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
10363         chmod +x make-tree || error "chmod +x failed"
10364         run_acl_subtest inheritance || error "inheritance test failed"
10365         rm -f make-tree
10366
10367         echo "LU-974 ignore umask when acl is enabled..."
10368         run_acl_subtest 974 || error "LU-974 umask test failed"
10369         if [ $MDSCOUNT -ge 2 ]; then
10370                 run_acl_subtest 974_remote ||
10371                         error "LU-974 umask test failed under remote dir"
10372         fi
10373
10374         echo "LU-2561 newly created file is same size as directory..."
10375         if [ "$mds1_FSTYPE" != "zfs" ]; then
10376                 run_acl_subtest 2561 || error "LU-2561 test failed"
10377         else
10378                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
10379         fi
10380
10381         run_acl_subtest 4924 || error "LU-4924 test failed"
10382
10383         cd $SAVE_PWD
10384         umask $SAVE_UMASK
10385
10386         for num in $(seq $MDSCOUNT); do
10387                 if [ "${identity_old[$num]}" = 1 ]; then
10388                         switch_identity $num false || identity_old[$num]=$?
10389                 fi
10390         done
10391 }
10392 run_test 103a "acl test"
10393
10394 test_103b() {
10395         declare -a pids
10396         local U
10397
10398         for U in {0..511}; do
10399                 {
10400                 local O=$(printf "%04o" $U)
10401
10402                 umask $(printf "%04o" $((511 ^ $O)))
10403                 $LFS setstripe -c 1 $DIR/$tfile.s$O
10404                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
10405
10406                 (( $S == ($O & 0666) )) ||
10407                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
10408
10409                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
10410                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
10411                 (( $S == ($O & 0666) )) ||
10412                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
10413
10414                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
10415                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
10416                 (( $S == ($O & 0666) )) ||
10417                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
10418                 rm -f $DIR/$tfile.[smp]$0
10419                 } &
10420                 local pid=$!
10421
10422                 # limit the concurrently running threads to 64. LU-11878
10423                 local idx=$((U % 64))
10424                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
10425                 pids[idx]=$pid
10426         done
10427         wait
10428 }
10429 run_test 103b "umask lfs setstripe"
10430
10431 test_103c() {
10432         mkdir -p $DIR/$tdir
10433         cp -rp $DIR/$tdir $DIR/$tdir.bak
10434
10435         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
10436                 error "$DIR/$tdir shouldn't contain default ACL"
10437         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
10438                 error "$DIR/$tdir.bak shouldn't contain default ACL"
10439         true
10440 }
10441 run_test 103c "'cp -rp' won't set empty acl"
10442
10443 test_104a() {
10444         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10445
10446         touch $DIR/$tfile
10447         lfs df || error "lfs df failed"
10448         lfs df -ih || error "lfs df -ih failed"
10449         lfs df -h $DIR || error "lfs df -h $DIR failed"
10450         lfs df -i $DIR || error "lfs df -i $DIR failed"
10451         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
10452         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
10453
10454         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
10455         lctl --device %$OSC deactivate
10456         lfs df || error "lfs df with deactivated OSC failed"
10457         lctl --device %$OSC activate
10458         # wait the osc back to normal
10459         wait_osc_import_ready client ost
10460
10461         lfs df || error "lfs df with reactivated OSC failed"
10462         rm -f $DIR/$tfile
10463 }
10464 run_test 104a "lfs df [-ih] [path] test ========================="
10465
10466 test_104b() {
10467         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10468         [ $RUNAS_ID -eq $UID ] &&
10469                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10470
10471         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
10472                         grep "Permission denied" | wc -l)))
10473         if [ $denied_cnt -ne 0 ]; then
10474                 error "lfs check servers test failed"
10475         fi
10476 }
10477 run_test 104b "$RUNAS lfs check servers test ===================="
10478
10479 test_105a() {
10480         # doesn't work on 2.4 kernels
10481         touch $DIR/$tfile
10482         if $(flock_is_enabled); then
10483                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
10484         else
10485                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
10486         fi
10487         rm -f $DIR/$tfile
10488 }
10489 run_test 105a "flock when mounted without -o flock test ========"
10490
10491 test_105b() {
10492         touch $DIR/$tfile
10493         if $(flock_is_enabled); then
10494                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
10495         else
10496                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
10497         fi
10498         rm -f $DIR/$tfile
10499 }
10500 run_test 105b "fcntl when mounted without -o flock test ========"
10501
10502 test_105c() {
10503         touch $DIR/$tfile
10504         if $(flock_is_enabled); then
10505                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
10506         else
10507                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
10508         fi
10509         rm -f $DIR/$tfile
10510 }
10511 run_test 105c "lockf when mounted without -o flock test"
10512
10513 test_105d() { # bug 15924
10514         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10515
10516         test_mkdir $DIR/$tdir
10517         flock_is_enabled || skip_env "mount w/o flock enabled"
10518         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
10519         $LCTL set_param fail_loc=0x80000315
10520         flocks_test 2 $DIR/$tdir
10521 }
10522 run_test 105d "flock race (should not freeze) ========"
10523
10524 test_105e() { # bug 22660 && 22040
10525         flock_is_enabled || skip_env "mount w/o flock enabled"
10526
10527         touch $DIR/$tfile
10528         flocks_test 3 $DIR/$tfile
10529 }
10530 run_test 105e "Two conflicting flocks from same process"
10531
10532 test_106() { #bug 10921
10533         test_mkdir $DIR/$tdir
10534         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
10535         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
10536 }
10537 run_test 106 "attempt exec of dir followed by chown of that dir"
10538
10539 test_107() {
10540         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10541
10542         CDIR=`pwd`
10543         local file=core
10544
10545         cd $DIR
10546         rm -f $file
10547
10548         local save_pattern=$(sysctl -n kernel.core_pattern)
10549         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
10550         sysctl -w kernel.core_pattern=$file
10551         sysctl -w kernel.core_uses_pid=0
10552
10553         ulimit -c unlimited
10554         sleep 60 &
10555         SLEEPPID=$!
10556
10557         sleep 1
10558
10559         kill -s 11 $SLEEPPID
10560         wait $SLEEPPID
10561         if [ -e $file ]; then
10562                 size=`stat -c%s $file`
10563                 [ $size -eq 0 ] && error "Fail to create core file $file"
10564         else
10565                 error "Fail to create core file $file"
10566         fi
10567         rm -f $file
10568         sysctl -w kernel.core_pattern=$save_pattern
10569         sysctl -w kernel.core_uses_pid=$save_uses_pid
10570         cd $CDIR
10571 }
10572 run_test 107 "Coredump on SIG"
10573
10574 test_110() {
10575         test_mkdir $DIR/$tdir
10576         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
10577         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
10578                 error "mkdir with 256 char should fail, but did not"
10579         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
10580                 error "create with 255 char failed"
10581         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
10582                 error "create with 256 char should fail, but did not"
10583
10584         ls -l $DIR/$tdir
10585         rm -rf $DIR/$tdir
10586 }
10587 run_test 110 "filename length checking"
10588
10589 #
10590 # Purpose: To verify dynamic thread (OSS) creation.
10591 #
10592 test_115() {
10593         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10594         remote_ost_nodsh && skip "remote OST with nodsh"
10595
10596         # Lustre does not stop service threads once they are started.
10597         # Reset number of running threads to default.
10598         stopall
10599         setupall
10600
10601         local OSTIO_pre
10602         local save_params="$TMP/sanity-$TESTNAME.parameters"
10603
10604         # Get ll_ost_io count before I/O
10605         OSTIO_pre=$(do_facet ost1 \
10606                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
10607         # Exit if lustre is not running (ll_ost_io not running).
10608         [ -z "$OSTIO_pre" ] && error "no OSS threads"
10609
10610         echo "Starting with $OSTIO_pre threads"
10611         local thread_max=$((OSTIO_pre * 2))
10612         local rpc_in_flight=$((thread_max * 2))
10613         # Number of I/O Process proposed to be started.
10614         local nfiles
10615         local facets=$(get_facets OST)
10616
10617         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
10618         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
10619
10620         # Set in_flight to $rpc_in_flight
10621         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
10622                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
10623         nfiles=${rpc_in_flight}
10624         # Set ost thread_max to $thread_max
10625         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
10626
10627         # 5 Minutes should be sufficient for max number of OSS
10628         # threads(thread_max) to be created.
10629         local timeout=300
10630
10631         # Start I/O.
10632         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
10633         test_mkdir $DIR/$tdir
10634         for i in $(seq $nfiles); do
10635                 local file=$DIR/$tdir/${tfile}-$i
10636                 $LFS setstripe -c -1 -i 0 $file
10637                 ($WTL $file $timeout)&
10638         done
10639
10640         # I/O Started - Wait for thread_started to reach thread_max or report
10641         # error if thread_started is more than thread_max.
10642         echo "Waiting for thread_started to reach thread_max"
10643         local thread_started=0
10644         local end_time=$((SECONDS + timeout))
10645
10646         while [ $SECONDS -le $end_time ] ; do
10647                 echo -n "."
10648                 # Get ost i/o thread_started count.
10649                 thread_started=$(do_facet ost1 \
10650                         "$LCTL get_param \
10651                         ost.OSS.ost_io.threads_started | cut -d= -f2")
10652                 # Break out if thread_started is equal/greater than thread_max
10653                 if [[ $thread_started -ge $thread_max ]]; then
10654                         echo ll_ost_io thread_started $thread_started, \
10655                                 equal/greater than thread_max $thread_max
10656                         break
10657                 fi
10658                 sleep 1
10659         done
10660
10661         # Cleanup - We have the numbers, Kill i/o jobs if running.
10662         jobcount=($(jobs -p))
10663         for i in $(seq 0 $((${#jobcount[@]}-1)))
10664         do
10665                 kill -9 ${jobcount[$i]}
10666                 if [ $? -ne 0 ] ; then
10667                         echo Warning: \
10668                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
10669                 fi
10670         done
10671
10672         # Cleanup files left by WTL binary.
10673         for i in $(seq $nfiles); do
10674                 local file=$DIR/$tdir/${tfile}-$i
10675                 rm -rf $file
10676                 if [ $? -ne 0 ] ; then
10677                         echo "Warning: Failed to delete file $file"
10678                 fi
10679         done
10680
10681         restore_lustre_params <$save_params
10682         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
10683
10684         # Error out if no new thread has started or Thread started is greater
10685         # than thread max.
10686         if [[ $thread_started -le $OSTIO_pre ||
10687                         $thread_started -gt $thread_max ]]; then
10688                 error "ll_ost_io: thread_started $thread_started" \
10689                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
10690                       "No new thread started or thread started greater " \
10691                       "than thread_max."
10692         fi
10693 }
10694 run_test 115 "verify dynamic thread creation===================="
10695
10696 free_min_max () {
10697         wait_delete_completed
10698         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
10699         echo "OST kbytes available: ${AVAIL[@]}"
10700         MAXV=${AVAIL[0]}
10701         MAXI=0
10702         MINV=${AVAIL[0]}
10703         MINI=0
10704         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
10705                 #echo OST $i: ${AVAIL[i]}kb
10706                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
10707                         MAXV=${AVAIL[i]}
10708                         MAXI=$i
10709                 fi
10710                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
10711                         MINV=${AVAIL[i]}
10712                         MINI=$i
10713                 fi
10714         done
10715         echo "Min free space: OST $MINI: $MINV"
10716         echo "Max free space: OST $MAXI: $MAXV"
10717 }
10718
10719 test_116a() { # was previously test_116()
10720         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10721         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10722         remote_mds_nodsh && skip "remote MDS with nodsh"
10723
10724         echo -n "Free space priority "
10725         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
10726                 head -n1
10727         declare -a AVAIL
10728         free_min_max
10729
10730         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
10731         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
10732         trap simple_cleanup_common EXIT
10733
10734         # Check if we need to generate uneven OSTs
10735         test_mkdir -p $DIR/$tdir/OST${MINI}
10736         local FILL=$((MINV / 4))
10737         local DIFF=$((MAXV - MINV))
10738         local DIFF2=$((DIFF * 100 / MINV))
10739
10740         local threshold=$(do_facet $SINGLEMDS \
10741                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
10742         threshold=${threshold%%%}
10743         echo -n "Check for uneven OSTs: "
10744         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
10745
10746         if [[ $DIFF2 -gt $threshold ]]; then
10747                 echo "ok"
10748                 echo "Don't need to fill OST$MINI"
10749         else
10750                 # generate uneven OSTs. Write 2% over the QOS threshold value
10751                 echo "no"
10752                 DIFF=$((threshold - DIFF2 + 2))
10753                 DIFF2=$((MINV * DIFF / 100))
10754                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
10755                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
10756                         error "setstripe failed"
10757                 DIFF=$((DIFF2 / 2048))
10758                 i=0
10759                 while [ $i -lt $DIFF ]; do
10760                         i=$((i + 1))
10761                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
10762                                 bs=2M count=1 2>/dev/null
10763                         echo -n .
10764                 done
10765                 echo .
10766                 sync
10767                 sleep_maxage
10768                 free_min_max
10769         fi
10770
10771         DIFF=$((MAXV - MINV))
10772         DIFF2=$((DIFF * 100 / MINV))
10773         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
10774         if [ $DIFF2 -gt $threshold ]; then
10775                 echo "ok"
10776         else
10777                 echo "failed - QOS mode won't be used"
10778                 simple_cleanup_common
10779                 skip "QOS imbalance criteria not met"
10780         fi
10781
10782         MINI1=$MINI
10783         MINV1=$MINV
10784         MAXI1=$MAXI
10785         MAXV1=$MAXV
10786
10787         # now fill using QOS
10788         $LFS setstripe -c 1 $DIR/$tdir
10789         FILL=$((FILL / 200))
10790         if [ $FILL -gt 600 ]; then
10791                 FILL=600
10792         fi
10793         echo "writing $FILL files to QOS-assigned OSTs"
10794         i=0
10795         while [ $i -lt $FILL ]; do
10796                 i=$((i + 1))
10797                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
10798                         count=1 2>/dev/null
10799                 echo -n .
10800         done
10801         echo "wrote $i 200k files"
10802         sync
10803         sleep_maxage
10804
10805         echo "Note: free space may not be updated, so measurements might be off"
10806         free_min_max
10807         DIFF2=$((MAXV - MINV))
10808         echo "free space delta: orig $DIFF final $DIFF2"
10809         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
10810         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
10811         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
10812         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
10813         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
10814         if [[ $DIFF -gt 0 ]]; then
10815                 FILL=$((DIFF2 * 100 / DIFF - 100))
10816                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
10817         fi
10818
10819         # Figure out which files were written where
10820         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10821                awk '/'$MINI1': / {print $2; exit}')
10822         echo $UUID
10823         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10824         echo "$MINC files created on smaller OST $MINI1"
10825         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10826                awk '/'$MAXI1': / {print $2; exit}')
10827         echo $UUID
10828         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10829         echo "$MAXC files created on larger OST $MAXI1"
10830         if [[ $MINC -gt 0 ]]; then
10831                 FILL=$((MAXC * 100 / MINC - 100))
10832                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
10833         fi
10834         [[ $MAXC -gt $MINC ]] ||
10835                 error_ignore LU-9 "stripe QOS didn't balance free space"
10836         simple_cleanup_common
10837 }
10838 run_test 116a "stripe QOS: free space balance ==================="
10839
10840 test_116b() { # LU-2093
10841         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10842         remote_mds_nodsh && skip "remote MDS with nodsh"
10843
10844 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
10845         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
10846                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
10847         [ -z "$old_rr" ] && skip "no QOS"
10848         do_facet $SINGLEMDS lctl set_param \
10849                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
10850         mkdir -p $DIR/$tdir
10851         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
10852         createmany -o $DIR/$tdir/f- 20 || error "can't create"
10853         do_facet $SINGLEMDS lctl set_param fail_loc=0
10854         rm -rf $DIR/$tdir
10855         do_facet $SINGLEMDS lctl set_param \
10856                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
10857 }
10858 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
10859
10860 test_117() # bug 10891
10861 {
10862         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10863
10864         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
10865         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
10866         lctl set_param fail_loc=0x21e
10867         > $DIR/$tfile || error "truncate failed"
10868         lctl set_param fail_loc=0
10869         echo "Truncate succeeded."
10870         rm -f $DIR/$tfile
10871 }
10872 run_test 117 "verify osd extend =========="
10873
10874 NO_SLOW_RESENDCOUNT=4
10875 export OLD_RESENDCOUNT=""
10876 set_resend_count () {
10877         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
10878         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
10879         lctl set_param -n $PROC_RESENDCOUNT $1
10880         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
10881 }
10882
10883 # for reduce test_118* time (b=14842)
10884 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
10885
10886 # Reset async IO behavior after error case
10887 reset_async() {
10888         FILE=$DIR/reset_async
10889
10890         # Ensure all OSCs are cleared
10891         $LFS setstripe -c -1 $FILE
10892         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
10893         sync
10894         rm $FILE
10895 }
10896
10897 test_118a() #bug 11710
10898 {
10899         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10900
10901         reset_async
10902
10903         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10904         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10905         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10906
10907         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10908                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10909                 return 1;
10910         fi
10911         rm -f $DIR/$tfile
10912 }
10913 run_test 118a "verify O_SYNC works =========="
10914
10915 test_118b()
10916 {
10917         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10918         remote_ost_nodsh && skip "remote OST with nodsh"
10919
10920         reset_async
10921
10922         #define OBD_FAIL_SRV_ENOENT 0x217
10923         set_nodes_failloc "$(osts_nodes)" 0x217
10924         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10925         RC=$?
10926         set_nodes_failloc "$(osts_nodes)" 0
10927         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10928         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10929                     grep -c writeback)
10930
10931         if [[ $RC -eq 0 ]]; then
10932                 error "Must return error due to dropped pages, rc=$RC"
10933                 return 1;
10934         fi
10935
10936         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10937                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10938                 return 1;
10939         fi
10940
10941         echo "Dirty pages not leaked on ENOENT"
10942
10943         # Due to the above error the OSC will issue all RPCs syncronously
10944         # until a subsequent RPC completes successfully without error.
10945         $MULTIOP $DIR/$tfile Ow4096yc
10946         rm -f $DIR/$tfile
10947
10948         return 0
10949 }
10950 run_test 118b "Reclaim dirty pages on fatal error =========="
10951
10952 test_118c()
10953 {
10954         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10955
10956         # for 118c, restore the original resend count, LU-1940
10957         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
10958                                 set_resend_count $OLD_RESENDCOUNT
10959         remote_ost_nodsh && skip "remote OST with nodsh"
10960
10961         reset_async
10962
10963         #define OBD_FAIL_OST_EROFS               0x216
10964         set_nodes_failloc "$(osts_nodes)" 0x216
10965
10966         # multiop should block due to fsync until pages are written
10967         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10968         MULTIPID=$!
10969         sleep 1
10970
10971         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
10972                 error "Multiop failed to block on fsync, pid=$MULTIPID"
10973         fi
10974
10975         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10976                     grep -c writeback)
10977         if [[ $WRITEBACK -eq 0 ]]; then
10978                 error "No page in writeback, writeback=$WRITEBACK"
10979         fi
10980
10981         set_nodes_failloc "$(osts_nodes)" 0
10982         wait $MULTIPID
10983         RC=$?
10984         if [[ $RC -ne 0 ]]; then
10985                 error "Multiop fsync failed, rc=$RC"
10986         fi
10987
10988         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10989         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10990                     grep -c writeback)
10991         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10992                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10993         fi
10994
10995         rm -f $DIR/$tfile
10996         echo "Dirty pages flushed via fsync on EROFS"
10997         return 0
10998 }
10999 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
11000
11001 # continue to use small resend count to reduce test_118* time (b=14842)
11002 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
11003
11004 test_118d()
11005 {
11006         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11007         remote_ost_nodsh && skip "remote OST with nodsh"
11008
11009         reset_async
11010
11011         #define OBD_FAIL_OST_BRW_PAUSE_BULK
11012         set_nodes_failloc "$(osts_nodes)" 0x214
11013         # multiop should block due to fsync until pages are written
11014         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11015         MULTIPID=$!
11016         sleep 1
11017
11018         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11019                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11020         fi
11021
11022         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11023                     grep -c writeback)
11024         if [[ $WRITEBACK -eq 0 ]]; then
11025                 error "No page in writeback, writeback=$WRITEBACK"
11026         fi
11027
11028         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
11029         set_nodes_failloc "$(osts_nodes)" 0
11030
11031         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11032         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11033                     grep -c writeback)
11034         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11035                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11036         fi
11037
11038         rm -f $DIR/$tfile
11039         echo "Dirty pages gaurenteed flushed via fsync"
11040         return 0
11041 }
11042 run_test 118d "Fsync validation inject a delay of the bulk =========="
11043
11044 test_118f() {
11045         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11046
11047         reset_async
11048
11049         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
11050         lctl set_param fail_loc=0x8000040a
11051
11052         # Should simulate EINVAL error which is fatal
11053         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11054         RC=$?
11055         if [[ $RC -eq 0 ]]; then
11056                 error "Must return error due to dropped pages, rc=$RC"
11057         fi
11058
11059         lctl set_param fail_loc=0x0
11060
11061         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11062         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11063         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11064                     grep -c writeback)
11065         if [[ $LOCKED -ne 0 ]]; then
11066                 error "Locked pages remain in cache, locked=$LOCKED"
11067         fi
11068
11069         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11070                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11071         fi
11072
11073         rm -f $DIR/$tfile
11074         echo "No pages locked after fsync"
11075
11076         reset_async
11077         return 0
11078 }
11079 run_test 118f "Simulate unrecoverable OSC side error =========="
11080
11081 test_118g() {
11082         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11083
11084         reset_async
11085
11086         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
11087         lctl set_param fail_loc=0x406
11088
11089         # simulate local -ENOMEM
11090         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11091         RC=$?
11092
11093         lctl set_param fail_loc=0
11094         if [[ $RC -eq 0 ]]; then
11095                 error "Must return error due to dropped pages, rc=$RC"
11096         fi
11097
11098         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11099         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11100         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11101                         grep -c writeback)
11102         if [[ $LOCKED -ne 0 ]]; then
11103                 error "Locked pages remain in cache, locked=$LOCKED"
11104         fi
11105
11106         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11107                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11108         fi
11109
11110         rm -f $DIR/$tfile
11111         echo "No pages locked after fsync"
11112
11113         reset_async
11114         return 0
11115 }
11116 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
11117
11118 test_118h() {
11119         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11120         remote_ost_nodsh && skip "remote OST with nodsh"
11121
11122         reset_async
11123
11124         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11125         set_nodes_failloc "$(osts_nodes)" 0x20e
11126         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11127         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11128         RC=$?
11129
11130         set_nodes_failloc "$(osts_nodes)" 0
11131         if [[ $RC -eq 0 ]]; then
11132                 error "Must return error due to dropped pages, rc=$RC"
11133         fi
11134
11135         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11136         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11137         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11138                     grep -c writeback)
11139         if [[ $LOCKED -ne 0 ]]; then
11140                 error "Locked pages remain in cache, locked=$LOCKED"
11141         fi
11142
11143         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11144                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11145         fi
11146
11147         rm -f $DIR/$tfile
11148         echo "No pages locked after fsync"
11149
11150         return 0
11151 }
11152 run_test 118h "Verify timeout in handling recoverables errors  =========="
11153
11154 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11155
11156 test_118i() {
11157         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11158         remote_ost_nodsh && skip "remote OST with nodsh"
11159
11160         reset_async
11161
11162         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11163         set_nodes_failloc "$(osts_nodes)" 0x20e
11164
11165         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11166         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11167         PID=$!
11168         sleep 5
11169         set_nodes_failloc "$(osts_nodes)" 0
11170
11171         wait $PID
11172         RC=$?
11173         if [[ $RC -ne 0 ]]; then
11174                 error "got error, but should be not, rc=$RC"
11175         fi
11176
11177         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11178         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11179         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11180         if [[ $LOCKED -ne 0 ]]; then
11181                 error "Locked pages remain in cache, locked=$LOCKED"
11182         fi
11183
11184         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11185                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11186         fi
11187
11188         rm -f $DIR/$tfile
11189         echo "No pages locked after fsync"
11190
11191         return 0
11192 }
11193 run_test 118i "Fix error before timeout in recoverable error  =========="
11194
11195 [ "$SLOW" = "no" ] && set_resend_count 4
11196
11197 test_118j() {
11198         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11199         remote_ost_nodsh && skip "remote OST with nodsh"
11200
11201         reset_async
11202
11203         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
11204         set_nodes_failloc "$(osts_nodes)" 0x220
11205
11206         # return -EIO from OST
11207         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11208         RC=$?
11209         set_nodes_failloc "$(osts_nodes)" 0x0
11210         if [[ $RC -eq 0 ]]; then
11211                 error "Must return error due to dropped pages, rc=$RC"
11212         fi
11213
11214         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11215         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11216         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11217         if [[ $LOCKED -ne 0 ]]; then
11218                 error "Locked pages remain in cache, locked=$LOCKED"
11219         fi
11220
11221         # in recoverable error on OST we want resend and stay until it finished
11222         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11223                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11224         fi
11225
11226         rm -f $DIR/$tfile
11227         echo "No pages locked after fsync"
11228
11229         return 0
11230 }
11231 run_test 118j "Simulate unrecoverable OST side error =========="
11232
11233 test_118k()
11234 {
11235         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11236         remote_ost_nodsh && skip "remote OSTs with nodsh"
11237
11238         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11239         set_nodes_failloc "$(osts_nodes)" 0x20e
11240         test_mkdir $DIR/$tdir
11241
11242         for ((i=0;i<10;i++)); do
11243                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
11244                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
11245                 SLEEPPID=$!
11246                 sleep 0.500s
11247                 kill $SLEEPPID
11248                 wait $SLEEPPID
11249         done
11250
11251         set_nodes_failloc "$(osts_nodes)" 0
11252         rm -rf $DIR/$tdir
11253 }
11254 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
11255
11256 test_118l() # LU-646
11257 {
11258         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11259
11260         test_mkdir $DIR/$tdir
11261         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
11262         rm -rf $DIR/$tdir
11263 }
11264 run_test 118l "fsync dir"
11265
11266 test_118m() # LU-3066
11267 {
11268         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11269
11270         test_mkdir $DIR/$tdir
11271         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
11272         rm -rf $DIR/$tdir
11273 }
11274 run_test 118m "fdatasync dir ========="
11275
11276 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11277
11278 test_118n()
11279 {
11280         local begin
11281         local end
11282
11283         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11284         remote_ost_nodsh && skip "remote OSTs with nodsh"
11285
11286         # Sleep to avoid a cached response.
11287         #define OBD_STATFS_CACHE_SECONDS 1
11288         sleep 2
11289
11290         # Inject a 10 second delay in the OST_STATFS handler.
11291         #define OBD_FAIL_OST_STATFS_DELAY 0x242
11292         set_nodes_failloc "$(osts_nodes)" 0x242
11293
11294         begin=$SECONDS
11295         stat --file-system $MOUNT > /dev/null
11296         end=$SECONDS
11297
11298         set_nodes_failloc "$(osts_nodes)" 0
11299
11300         if ((end - begin > 20)); then
11301             error "statfs took $((end - begin)) seconds, expected 10"
11302         fi
11303 }
11304 run_test 118n "statfs() sends OST_STATFS requests in parallel"
11305
11306 test_119a() # bug 11737
11307 {
11308         BSIZE=$((512 * 1024))
11309         directio write $DIR/$tfile 0 1 $BSIZE
11310         # We ask to read two blocks, which is more than a file size.
11311         # directio will indicate an error when requested and actual
11312         # sizes aren't equeal (a normal situation in this case) and
11313         # print actual read amount.
11314         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
11315         if [ "$NOB" != "$BSIZE" ]; then
11316                 error "read $NOB bytes instead of $BSIZE"
11317         fi
11318         rm -f $DIR/$tfile
11319 }
11320 run_test 119a "Short directIO read must return actual read amount"
11321
11322 test_119b() # bug 11737
11323 {
11324         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11325
11326         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
11327         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
11328         sync
11329         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
11330                 error "direct read failed"
11331         rm -f $DIR/$tfile
11332 }
11333 run_test 119b "Sparse directIO read must return actual read amount"
11334
11335 test_119c() # bug 13099
11336 {
11337         BSIZE=1048576
11338         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
11339         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
11340         rm -f $DIR/$tfile
11341 }
11342 run_test 119c "Testing for direct read hitting hole"
11343
11344 test_119d() # bug 15950
11345 {
11346         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11347
11348         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
11349         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
11350         BSIZE=1048576
11351         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
11352         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
11353         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
11354         lctl set_param fail_loc=0x40d
11355         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
11356         pid_dio=$!
11357         sleep 1
11358         cat $DIR/$tfile > /dev/null &
11359         lctl set_param fail_loc=0
11360         pid_reads=$!
11361         wait $pid_dio
11362         log "the DIO writes have completed, now wait for the reads (should not block very long)"
11363         sleep 2
11364         [ -n "`ps h -p $pid_reads -o comm`" ] && \
11365         error "the read rpcs have not completed in 2s"
11366         rm -f $DIR/$tfile
11367         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
11368 }
11369 run_test 119d "The DIO path should try to send a new rpc once one is completed"
11370
11371 test_120a() {
11372         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11373         remote_mds_nodsh && skip "remote MDS with nodsh"
11374         test_mkdir -i0 -c1 $DIR/$tdir
11375         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11376                 skip_env "no early lock cancel on server"
11377
11378         lru_resize_disable mdc
11379         lru_resize_disable osc
11380         cancel_lru_locks mdc
11381         # asynchronous object destroy at MDT could cause bl ast to client
11382         cancel_lru_locks osc
11383
11384         stat $DIR/$tdir > /dev/null
11385         can1=$(do_facet mds1 \
11386                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11387                awk '/ldlm_cancel/ {print $2}')
11388         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11389                awk '/ldlm_bl_callback/ {print $2}')
11390         test_mkdir -i0 -c1 $DIR/$tdir/d1
11391         can2=$(do_facet mds1 \
11392                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11393                awk '/ldlm_cancel/ {print $2}')
11394         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11395                awk '/ldlm_bl_callback/ {print $2}')
11396         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11397         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11398         lru_resize_enable mdc
11399         lru_resize_enable osc
11400 }
11401 run_test 120a "Early Lock Cancel: mkdir test"
11402
11403 test_120b() {
11404         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11405         remote_mds_nodsh && skip "remote MDS with nodsh"
11406         test_mkdir $DIR/$tdir
11407         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11408                 skip_env "no early lock cancel on server"
11409
11410         lru_resize_disable mdc
11411         lru_resize_disable osc
11412         cancel_lru_locks mdc
11413         stat $DIR/$tdir > /dev/null
11414         can1=$(do_facet $SINGLEMDS \
11415                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11416                awk '/ldlm_cancel/ {print $2}')
11417         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11418                awk '/ldlm_bl_callback/ {print $2}')
11419         touch $DIR/$tdir/f1
11420         can2=$(do_facet $SINGLEMDS \
11421                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11422                awk '/ldlm_cancel/ {print $2}')
11423         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11424                awk '/ldlm_bl_callback/ {print $2}')
11425         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11426         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11427         lru_resize_enable mdc
11428         lru_resize_enable osc
11429 }
11430 run_test 120b "Early Lock Cancel: create test"
11431
11432 test_120c() {
11433         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11434         remote_mds_nodsh && skip "remote MDS with nodsh"
11435         test_mkdir -i0 -c1 $DIR/$tdir
11436         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11437                 skip "no early lock cancel on server"
11438
11439         lru_resize_disable mdc
11440         lru_resize_disable osc
11441         test_mkdir -i0 -c1 $DIR/$tdir/d1
11442         test_mkdir -i0 -c1 $DIR/$tdir/d2
11443         touch $DIR/$tdir/d1/f1
11444         cancel_lru_locks mdc
11445         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
11446         can1=$(do_facet mds1 \
11447                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11448                awk '/ldlm_cancel/ {print $2}')
11449         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11450                awk '/ldlm_bl_callback/ {print $2}')
11451         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11452         can2=$(do_facet mds1 \
11453                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11454                awk '/ldlm_cancel/ {print $2}')
11455         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11456                awk '/ldlm_bl_callback/ {print $2}')
11457         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11458         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11459         lru_resize_enable mdc
11460         lru_resize_enable osc
11461 }
11462 run_test 120c "Early Lock Cancel: link test"
11463
11464 test_120d() {
11465         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11466         remote_mds_nodsh && skip "remote MDS with nodsh"
11467         test_mkdir -i0 -c1 $DIR/$tdir
11468         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11469                 skip_env "no early lock cancel on server"
11470
11471         lru_resize_disable mdc
11472         lru_resize_disable osc
11473         touch $DIR/$tdir
11474         cancel_lru_locks mdc
11475         stat $DIR/$tdir > /dev/null
11476         can1=$(do_facet mds1 \
11477                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11478                awk '/ldlm_cancel/ {print $2}')
11479         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11480                awk '/ldlm_bl_callback/ {print $2}')
11481         chmod a+x $DIR/$tdir
11482         can2=$(do_facet mds1 \
11483                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11484                awk '/ldlm_cancel/ {print $2}')
11485         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11486                awk '/ldlm_bl_callback/ {print $2}')
11487         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11488         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11489         lru_resize_enable mdc
11490         lru_resize_enable osc
11491 }
11492 run_test 120d "Early Lock Cancel: setattr test"
11493
11494 test_120e() {
11495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11496         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11497                 skip_env "no early lock cancel on server"
11498         remote_mds_nodsh && skip "remote MDS with nodsh"
11499
11500         local dlmtrace_set=false
11501
11502         test_mkdir -i0 -c1 $DIR/$tdir
11503         lru_resize_disable mdc
11504         lru_resize_disable osc
11505         ! $LCTL get_param debug | grep -q dlmtrace &&
11506                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
11507         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
11508         cancel_lru_locks mdc
11509         cancel_lru_locks osc
11510         dd if=$DIR/$tdir/f1 of=/dev/null
11511         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
11512         # XXX client can not do early lock cancel of OST lock
11513         # during unlink (LU-4206), so cancel osc lock now.
11514         sleep 2
11515         cancel_lru_locks osc
11516         can1=$(do_facet mds1 \
11517                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11518                awk '/ldlm_cancel/ {print $2}')
11519         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11520                awk '/ldlm_bl_callback/ {print $2}')
11521         unlink $DIR/$tdir/f1
11522         sleep 5
11523         can2=$(do_facet mds1 \
11524                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11525                awk '/ldlm_cancel/ {print $2}')
11526         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11527                awk '/ldlm_bl_callback/ {print $2}')
11528         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
11529                 $LCTL dk $TMP/cancel.debug.txt
11530         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
11531                 $LCTL dk $TMP/blocking.debug.txt
11532         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
11533         lru_resize_enable mdc
11534         lru_resize_enable osc
11535 }
11536 run_test 120e "Early Lock Cancel: unlink test"
11537
11538 test_120f() {
11539         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11540         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11541                 skip_env "no early lock cancel on server"
11542         remote_mds_nodsh && skip "remote MDS with nodsh"
11543
11544         test_mkdir -i0 -c1 $DIR/$tdir
11545         lru_resize_disable mdc
11546         lru_resize_disable osc
11547         test_mkdir -i0 -c1 $DIR/$tdir/d1
11548         test_mkdir -i0 -c1 $DIR/$tdir/d2
11549         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
11550         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
11551         cancel_lru_locks mdc
11552         cancel_lru_locks osc
11553         dd if=$DIR/$tdir/d1/f1 of=/dev/null
11554         dd if=$DIR/$tdir/d2/f2 of=/dev/null
11555         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
11556         # XXX client can not do early lock cancel of OST lock
11557         # during rename (LU-4206), so cancel osc lock now.
11558         sleep 2
11559         cancel_lru_locks osc
11560         can1=$(do_facet mds1 \
11561                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11562                awk '/ldlm_cancel/ {print $2}')
11563         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11564                awk '/ldlm_bl_callback/ {print $2}')
11565         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11566         sleep 5
11567         can2=$(do_facet mds1 \
11568                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11569                awk '/ldlm_cancel/ {print $2}')
11570         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11571                awk '/ldlm_bl_callback/ {print $2}')
11572         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11573         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11574         lru_resize_enable mdc
11575         lru_resize_enable osc
11576 }
11577 run_test 120f "Early Lock Cancel: rename test"
11578
11579 test_120g() {
11580         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11581         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11582                 skip_env "no early lock cancel on server"
11583         remote_mds_nodsh && skip "remote MDS with nodsh"
11584
11585         lru_resize_disable mdc
11586         lru_resize_disable osc
11587         count=10000
11588         echo create $count files
11589         test_mkdir $DIR/$tdir
11590         cancel_lru_locks mdc
11591         cancel_lru_locks osc
11592         t0=$(date +%s)
11593
11594         can0=$(do_facet $SINGLEMDS \
11595                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11596                awk '/ldlm_cancel/ {print $2}')
11597         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11598                awk '/ldlm_bl_callback/ {print $2}')
11599         createmany -o $DIR/$tdir/f $count
11600         sync
11601         can1=$(do_facet $SINGLEMDS \
11602                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11603                awk '/ldlm_cancel/ {print $2}')
11604         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11605                awk '/ldlm_bl_callback/ {print $2}')
11606         t1=$(date +%s)
11607         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
11608         echo rm $count files
11609         rm -r $DIR/$tdir
11610         sync
11611         can2=$(do_facet $SINGLEMDS \
11612                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11613                awk '/ldlm_cancel/ {print $2}')
11614         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11615                awk '/ldlm_bl_callback/ {print $2}')
11616         t2=$(date +%s)
11617         echo total: $count removes in $((t2-t1))
11618         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
11619         sleep 2
11620         # wait for commitment of removal
11621         lru_resize_enable mdc
11622         lru_resize_enable osc
11623 }
11624 run_test 120g "Early Lock Cancel: performance test"
11625
11626 test_121() { #bug #10589
11627         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11628
11629         rm -rf $DIR/$tfile
11630         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
11631 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
11632         lctl set_param fail_loc=0x310
11633         cancel_lru_locks osc > /dev/null
11634         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
11635         lctl set_param fail_loc=0
11636         [[ $reads -eq $writes ]] ||
11637                 error "read $reads blocks, must be $writes blocks"
11638 }
11639 run_test 121 "read cancel race ========="
11640
11641 test_123a_base() { # was test 123, statahead(bug 11401)
11642         local lsx="$1"
11643
11644         SLOWOK=0
11645         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
11646                 log "testing UP system. Performance may be lower than expected."
11647                 SLOWOK=1
11648         fi
11649
11650         rm -rf $DIR/$tdir
11651         test_mkdir $DIR/$tdir
11652         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
11653         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
11654         MULT=10
11655         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
11656                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
11657
11658                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
11659                 lctl set_param -n llite.*.statahead_max 0
11660                 lctl get_param llite.*.statahead_max
11661                 cancel_lru_locks mdc
11662                 cancel_lru_locks osc
11663                 stime=$(date +%s)
11664                 time $lsx $DIR/$tdir | wc -l
11665                 etime=$(date +%s)
11666                 delta=$((etime - stime))
11667                 log "$lsx $i files without statahead: $delta sec"
11668                 lctl set_param llite.*.statahead_max=$max
11669
11670                 swrong=$(lctl get_param -n llite.*.statahead_stats |
11671                         grep "statahead wrong:" | awk '{print $3}')
11672                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
11673                 cancel_lru_locks mdc
11674                 cancel_lru_locks osc
11675                 stime=$(date +%s)
11676                 time $lsx $DIR/$tdir | wc -l
11677                 etime=$(date +%s)
11678                 delta_sa=$((etime - stime))
11679                 log "$lsx $i files with statahead: $delta_sa sec"
11680                 lctl get_param -n llite.*.statahead_stats
11681                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
11682                         grep "statahead wrong:" | awk '{print $3}')
11683
11684                 [[ $swrong -lt $ewrong ]] &&
11685                         log "statahead was stopped, maybe too many locks held!"
11686                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
11687
11688                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
11689                         max=$(lctl get_param -n llite.*.statahead_max |
11690                                 head -n 1)
11691                         lctl set_param -n llite.*.statahead_max 0
11692                         lctl get_param llite.*.statahead_max
11693                         cancel_lru_locks mdc
11694                         cancel_lru_locks osc
11695                         stime=$(date +%s)
11696                         time $lsx $DIR/$tdir | wc -l
11697                         etime=$(date +%s)
11698                         delta=$((etime - stime))
11699                         log "$lsx $i files again without statahead: $delta sec"
11700                         lctl set_param llite.*.statahead_max=$max
11701                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
11702                                 if [  $SLOWOK -eq 0 ]; then
11703                                         error "$lsx $i files is slower with statahead!"
11704                                 else
11705                                         log "$lsx $i files is slower with statahead!"
11706                                 fi
11707                                 break
11708                         fi
11709                 fi
11710
11711                 [ $delta -gt 20 ] && break
11712                 [ $delta -gt 8 ] && MULT=$((50 / delta))
11713                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
11714         done
11715         log "$lsx done"
11716
11717         stime=$(date +%s)
11718         rm -r $DIR/$tdir
11719         sync
11720         etime=$(date +%s)
11721         delta=$((etime - stime))
11722         log "rm -r $DIR/$tdir/: $delta seconds"
11723         log "rm done"
11724         lctl get_param -n llite.*.statahead_stats
11725 }
11726
11727 test_123aa() {
11728         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11729
11730         test_123a_base "ls -l"
11731 }
11732 run_test 123aa "verify statahead work"
11733
11734 test_123ab() {
11735         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11736
11737         statx_supported || skip_env "Test must be statx() syscall supported"
11738
11739         test_123a_base "$STATX -l"
11740 }
11741 run_test 123ab "verify statahead work by using statx"
11742
11743 test_123ac() {
11744         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11745
11746         statx_supported || skip_env "Test must be statx() syscall supported"
11747
11748         local rpcs_before
11749         local rpcs_after
11750         local agl_before
11751         local agl_after
11752
11753         cancel_lru_locks $OSC
11754         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
11755         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
11756                 awk '/agl.total:/ {print $3}')
11757         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
11758         test_123a_base "$STATX --cached=always -D"
11759         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
11760                 awk '/agl.total:/ {print $3}')
11761         [ $agl_before -eq $agl_after ] ||
11762                 error "Should not trigger AGL thread - $agl_before:$agl_after"
11763         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
11764         [ $rpcs_after -eq $rpcs_before ] ||
11765                 error "$STATX should not send glimpse RPCs to $OSC"
11766 }
11767 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
11768
11769 test_123b () { # statahead(bug 15027)
11770         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11771
11772         test_mkdir $DIR/$tdir
11773         createmany -o $DIR/$tdir/$tfile-%d 1000
11774
11775         cancel_lru_locks mdc
11776         cancel_lru_locks osc
11777
11778 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
11779         lctl set_param fail_loc=0x80000803
11780         ls -lR $DIR/$tdir > /dev/null
11781         log "ls done"
11782         lctl set_param fail_loc=0x0
11783         lctl get_param -n llite.*.statahead_stats
11784         rm -r $DIR/$tdir
11785         sync
11786
11787 }
11788 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
11789
11790 test_123c() {
11791         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
11792
11793         test_mkdir -i 0 -c 1 $DIR/$tdir.0
11794         test_mkdir -i 1 -c 1 $DIR/$tdir.1
11795         touch $DIR/$tdir.1/{1..3}
11796         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
11797
11798         remount_client $MOUNT
11799
11800         $MULTIOP $DIR/$tdir.0 Q
11801
11802         # let statahead to complete
11803         ls -l $DIR/$tdir.0 > /dev/null
11804
11805         testid=$(echo $TESTNAME | tr '_' ' ')
11806         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
11807                 error "statahead warning" || true
11808 }
11809 run_test 123c "Can not initialize inode warning on DNE statahead"
11810
11811 test_124a() {
11812         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11813         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11814                 skip_env "no lru resize on server"
11815
11816         local NR=2000
11817
11818         test_mkdir $DIR/$tdir
11819
11820         log "create $NR files at $DIR/$tdir"
11821         createmany -o $DIR/$tdir/f $NR ||
11822                 error "failed to create $NR files in $DIR/$tdir"
11823
11824         cancel_lru_locks mdc
11825         ls -l $DIR/$tdir > /dev/null
11826
11827         local NSDIR=""
11828         local LRU_SIZE=0
11829         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
11830                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
11831                 LRU_SIZE=$($LCTL get_param -n $PARAM)
11832                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
11833                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
11834                         log "NSDIR=$NSDIR"
11835                         log "NS=$(basename $NSDIR)"
11836                         break
11837                 fi
11838         done
11839
11840         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
11841                 skip "Not enough cached locks created!"
11842         fi
11843         log "LRU=$LRU_SIZE"
11844
11845         local SLEEP=30
11846
11847         # We know that lru resize allows one client to hold $LIMIT locks
11848         # for 10h. After that locks begin to be killed by client.
11849         local MAX_HRS=10
11850         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
11851         log "LIMIT=$LIMIT"
11852         if [ $LIMIT -lt $LRU_SIZE ]; then
11853                 skip "Limit is too small $LIMIT"
11854         fi
11855
11856         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
11857         # killing locks. Some time was spent for creating locks. This means
11858         # that up to the moment of sleep finish we must have killed some of
11859         # them (10-100 locks). This depends on how fast ther were created.
11860         # Many of them were touched in almost the same moment and thus will
11861         # be killed in groups.
11862         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
11863
11864         # Use $LRU_SIZE_B here to take into account real number of locks
11865         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
11866         local LRU_SIZE_B=$LRU_SIZE
11867         log "LVF=$LVF"
11868         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
11869         log "OLD_LVF=$OLD_LVF"
11870         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
11871
11872         # Let's make sure that we really have some margin. Client checks
11873         # cached locks every 10 sec.
11874         SLEEP=$((SLEEP+20))
11875         log "Sleep ${SLEEP} sec"
11876         local SEC=0
11877         while ((SEC<$SLEEP)); do
11878                 echo -n "..."
11879                 sleep 5
11880                 SEC=$((SEC+5))
11881                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
11882                 echo -n "$LRU_SIZE"
11883         done
11884         echo ""
11885         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
11886         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
11887
11888         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
11889                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
11890                 unlinkmany $DIR/$tdir/f $NR
11891                 return
11892         }
11893
11894         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
11895         log "unlink $NR files at $DIR/$tdir"
11896         unlinkmany $DIR/$tdir/f $NR
11897 }
11898 run_test 124a "lru resize ======================================="
11899
11900 get_max_pool_limit()
11901 {
11902         local limit=$($LCTL get_param \
11903                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
11904         local max=0
11905         for l in $limit; do
11906                 if [[ $l -gt $max ]]; then
11907                         max=$l
11908                 fi
11909         done
11910         echo $max
11911 }
11912
11913 test_124b() {
11914         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11915         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11916                 skip_env "no lru resize on server"
11917
11918         LIMIT=$(get_max_pool_limit)
11919
11920         NR=$(($(default_lru_size)*20))
11921         if [[ $NR -gt $LIMIT ]]; then
11922                 log "Limit lock number by $LIMIT locks"
11923                 NR=$LIMIT
11924         fi
11925
11926         IFree=$(mdsrate_inodes_available)
11927         if [ $IFree -lt $NR ]; then
11928                 log "Limit lock number by $IFree inodes"
11929                 NR=$IFree
11930         fi
11931
11932         lru_resize_disable mdc
11933         test_mkdir -p $DIR/$tdir/disable_lru_resize
11934
11935         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
11936         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
11937         cancel_lru_locks mdc
11938         stime=`date +%s`
11939         PID=""
11940         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11941         PID="$PID $!"
11942         sleep 2
11943         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11944         PID="$PID $!"
11945         sleep 2
11946         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11947         PID="$PID $!"
11948         wait $PID
11949         etime=`date +%s`
11950         nolruresize_delta=$((etime-stime))
11951         log "ls -la time: $nolruresize_delta seconds"
11952         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
11953         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
11954
11955         lru_resize_enable mdc
11956         test_mkdir -p $DIR/$tdir/enable_lru_resize
11957
11958         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
11959         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
11960         cancel_lru_locks mdc
11961         stime=`date +%s`
11962         PID=""
11963         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11964         PID="$PID $!"
11965         sleep 2
11966         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11967         PID="$PID $!"
11968         sleep 2
11969         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11970         PID="$PID $!"
11971         wait $PID
11972         etime=`date +%s`
11973         lruresize_delta=$((etime-stime))
11974         log "ls -la time: $lruresize_delta seconds"
11975         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
11976
11977         if [ $lruresize_delta -gt $nolruresize_delta ]; then
11978                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
11979         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
11980                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
11981         else
11982                 log "lru resize performs the same with no lru resize"
11983         fi
11984         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
11985 }
11986 run_test 124b "lru resize (performance test) ======================="
11987
11988 test_124c() {
11989         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11990         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11991                 skip_env "no lru resize on server"
11992
11993         # cache ununsed locks on client
11994         local nr=100
11995         cancel_lru_locks mdc
11996         test_mkdir $DIR/$tdir
11997         createmany -o $DIR/$tdir/f $nr ||
11998                 error "failed to create $nr files in $DIR/$tdir"
11999         ls -l $DIR/$tdir > /dev/null
12000
12001         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12002         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12003         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12004         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12005         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12006
12007         # set lru_max_age to 1 sec
12008         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12009         echo "sleep $((recalc_p * 2)) seconds..."
12010         sleep $((recalc_p * 2))
12011
12012         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12013         # restore lru_max_age
12014         $LCTL set_param -n $nsdir.lru_max_age $max_age
12015         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12016         unlinkmany $DIR/$tdir/f $nr
12017 }
12018 run_test 124c "LRUR cancel very aged locks"
12019
12020 test_124d() {
12021         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12022         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12023                 skip_env "no lru resize on server"
12024
12025         # cache ununsed locks on client
12026         local nr=100
12027
12028         lru_resize_disable mdc
12029         stack_trap "lru_resize_enable mdc" EXIT
12030
12031         cancel_lru_locks mdc
12032
12033         # asynchronous object destroy at MDT could cause bl ast to client
12034         test_mkdir $DIR/$tdir
12035         createmany -o $DIR/$tdir/f $nr ||
12036                 error "failed to create $nr files in $DIR/$tdir"
12037         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
12038
12039         ls -l $DIR/$tdir > /dev/null
12040
12041         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12042         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12043         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12044         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12045
12046         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12047
12048         # set lru_max_age to 1 sec
12049         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12050         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
12051
12052         echo "sleep $((recalc_p * 2)) seconds..."
12053         sleep $((recalc_p * 2))
12054
12055         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12056
12057         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12058 }
12059 run_test 124d "cancel very aged locks if lru-resize diasbaled"
12060
12061 test_125() { # 13358
12062         $LCTL get_param -n llite.*.client_type | grep -q local ||
12063                 skip "must run as local client"
12064         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
12065                 skip_env "must have acl enabled"
12066         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
12067
12068         test_mkdir $DIR/$tdir
12069         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
12070         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
12071         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
12072 }
12073 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
12074
12075 test_126() { # bug 12829/13455
12076         $GSS && skip_env "must run as gss disabled"
12077         $LCTL get_param -n llite.*.client_type | grep -q local ||
12078                 skip "must run as local client"
12079         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
12080
12081         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
12082         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
12083         rm -f $DIR/$tfile
12084         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
12085 }
12086 run_test 126 "check that the fsgid provided by the client is taken into account"
12087
12088 test_127a() { # bug 15521
12089         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12090         local name count samp unit min max sum sumsq
12091
12092         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
12093         echo "stats before reset"
12094         $LCTL get_param osc.*.stats
12095         $LCTL set_param osc.*.stats=0
12096         local fsize=$((2048 * 1024))
12097
12098         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
12099         cancel_lru_locks osc
12100         dd if=$DIR/$tfile of=/dev/null bs=$fsize
12101
12102         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
12103         stack_trap "rm -f $TMP/$tfile.tmp"
12104         while read name count samp unit min max sum sumsq; do
12105                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12106                 [ ! $min ] && error "Missing min value for $name proc entry"
12107                 eval $name=$count || error "Wrong proc format"
12108
12109                 case $name in
12110                 read_bytes|write_bytes)
12111                         [[ "$unit" =~ "bytes" ]] ||
12112                                 error "unit is not 'bytes': $unit"
12113                         (( $min >= 4096 )) || error "min is too small: $min"
12114                         (( $min <= $fsize )) || error "min is too big: $min"
12115                         (( $max >= 4096 )) || error "max is too small: $max"
12116                         (( $max <= $fsize )) || error "max is too big: $max"
12117                         (( $sum == $fsize )) || error "sum is wrong: $sum"
12118                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
12119                                 error "sumsquare is too small: $sumsq"
12120                         (( $sumsq <= $fsize * $fsize )) ||
12121                                 error "sumsquare is too big: $sumsq"
12122                         ;;
12123                 ost_read|ost_write)
12124                         [[ "$unit" =~ "usec" ]] ||
12125                                 error "unit is not 'usec': $unit"
12126                         ;;
12127                 *)      ;;
12128                 esac
12129         done < $DIR/$tfile.tmp
12130
12131         #check that we actually got some stats
12132         [ "$read_bytes" ] || error "Missing read_bytes stats"
12133         [ "$write_bytes" ] || error "Missing write_bytes stats"
12134         [ "$read_bytes" != 0 ] || error "no read done"
12135         [ "$write_bytes" != 0 ] || error "no write done"
12136 }
12137 run_test 127a "verify the client stats are sane"
12138
12139 test_127b() { # bug LU-333
12140         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12141         local name count samp unit min max sum sumsq
12142
12143         echo "stats before reset"
12144         $LCTL get_param llite.*.stats
12145         $LCTL set_param llite.*.stats=0
12146
12147         # perform 2 reads and writes so MAX is different from SUM.
12148         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12149         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12150         cancel_lru_locks osc
12151         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12152         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12153
12154         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
12155         stack_trap "rm -f $TMP/$tfile.tmp"
12156         while read name count samp unit min max sum sumsq; do
12157                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12158                 eval $name=$count || error "Wrong proc format"
12159
12160                 case $name in
12161                 read_bytes|write_bytes)
12162                         [[ "$unit" =~ "bytes" ]] ||
12163                                 error "unit is not 'bytes': $unit"
12164                         (( $count == 2 )) || error "count is not 2: $count"
12165                         (( $min == $PAGE_SIZE )) ||
12166                                 error "min is not $PAGE_SIZE: $min"
12167                         (( $max == $PAGE_SIZE )) ||
12168                                 error "max is not $PAGE_SIZE: $max"
12169                         (( $sum == $PAGE_SIZE * 2 )) ||
12170                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
12171                         ;;
12172                 read|write)
12173                         [[ "$unit" =~ "usec" ]] ||
12174                                 error "unit is not 'usec': $unit"
12175                         ;;
12176                 *)      ;;
12177                 esac
12178         done < $TMP/$tfile.tmp
12179
12180         #check that we actually got some stats
12181         [ "$read_bytes" ] || error "Missing read_bytes stats"
12182         [ "$write_bytes" ] || error "Missing write_bytes stats"
12183         [ "$read_bytes" != 0 ] || error "no read done"
12184         [ "$write_bytes" != 0 ] || error "no write done"
12185 }
12186 run_test 127b "verify the llite client stats are sane"
12187
12188 test_127c() { # LU-12394
12189         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12190         local size
12191         local bsize
12192         local reads
12193         local writes
12194         local count
12195
12196         $LCTL set_param llite.*.extents_stats=1
12197         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
12198
12199         # Use two stripes so there is enough space in default config
12200         $LFS setstripe -c 2 $DIR/$tfile
12201
12202         # Extent stats start at 0-4K and go in power of two buckets
12203         # LL_HIST_START = 12 --> 2^12 = 4K
12204         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
12205         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
12206         # small configs
12207         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
12208                 do
12209                 # Write and read, 2x each, second time at a non-zero offset
12210                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
12211                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
12212                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
12213                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
12214                 rm -f $DIR/$tfile
12215         done
12216
12217         $LCTL get_param llite.*.extents_stats
12218
12219         count=2
12220         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
12221                 do
12222                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
12223                                 grep -m 1 $bsize)
12224                 reads=$(echo $bucket | awk '{print $5}')
12225                 writes=$(echo $bucket | awk '{print $9}')
12226                 [ "$reads" -eq $count ] ||
12227                         error "$reads reads in < $bsize bucket, expect $count"
12228                 [ "$writes" -eq $count ] ||
12229                         error "$writes writes in < $bsize bucket, expect $count"
12230         done
12231
12232         # Test mmap write and read
12233         $LCTL set_param llite.*.extents_stats=c
12234         size=512
12235         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
12236         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
12237         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
12238
12239         $LCTL get_param llite.*.extents_stats
12240
12241         count=$(((size*1024) / PAGE_SIZE))
12242
12243         bsize=$((2 * PAGE_SIZE / 1024))K
12244
12245         bucket=$($LCTL get_param -n llite.*.extents_stats |
12246                         grep -m 1 $bsize)
12247         reads=$(echo $bucket | awk '{print $5}')
12248         writes=$(echo $bucket | awk '{print $9}')
12249         # mmap writes fault in the page first, creating an additonal read
12250         [ "$reads" -eq $((2 * count)) ] ||
12251                 error "$reads reads in < $bsize bucket, expect $count"
12252         [ "$writes" -eq $count ] ||
12253                 error "$writes writes in < $bsize bucket, expect $count"
12254 }
12255 run_test 127c "test llite extent stats with regular & mmap i/o"
12256
12257 test_128() { # bug 15212
12258         touch $DIR/$tfile
12259         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
12260                 find $DIR/$tfile
12261                 find $DIR/$tfile
12262         EOF
12263
12264         result=$(grep error $TMP/$tfile.log)
12265         rm -f $DIR/$tfile $TMP/$tfile.log
12266         [ -z "$result" ] ||
12267                 error "consecutive find's under interactive lfs failed"
12268 }
12269 run_test 128 "interactive lfs for 2 consecutive find's"
12270
12271 set_dir_limits () {
12272         local mntdev
12273         local canondev
12274         local node
12275
12276         local ldproc=/proc/fs/ldiskfs
12277         local facets=$(get_facets MDS)
12278
12279         for facet in ${facets//,/ }; do
12280                 canondev=$(ldiskfs_canon \
12281                            *.$(convert_facet2label $facet).mntdev $facet)
12282                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
12283                         ldproc=/sys/fs/ldiskfs
12284                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
12285                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
12286         done
12287 }
12288
12289 check_mds_dmesg() {
12290         local facets=$(get_facets MDS)
12291         for facet in ${facets//,/ }; do
12292                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
12293         done
12294         return 1
12295 }
12296
12297 test_129() {
12298         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12299         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
12300                 skip "Need MDS version with at least 2.5.56"
12301         if [ "$mds1_FSTYPE" != ldiskfs ]; then
12302                 skip_env "ldiskfs only test"
12303         fi
12304         remote_mds_nodsh && skip "remote MDS with nodsh"
12305
12306         local ENOSPC=28
12307         local has_warning=false
12308
12309         rm -rf $DIR/$tdir
12310         mkdir -p $DIR/$tdir
12311
12312         # block size of mds1
12313         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
12314         set_dir_limits $maxsize $((maxsize * 6 / 8))
12315         stack_trap "set_dir_limits 0 0"
12316         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
12317         local dirsize=$(stat -c%s "$DIR/$tdir")
12318         local nfiles=0
12319         while (( $dirsize <= $maxsize )); do
12320                 $MCREATE $DIR/$tdir/file_base_$nfiles
12321                 rc=$?
12322                 # check two errors:
12323                 # ENOSPC for ext4 max_dir_size, which has been used since
12324                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
12325                 if (( rc == ENOSPC )); then
12326                         set_dir_limits 0 0
12327                         echo "rc=$rc returned as expected after $nfiles files"
12328
12329                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
12330                                 error "create failed w/o dir size limit"
12331
12332                         # messages may be rate limited if test is run repeatedly
12333                         check_mds_dmesg '"is approaching max"' ||
12334                                 echo "warning message should be output"
12335                         check_mds_dmesg '"has reached max"' ||
12336                                 echo "reached message should be output"
12337
12338                         dirsize=$(stat -c%s "$DIR/$tdir")
12339
12340                         [[ $dirsize -ge $maxsize ]] && return 0
12341                         error "dirsize $dirsize < $maxsize after $nfiles files"
12342                 elif (( rc != 0 )); then
12343                         break
12344                 fi
12345                 nfiles=$((nfiles + 1))
12346                 dirsize=$(stat -c%s "$DIR/$tdir")
12347         done
12348
12349         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
12350 }
12351 run_test 129 "test directory size limit ========================"
12352
12353 OLDIFS="$IFS"
12354 cleanup_130() {
12355         trap 0
12356         IFS="$OLDIFS"
12357 }
12358
12359 test_130a() {
12360         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12361         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12362
12363         trap cleanup_130 EXIT RETURN
12364
12365         local fm_file=$DIR/$tfile
12366         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
12367         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
12368                 error "dd failed for $fm_file"
12369
12370         # LU-1795: test filefrag/FIEMAP once, even if unsupported
12371         filefrag -ves $fm_file
12372         RC=$?
12373         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12374                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12375         [ $RC != 0 ] && error "filefrag $fm_file failed"
12376
12377         filefrag_op=$(filefrag -ve -k $fm_file |
12378                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12379         lun=$($LFS getstripe -i $fm_file)
12380
12381         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
12382         IFS=$'\n'
12383         tot_len=0
12384         for line in $filefrag_op
12385         do
12386                 frag_lun=`echo $line | cut -d: -f5`
12387                 ext_len=`echo $line | cut -d: -f4`
12388                 if (( $frag_lun != $lun )); then
12389                         cleanup_130
12390                         error "FIEMAP on 1-stripe file($fm_file) failed"
12391                         return
12392                 fi
12393                 (( tot_len += ext_len ))
12394         done
12395
12396         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
12397                 cleanup_130
12398                 error "FIEMAP on 1-stripe file($fm_file) failed;"
12399                 return
12400         fi
12401
12402         cleanup_130
12403
12404         echo "FIEMAP on single striped file succeeded"
12405 }
12406 run_test 130a "FIEMAP (1-stripe file)"
12407
12408 test_130b() {
12409         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12410
12411         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12412         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12413
12414         trap cleanup_130 EXIT RETURN
12415
12416         local fm_file=$DIR/$tfile
12417         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12418                         error "setstripe on $fm_file"
12419         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12420                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12421
12422         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
12423                 error "dd failed on $fm_file"
12424
12425         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12426         filefrag_op=$(filefrag -ve -k $fm_file |
12427                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12428
12429         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12430                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12431
12432         IFS=$'\n'
12433         tot_len=0
12434         num_luns=1
12435         for line in $filefrag_op
12436         do
12437                 frag_lun=$(echo $line | cut -d: -f5 |
12438                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12439                 ext_len=$(echo $line | cut -d: -f4)
12440                 if (( $frag_lun != $last_lun )); then
12441                         if (( tot_len != 1024 )); then
12442                                 cleanup_130
12443                                 error "FIEMAP on $fm_file failed; returned " \
12444                                 "len $tot_len for OST $last_lun instead of 1024"
12445                                 return
12446                         else
12447                                 (( num_luns += 1 ))
12448                                 tot_len=0
12449                         fi
12450                 fi
12451                 (( tot_len += ext_len ))
12452                 last_lun=$frag_lun
12453         done
12454         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
12455                 cleanup_130
12456                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12457                         "luns or wrong len for OST $last_lun"
12458                 return
12459         fi
12460
12461         cleanup_130
12462
12463         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
12464 }
12465 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
12466
12467 test_130c() {
12468         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12469
12470         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12471         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12472
12473         trap cleanup_130 EXIT RETURN
12474
12475         local fm_file=$DIR/$tfile
12476         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
12477         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12478                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12479
12480         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
12481                         error "dd failed on $fm_file"
12482
12483         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12484         filefrag_op=$(filefrag -ve -k $fm_file |
12485                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12486
12487         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12488                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12489
12490         IFS=$'\n'
12491         tot_len=0
12492         num_luns=1
12493         for line in $filefrag_op
12494         do
12495                 frag_lun=$(echo $line | cut -d: -f5 |
12496                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12497                 ext_len=$(echo $line | cut -d: -f4)
12498                 if (( $frag_lun != $last_lun )); then
12499                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
12500                         if (( logical != 512 )); then
12501                                 cleanup_130
12502                                 error "FIEMAP on $fm_file failed; returned " \
12503                                 "logical start for lun $logical instead of 512"
12504                                 return
12505                         fi
12506                         if (( tot_len != 512 )); then
12507                                 cleanup_130
12508                                 error "FIEMAP on $fm_file failed; returned " \
12509                                 "len $tot_len for OST $last_lun instead of 1024"
12510                                 return
12511                         else
12512                                 (( num_luns += 1 ))
12513                                 tot_len=0
12514                         fi
12515                 fi
12516                 (( tot_len += ext_len ))
12517                 last_lun=$frag_lun
12518         done
12519         if (( num_luns != 2 || tot_len != 512 )); then
12520                 cleanup_130
12521                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12522                         "luns or wrong len for OST $last_lun"
12523                 return
12524         fi
12525
12526         cleanup_130
12527
12528         echo "FIEMAP on 2-stripe file with hole succeeded"
12529 }
12530 run_test 130c "FIEMAP (2-stripe file with hole)"
12531
12532 test_130d() {
12533         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
12534
12535         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12536         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12537
12538         trap cleanup_130 EXIT RETURN
12539
12540         local fm_file=$DIR/$tfile
12541         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12542                         error "setstripe on $fm_file"
12543         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12544                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12545
12546         local actual_stripe_count=$($LFS getstripe -c $fm_file)
12547         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
12548                 error "dd failed on $fm_file"
12549
12550         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12551         filefrag_op=$(filefrag -ve -k $fm_file |
12552                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12553
12554         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12555                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12556
12557         IFS=$'\n'
12558         tot_len=0
12559         num_luns=1
12560         for line in $filefrag_op
12561         do
12562                 frag_lun=$(echo $line | cut -d: -f5 |
12563                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12564                 ext_len=$(echo $line | cut -d: -f4)
12565                 if (( $frag_lun != $last_lun )); then
12566                         if (( tot_len != 1024 )); then
12567                                 cleanup_130
12568                                 error "FIEMAP on $fm_file failed; returned " \
12569                                 "len $tot_len for OST $last_lun instead of 1024"
12570                                 return
12571                         else
12572                                 (( num_luns += 1 ))
12573                                 tot_len=0
12574                         fi
12575                 fi
12576                 (( tot_len += ext_len ))
12577                 last_lun=$frag_lun
12578         done
12579         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
12580                 cleanup_130
12581                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12582                         "luns or wrong len for OST $last_lun"
12583                 return
12584         fi
12585
12586         cleanup_130
12587
12588         echo "FIEMAP on N-stripe file succeeded"
12589 }
12590 run_test 130d "FIEMAP (N-stripe file)"
12591
12592 test_130e() {
12593         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12594
12595         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12596         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12597
12598         trap cleanup_130 EXIT RETURN
12599
12600         local fm_file=$DIR/$tfile
12601         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
12602         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12603                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12604
12605         NUM_BLKS=512
12606         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
12607         for ((i = 0; i < $NUM_BLKS; i++))
12608         do
12609                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) conv=notrunc > /dev/null 2>&1
12610         done
12611
12612         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12613         filefrag_op=$(filefrag -ve -k $fm_file |
12614                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12615
12616         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12617                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12618
12619         IFS=$'\n'
12620         tot_len=0
12621         num_luns=1
12622         for line in $filefrag_op
12623         do
12624                 frag_lun=$(echo $line | cut -d: -f5 |
12625                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12626                 ext_len=$(echo $line | cut -d: -f4)
12627                 if (( $frag_lun != $last_lun )); then
12628                         if (( tot_len != $EXPECTED_LEN )); then
12629                                 cleanup_130
12630                                 error "FIEMAP on $fm_file failed; returned " \
12631                                 "len $tot_len for OST $last_lun instead " \
12632                                 "of $EXPECTED_LEN"
12633                                 return
12634                         else
12635                                 (( num_luns += 1 ))
12636                                 tot_len=0
12637                         fi
12638                 fi
12639                 (( tot_len += ext_len ))
12640                 last_lun=$frag_lun
12641         done
12642         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
12643                 cleanup_130
12644                 error "FIEMAP on $fm_file failed; returned wrong number " \
12645                         "of luns or wrong len for OST $last_lun"
12646                 return
12647         fi
12648
12649         cleanup_130
12650
12651         echo "FIEMAP with continuation calls succeeded"
12652 }
12653 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
12654
12655 test_130f() {
12656         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12657         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12658
12659         local fm_file=$DIR/$tfile
12660         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
12661                 error "multiop create with lov_delay_create on $fm_file"
12662
12663         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12664         filefrag_extents=$(filefrag -vek $fm_file |
12665                            awk '/extents? found/ { print $2 }')
12666         if [[ "$filefrag_extents" != "0" ]]; then
12667                 error "FIEMAP on $fm_file failed; " \
12668                       "returned $filefrag_extents expected 0"
12669         fi
12670
12671         rm -f $fm_file
12672 }
12673 run_test 130f "FIEMAP (unstriped file)"
12674
12675 # Test for writev/readv
12676 test_131a() {
12677         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
12678                 error "writev test failed"
12679         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
12680                 error "readv failed"
12681         rm -f $DIR/$tfile
12682 }
12683 run_test 131a "test iov's crossing stripe boundary for writev/readv"
12684
12685 test_131b() {
12686         local fsize=$((524288 + 1048576 + 1572864))
12687         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
12688                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12689                         error "append writev test failed"
12690
12691         ((fsize += 1572864 + 1048576))
12692         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
12693                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12694                         error "append writev test failed"
12695         rm -f $DIR/$tfile
12696 }
12697 run_test 131b "test append writev"
12698
12699 test_131c() {
12700         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
12701         error "NOT PASS"
12702 }
12703 run_test 131c "test read/write on file w/o objects"
12704
12705 test_131d() {
12706         rwv -f $DIR/$tfile -w -n 1 1572864
12707         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
12708         if [ "$NOB" != 1572864 ]; then
12709                 error "Short read filed: read $NOB bytes instead of 1572864"
12710         fi
12711         rm -f $DIR/$tfile
12712 }
12713 run_test 131d "test short read"
12714
12715 test_131e() {
12716         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
12717         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
12718         error "read hitting hole failed"
12719         rm -f $DIR/$tfile
12720 }
12721 run_test 131e "test read hitting hole"
12722
12723 check_stats() {
12724         local facet=$1
12725         local op=$2
12726         local want=${3:-0}
12727         local res
12728
12729         case $facet in
12730         mds*) res=$(do_facet $facet \
12731                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
12732                  ;;
12733         ost*) res=$(do_facet $facet \
12734                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
12735                  ;;
12736         *) error "Wrong facet '$facet'" ;;
12737         esac
12738         [ "$res" ] || error "The counter for $op on $facet was not incremented"
12739         # if the argument $3 is zero, it means any stat increment is ok.
12740         if [[ $want -gt 0 ]]; then
12741                 local count=$(echo $res | awk '{ print $2 }')
12742                 [[ $count -ne $want ]] &&
12743                         error "The $op counter on $facet is $count, not $want"
12744         fi
12745 }
12746
12747 test_133a() {
12748         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12749         remote_ost_nodsh && skip "remote OST with nodsh"
12750         remote_mds_nodsh && skip "remote MDS with nodsh"
12751         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
12752                 skip_env "MDS doesn't support rename stats"
12753
12754         local testdir=$DIR/${tdir}/stats_testdir
12755
12756         mkdir -p $DIR/${tdir}
12757
12758         # clear stats.
12759         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12760         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12761
12762         # verify mdt stats first.
12763         mkdir ${testdir} || error "mkdir failed"
12764         check_stats $SINGLEMDS "mkdir" 1
12765         touch ${testdir}/${tfile} || error "touch failed"
12766         check_stats $SINGLEMDS "open" 1
12767         check_stats $SINGLEMDS "close" 1
12768         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
12769                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
12770                 check_stats $SINGLEMDS "mknod" 2
12771         }
12772         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
12773         check_stats $SINGLEMDS "unlink" 1
12774         rm -f ${testdir}/${tfile} || error "file remove failed"
12775         check_stats $SINGLEMDS "unlink" 2
12776
12777         # remove working dir and check mdt stats again.
12778         rmdir ${testdir} || error "rmdir failed"
12779         check_stats $SINGLEMDS "rmdir" 1
12780
12781         local testdir1=$DIR/${tdir}/stats_testdir1
12782         mkdir -p ${testdir}
12783         mkdir -p ${testdir1}
12784         touch ${testdir1}/test1
12785         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
12786         check_stats $SINGLEMDS "crossdir_rename" 1
12787
12788         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
12789         check_stats $SINGLEMDS "samedir_rename" 1
12790
12791         rm -rf $DIR/${tdir}
12792 }
12793 run_test 133a "Verifying MDT stats ========================================"
12794
12795 test_133b() {
12796         local res
12797
12798         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12799         remote_ost_nodsh && skip "remote OST with nodsh"
12800         remote_mds_nodsh && skip "remote MDS with nodsh"
12801
12802         local testdir=$DIR/${tdir}/stats_testdir
12803
12804         mkdir -p ${testdir} || error "mkdir failed"
12805         touch ${testdir}/${tfile} || error "touch failed"
12806         cancel_lru_locks mdc
12807
12808         # clear stats.
12809         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12810         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12811
12812         # extra mdt stats verification.
12813         chmod 444 ${testdir}/${tfile} || error "chmod failed"
12814         check_stats $SINGLEMDS "setattr" 1
12815         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12816         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
12817         then            # LU-1740
12818                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
12819                 check_stats $SINGLEMDS "getattr" 1
12820         fi
12821         rm -rf $DIR/${tdir}
12822
12823         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
12824         # so the check below is not reliable
12825         [ $MDSCOUNT -eq 1 ] || return 0
12826
12827         # Sleep to avoid a cached response.
12828         #define OBD_STATFS_CACHE_SECONDS 1
12829         sleep 2
12830         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12831         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12832         $LFS df || error "lfs failed"
12833         check_stats $SINGLEMDS "statfs" 1
12834
12835         # check aggregated statfs (LU-10018)
12836         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
12837                 return 0
12838         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
12839                 return 0
12840         sleep 2
12841         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12842         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12843         df $DIR
12844         check_stats $SINGLEMDS "statfs" 1
12845
12846         # We want to check that the client didn't send OST_STATFS to
12847         # ost1 but the MDT also uses OST_STATFS for precreate. So some
12848         # extra care is needed here.
12849         if remote_mds; then
12850                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
12851                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
12852
12853                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
12854                 [ "$res" ] && error "OST got STATFS"
12855         fi
12856
12857         return 0
12858 }
12859 run_test 133b "Verifying extra MDT stats =================================="
12860
12861 test_133c() {
12862         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12863         remote_ost_nodsh && skip "remote OST with nodsh"
12864         remote_mds_nodsh && skip "remote MDS with nodsh"
12865
12866         local testdir=$DIR/$tdir/stats_testdir
12867
12868         test_mkdir -p $testdir
12869
12870         # verify obdfilter stats.
12871         $LFS setstripe -c 1 -i 0 $testdir/$tfile
12872         sync
12873         cancel_lru_locks osc
12874         wait_delete_completed
12875
12876         # clear stats.
12877         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12878         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12879
12880         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
12881                 error "dd failed"
12882         sync
12883         cancel_lru_locks osc
12884         check_stats ost1 "write" 1
12885
12886         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
12887         check_stats ost1 "read" 1
12888
12889         > $testdir/$tfile || error "truncate failed"
12890         check_stats ost1 "punch" 1
12891
12892         rm -f $testdir/$tfile || error "file remove failed"
12893         wait_delete_completed
12894         check_stats ost1 "destroy" 1
12895
12896         rm -rf $DIR/$tdir
12897 }
12898 run_test 133c "Verifying OST stats ========================================"
12899
12900 order_2() {
12901         local value=$1
12902         local orig=$value
12903         local order=1
12904
12905         while [ $value -ge 2 ]; do
12906                 order=$((order*2))
12907                 value=$((value/2))
12908         done
12909
12910         if [ $orig -gt $order ]; then
12911                 order=$((order*2))
12912         fi
12913         echo $order
12914 }
12915
12916 size_in_KMGT() {
12917     local value=$1
12918     local size=('K' 'M' 'G' 'T');
12919     local i=0
12920     local size_string=$value
12921
12922     while [ $value -ge 1024 ]; do
12923         if [ $i -gt 3 ]; then
12924             #T is the biggest unit we get here, if that is bigger,
12925             #just return XXXT
12926             size_string=${value}T
12927             break
12928         fi
12929         value=$((value >> 10))
12930         if [ $value -lt 1024 ]; then
12931             size_string=${value}${size[$i]}
12932             break
12933         fi
12934         i=$((i + 1))
12935     done
12936
12937     echo $size_string
12938 }
12939
12940 get_rename_size() {
12941         local size=$1
12942         local context=${2:-.}
12943         local sample=$(do_facet $SINGLEMDS $LCTL \
12944                 get_param mdt.$FSNAME-MDT0000.rename_stats |
12945                 grep -A1 $context |
12946                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
12947         echo $sample
12948 }
12949
12950 test_133d() {
12951         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12952         remote_ost_nodsh && skip "remote OST with nodsh"
12953         remote_mds_nodsh && skip "remote MDS with nodsh"
12954         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
12955                 skip_env "MDS doesn't support rename stats"
12956
12957         local testdir1=$DIR/${tdir}/stats_testdir1
12958         local testdir2=$DIR/${tdir}/stats_testdir2
12959         mkdir -p $DIR/${tdir}
12960
12961         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
12962
12963         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
12964         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
12965
12966         createmany -o $testdir1/test 512 || error "createmany failed"
12967
12968         # check samedir rename size
12969         mv ${testdir1}/test0 ${testdir1}/test_0
12970
12971         local testdir1_size=$(ls -l $DIR/${tdir} |
12972                 awk '/stats_testdir1/ {print $5}')
12973         local testdir2_size=$(ls -l $DIR/${tdir} |
12974                 awk '/stats_testdir2/ {print $5}')
12975
12976         testdir1_size=$(order_2 $testdir1_size)
12977         testdir2_size=$(order_2 $testdir2_size)
12978
12979         testdir1_size=$(size_in_KMGT $testdir1_size)
12980         testdir2_size=$(size_in_KMGT $testdir2_size)
12981
12982         echo "source rename dir size: ${testdir1_size}"
12983         echo "target rename dir size: ${testdir2_size}"
12984
12985         local cmd="do_facet $SINGLEMDS $LCTL "
12986         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
12987
12988         eval $cmd || error "$cmd failed"
12989         local samedir=$($cmd | grep 'same_dir')
12990         local same_sample=$(get_rename_size $testdir1_size)
12991         [ -z "$samedir" ] && error "samedir_rename_size count error"
12992         [[ $same_sample -eq 1 ]] ||
12993                 error "samedir_rename_size error $same_sample"
12994         echo "Check same dir rename stats success"
12995
12996         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
12997
12998         # check crossdir rename size
12999         mv ${testdir1}/test_0 ${testdir2}/test_0
13000
13001         testdir1_size=$(ls -l $DIR/${tdir} |
13002                 awk '/stats_testdir1/ {print $5}')
13003         testdir2_size=$(ls -l $DIR/${tdir} |
13004                 awk '/stats_testdir2/ {print $5}')
13005
13006         testdir1_size=$(order_2 $testdir1_size)
13007         testdir2_size=$(order_2 $testdir2_size)
13008
13009         testdir1_size=$(size_in_KMGT $testdir1_size)
13010         testdir2_size=$(size_in_KMGT $testdir2_size)
13011
13012         echo "source rename dir size: ${testdir1_size}"
13013         echo "target rename dir size: ${testdir2_size}"
13014
13015         eval $cmd || error "$cmd failed"
13016         local crossdir=$($cmd | grep 'crossdir')
13017         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
13018         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
13019         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
13020         [[ $src_sample -eq 1 ]] ||
13021                 error "crossdir_rename_size error $src_sample"
13022         [[ $tgt_sample -eq 1 ]] ||
13023                 error "crossdir_rename_size error $tgt_sample"
13024         echo "Check cross dir rename stats success"
13025         rm -rf $DIR/${tdir}
13026 }
13027 run_test 133d "Verifying rename_stats ========================================"
13028
13029 test_133e() {
13030         remote_mds_nodsh && skip "remote MDS with nodsh"
13031         remote_ost_nodsh && skip "remote OST with nodsh"
13032         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13033
13034         local testdir=$DIR/${tdir}/stats_testdir
13035         local ctr f0 f1 bs=32768 count=42 sum
13036
13037         mkdir -p ${testdir} || error "mkdir failed"
13038
13039         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
13040
13041         for ctr in {write,read}_bytes; do
13042                 sync
13043                 cancel_lru_locks osc
13044
13045                 do_facet ost1 $LCTL set_param -n \
13046                         "obdfilter.*.exports.clear=clear"
13047
13048                 if [ $ctr = write_bytes ]; then
13049                         f0=/dev/zero
13050                         f1=${testdir}/${tfile}
13051                 else
13052                         f0=${testdir}/${tfile}
13053                         f1=/dev/null
13054                 fi
13055
13056                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
13057                         error "dd failed"
13058                 sync
13059                 cancel_lru_locks osc
13060
13061                 sum=$(do_facet ost1 $LCTL get_param \
13062                         "obdfilter.*.exports.*.stats" |
13063                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
13064                                 $1 == ctr { sum += $7 }
13065                                 END { printf("%0.0f", sum) }')
13066
13067                 if ((sum != bs * count)); then
13068                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
13069                 fi
13070         done
13071
13072         rm -rf $DIR/${tdir}
13073 }
13074 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
13075
13076 test_133f() {
13077         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
13078                 skip "too old lustre for get_param -R ($facet_ver)"
13079
13080         # verifying readability.
13081         $LCTL get_param -R '*' &> /dev/null
13082
13083         # Verifing writability with badarea_io.
13084         $LCTL list_param -FR '*' | grep '=' | tr -d = |
13085                 egrep -v 'force_lbug|changelog_mask' | xargs badarea_io ||
13086                 error "client badarea_io failed"
13087
13088         # remount the FS in case writes/reads /proc break the FS
13089         cleanup || error "failed to unmount"
13090         setup || error "failed to setup"
13091 }
13092 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
13093
13094 test_133g() {
13095         remote_mds_nodsh && skip "remote MDS with nodsh"
13096         remote_ost_nodsh && skip "remote OST with nodsh"
13097
13098         local facet
13099         for facet in mds1 ost1; do
13100                 local facet_ver=$(lustre_version_code $facet)
13101                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
13102                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
13103                 else
13104                         log "$facet: too old lustre for get_param -R"
13105                 fi
13106                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
13107                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
13108                                 tr -d = | egrep -v 'force_lbug|changelog_mask' |
13109                                 xargs badarea_io" ||
13110                                         error "$facet badarea_io failed"
13111                 else
13112                         skip_noexit "$facet: too old lustre for get_param -R"
13113                 fi
13114         done
13115
13116         # remount the FS in case writes/reads /proc break the FS
13117         cleanup || error "failed to unmount"
13118         setup || error "failed to setup"
13119 }
13120 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
13121
13122 test_133h() {
13123         remote_mds_nodsh && skip "remote MDS with nodsh"
13124         remote_ost_nodsh && skip "remote OST with nodsh"
13125         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
13126                 skip "Need MDS version at least 2.9.54"
13127
13128         local facet
13129         for facet in client mds1 ost1; do
13130                 # Get the list of files that are missing the terminating newline
13131                 local plist=$(do_facet $facet
13132                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
13133                 local ent
13134                 for ent in $plist; do
13135                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
13136                                 awk -v FS='\v' -v RS='\v\v' \
13137                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
13138                                         print FILENAME}'" 2>/dev/null)
13139                         [ -z $missing ] || {
13140                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
13141                                 error "file does not end with newline: $facet-$ent"
13142                         }
13143                 done
13144         done
13145 }
13146 run_test 133h "Proc files should end with newlines"
13147
13148 test_134a() {
13149         remote_mds_nodsh && skip "remote MDS with nodsh"
13150         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13151                 skip "Need MDS version at least 2.7.54"
13152
13153         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13154         cancel_lru_locks mdc
13155
13156         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13157         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13158         [ $unused -eq 0 ] || error "$unused locks are not cleared"
13159
13160         local nr=1000
13161         createmany -o $DIR/$tdir/f $nr ||
13162                 error "failed to create $nr files in $DIR/$tdir"
13163         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13164
13165         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
13166         do_facet mds1 $LCTL set_param fail_loc=0x327
13167         do_facet mds1 $LCTL set_param fail_val=500
13168         touch $DIR/$tdir/m
13169
13170         echo "sleep 10 seconds ..."
13171         sleep 10
13172         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
13173
13174         do_facet mds1 $LCTL set_param fail_loc=0
13175         do_facet mds1 $LCTL set_param fail_val=0
13176         [ $lck_cnt -lt $unused ] ||
13177                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
13178
13179         rm $DIR/$tdir/m
13180         unlinkmany $DIR/$tdir/f $nr
13181 }
13182 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
13183
13184 test_134b() {
13185         remote_mds_nodsh && skip "remote MDS with nodsh"
13186         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13187                 skip "Need MDS version at least 2.7.54"
13188
13189         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13190         cancel_lru_locks mdc
13191
13192         local low_wm=$(do_facet mds1 $LCTL get_param -n \
13193                         ldlm.lock_reclaim_threshold_mb)
13194         # disable reclaim temporarily
13195         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
13196
13197         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
13198         do_facet mds1 $LCTL set_param fail_loc=0x328
13199         do_facet mds1 $LCTL set_param fail_val=500
13200
13201         $LCTL set_param debug=+trace
13202
13203         local nr=600
13204         createmany -o $DIR/$tdir/f $nr &
13205         local create_pid=$!
13206
13207         echo "Sleep $TIMEOUT seconds ..."
13208         sleep $TIMEOUT
13209         if ! ps -p $create_pid  > /dev/null 2>&1; then
13210                 do_facet mds1 $LCTL set_param fail_loc=0
13211                 do_facet mds1 $LCTL set_param fail_val=0
13212                 do_facet mds1 $LCTL set_param \
13213                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
13214                 error "createmany finished incorrectly!"
13215         fi
13216         do_facet mds1 $LCTL set_param fail_loc=0
13217         do_facet mds1 $LCTL set_param fail_val=0
13218         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
13219         wait $create_pid || return 1
13220
13221         unlinkmany $DIR/$tdir/f $nr
13222 }
13223 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
13224
13225 test_135() {
13226         remote_mds_nodsh && skip "remote MDS with nodsh"
13227         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13228                 skip "Need MDS version at least 2.13.50"
13229         local fname
13230
13231         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13232
13233 #define OBD_FAIL_PLAIN_RECORDS 0x1319
13234         #set only one record at plain llog
13235         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
13236
13237         #fill already existed plain llog each 64767
13238         #wrapping whole catalog
13239         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13240
13241         createmany -o $DIR/$tdir/$tfile_ 64700
13242         for (( i = 0; i < 64700; i = i + 2 ))
13243         do
13244                 rm $DIR/$tdir/$tfile_$i &
13245                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13246                 local pid=$!
13247                 wait $pid
13248         done
13249
13250         #waiting osp synchronization
13251         wait_delete_completed
13252 }
13253 run_test 135 "Race catalog processing"
13254
13255 test_136() {
13256         remote_mds_nodsh && skip "remote MDS with nodsh"
13257         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13258                 skip "Need MDS version at least 2.13.50"
13259         local fname
13260
13261         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13262         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
13263         #set only one record at plain llog
13264 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
13265         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
13266
13267         #fill already existed 2 plain llogs each 64767
13268         #wrapping whole catalog
13269         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13270         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
13271         wait_delete_completed
13272
13273         createmany -o $DIR/$tdir/$tfile_ 10
13274         sleep 25
13275
13276         do_facet $SINGLEMDS $LCTL set_param fail_val=3
13277         for (( i = 0; i < 10; i = i + 3 ))
13278         do
13279                 rm $DIR/$tdir/$tfile_$i &
13280                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13281                 local pid=$!
13282                 wait $pid
13283                 sleep 7
13284                 rm $DIR/$tdir/$tfile_$((i + 2)) &
13285         done
13286
13287         #waiting osp synchronization
13288         wait_delete_completed
13289 }
13290 run_test 136 "Race catalog processing 2"
13291
13292 test_140() { #bug-17379
13293         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13294
13295         test_mkdir $DIR/$tdir
13296         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
13297         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
13298
13299         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
13300         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
13301         local i=0
13302         while i=$((i + 1)); do
13303                 test_mkdir $i
13304                 cd $i || error "Changing to $i"
13305                 ln -s ../stat stat || error "Creating stat symlink"
13306                 # Read the symlink until ELOOP present,
13307                 # not LBUGing the system is considered success,
13308                 # we didn't overrun the stack.
13309                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
13310                 if [ $ret -ne 0 ]; then
13311                         if [ $ret -eq 40 ]; then
13312                                 break  # -ELOOP
13313                         else
13314                                 error "Open stat symlink"
13315                                         return
13316                         fi
13317                 fi
13318         done
13319         i=$((i - 1))
13320         echo "The symlink depth = $i"
13321         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
13322                 error "Invalid symlink depth"
13323
13324         # Test recursive symlink
13325         ln -s symlink_self symlink_self
13326         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
13327         echo "open symlink_self returns $ret"
13328         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
13329 }
13330 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
13331
13332 test_150a() {
13333         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13334
13335         local TF="$TMP/$tfile"
13336
13337         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13338         cp $TF $DIR/$tfile
13339         cancel_lru_locks $OSC
13340         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
13341         remount_client $MOUNT
13342         df -P $MOUNT
13343         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
13344
13345         $TRUNCATE $TF 6000
13346         $TRUNCATE $DIR/$tfile 6000
13347         cancel_lru_locks $OSC
13348         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
13349
13350         echo "12345" >>$TF
13351         echo "12345" >>$DIR/$tfile
13352         cancel_lru_locks $OSC
13353         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
13354
13355         echo "12345" >>$TF
13356         echo "12345" >>$DIR/$tfile
13357         cancel_lru_locks $OSC
13358         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
13359
13360         rm -f $TF
13361         true
13362 }
13363 run_test 150a "truncate/append tests"
13364
13365 test_150b() {
13366         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13367         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13368                 skip "Need OST version at least 2.13.53"
13369         touch $DIR/$tfile
13370         check_fallocate $DIR/$tfile || error "fallocate failed"
13371 }
13372 run_test 150b "Verify fallocate (prealloc) functionality"
13373
13374 test_150c() {
13375         local bytes
13376         local want
13377
13378         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13379         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13380                 skip "Need OST version at least 2.13.53"
13381
13382         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
13383         fallocate -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
13384         sync; sync_all_data
13385         cancel_lru_locks $OSC
13386         sleep 5
13387         bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
13388         want=$((OSTCOUNT * 1048576))
13389
13390         # Must allocate all requested space, not more than 5% extra
13391         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13392                 error "bytes $bytes is not $want"
13393 }
13394 run_test 150c "Verify fallocate Size and Blocks"
13395
13396 test_150d() {
13397         local bytes
13398         local want
13399
13400         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13401         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13402                 skip "Need OST version at least 2.13.53"
13403
13404         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
13405         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
13406         sync; sync_all_data
13407         cancel_lru_locks $OSC
13408         sleep 5
13409         bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
13410         want=$((OSTCOUNT * 1048576))
13411
13412         # Must allocate all requested space, not more than 5% extra
13413         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13414                 error "bytes $bytes is not $want"
13415 }
13416 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
13417
13418 #LU-2902 roc_hit was not able to read all values from lproc
13419 function roc_hit_init() {
13420         local list=$(comma_list $(osts_nodes))
13421         local dir=$DIR/$tdir-check
13422         local file=$dir/$tfile
13423         local BEFORE
13424         local AFTER
13425         local idx
13426
13427         test_mkdir $dir
13428         #use setstripe to do a write to every ost
13429         for i in $(seq 0 $((OSTCOUNT-1))); do
13430                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
13431                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
13432                 idx=$(printf %04x $i)
13433                 BEFORE=$(get_osd_param $list *OST*$idx stats |
13434                         awk '$1 == "cache_access" {sum += $7}
13435                                 END { printf("%0.0f", sum) }')
13436
13437                 cancel_lru_locks osc
13438                 cat $file >/dev/null
13439
13440                 AFTER=$(get_osd_param $list *OST*$idx stats |
13441                         awk '$1 == "cache_access" {sum += $7}
13442                                 END { printf("%0.0f", sum) }')
13443
13444                 echo BEFORE:$BEFORE AFTER:$AFTER
13445                 if ! let "AFTER - BEFORE == 4"; then
13446                         rm -rf $dir
13447                         error "roc_hit is not safe to use"
13448                 fi
13449                 rm $file
13450         done
13451
13452         rm -rf $dir
13453 }
13454
13455 function roc_hit() {
13456         local list=$(comma_list $(osts_nodes))
13457         echo $(get_osd_param $list '' stats |
13458                 awk '$1 == "cache_hit" {sum += $7}
13459                         END { printf("%0.0f", sum) }')
13460 }
13461
13462 function set_cache() {
13463         local on=1
13464
13465         if [ "$2" == "off" ]; then
13466                 on=0;
13467         fi
13468         local list=$(comma_list $(osts_nodes))
13469         set_osd_param $list '' $1_cache_enable $on
13470
13471         cancel_lru_locks osc
13472 }
13473
13474 test_151() {
13475         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13476         remote_ost_nodsh && skip "remote OST with nodsh"
13477
13478         local CPAGES=3
13479         local list=$(comma_list $(osts_nodes))
13480
13481         # check whether obdfilter is cache capable at all
13482         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
13483                 skip "not cache-capable obdfilter"
13484         fi
13485
13486         # check cache is enabled on all obdfilters
13487         if get_osd_param $list '' read_cache_enable | grep 0; then
13488                 skip "oss cache is disabled"
13489         fi
13490
13491         set_osd_param $list '' writethrough_cache_enable 1
13492
13493         # check write cache is enabled on all obdfilters
13494         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
13495                 skip "oss write cache is NOT enabled"
13496         fi
13497
13498         roc_hit_init
13499
13500         #define OBD_FAIL_OBD_NO_LRU  0x609
13501         do_nodes $list $LCTL set_param fail_loc=0x609
13502
13503         # pages should be in the case right after write
13504         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
13505                 error "dd failed"
13506
13507         local BEFORE=$(roc_hit)
13508         cancel_lru_locks osc
13509         cat $DIR/$tfile >/dev/null
13510         local AFTER=$(roc_hit)
13511
13512         do_nodes $list $LCTL set_param fail_loc=0
13513
13514         if ! let "AFTER - BEFORE == CPAGES"; then
13515                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
13516         fi
13517
13518         cancel_lru_locks osc
13519         # invalidates OST cache
13520         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
13521         set_osd_param $list '' read_cache_enable 0
13522         cat $DIR/$tfile >/dev/null
13523
13524         # now data shouldn't be found in the cache
13525         BEFORE=$(roc_hit)
13526         cancel_lru_locks osc
13527         cat $DIR/$tfile >/dev/null
13528         AFTER=$(roc_hit)
13529         if let "AFTER - BEFORE != 0"; then
13530                 error "IN CACHE: before: $BEFORE, after: $AFTER"
13531         fi
13532
13533         set_osd_param $list '' read_cache_enable 1
13534         rm -f $DIR/$tfile
13535 }
13536 run_test 151 "test cache on oss and controls ==============================="
13537
13538 test_152() {
13539         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13540
13541         local TF="$TMP/$tfile"
13542
13543         # simulate ENOMEM during write
13544 #define OBD_FAIL_OST_NOMEM      0x226
13545         lctl set_param fail_loc=0x80000226
13546         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13547         cp $TF $DIR/$tfile
13548         sync || error "sync failed"
13549         lctl set_param fail_loc=0
13550
13551         # discard client's cache
13552         cancel_lru_locks osc
13553
13554         # simulate ENOMEM during read
13555         lctl set_param fail_loc=0x80000226
13556         cmp $TF $DIR/$tfile || error "cmp failed"
13557         lctl set_param fail_loc=0
13558
13559         rm -f $TF
13560 }
13561 run_test 152 "test read/write with enomem ============================"
13562
13563 test_153() {
13564         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
13565 }
13566 run_test 153 "test if fdatasync does not crash ======================="
13567
13568 dot_lustre_fid_permission_check() {
13569         local fid=$1
13570         local ffid=$MOUNT/.lustre/fid/$fid
13571         local test_dir=$2
13572
13573         echo "stat fid $fid"
13574         stat $ffid > /dev/null || error "stat $ffid failed."
13575         echo "touch fid $fid"
13576         touch $ffid || error "touch $ffid failed."
13577         echo "write to fid $fid"
13578         cat /etc/hosts > $ffid || error "write $ffid failed."
13579         echo "read fid $fid"
13580         diff /etc/hosts $ffid || error "read $ffid failed."
13581         echo "append write to fid $fid"
13582         cat /etc/hosts >> $ffid || error "append write $ffid failed."
13583         echo "rename fid $fid"
13584         mv $ffid $test_dir/$tfile.1 &&
13585                 error "rename $ffid to $tfile.1 should fail."
13586         touch $test_dir/$tfile.1
13587         mv $test_dir/$tfile.1 $ffid &&
13588                 error "rename $tfile.1 to $ffid should fail."
13589         rm -f $test_dir/$tfile.1
13590         echo "truncate fid $fid"
13591         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
13592         echo "link fid $fid"
13593         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
13594         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
13595                 echo "setfacl fid $fid"
13596                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
13597                 echo "getfacl fid $fid"
13598                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
13599         fi
13600         echo "unlink fid $fid"
13601         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
13602         echo "mknod fid $fid"
13603         mknod $ffid c 1 3 && error "mknod $ffid should fail."
13604
13605         fid=[0xf00000400:0x1:0x0]
13606         ffid=$MOUNT/.lustre/fid/$fid
13607
13608         echo "stat non-exist fid $fid"
13609         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
13610         echo "write to non-exist fid $fid"
13611         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
13612         echo "link new fid $fid"
13613         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
13614
13615         mkdir -p $test_dir/$tdir
13616         touch $test_dir/$tdir/$tfile
13617         fid=$($LFS path2fid $test_dir/$tdir)
13618         rc=$?
13619         [ $rc -ne 0 ] &&
13620                 error "error: could not get fid for $test_dir/$dir/$tfile."
13621
13622         ffid=$MOUNT/.lustre/fid/$fid
13623
13624         echo "ls $fid"
13625         ls $ffid > /dev/null || error "ls $ffid failed."
13626         echo "touch $fid/$tfile.1"
13627         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
13628
13629         echo "touch $MOUNT/.lustre/fid/$tfile"
13630         touch $MOUNT/.lustre/fid/$tfile && \
13631                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
13632
13633         echo "setxattr to $MOUNT/.lustre/fid"
13634         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
13635
13636         echo "listxattr for $MOUNT/.lustre/fid"
13637         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
13638
13639         echo "delxattr from $MOUNT/.lustre/fid"
13640         setfattr -x trusted.name1 $MOUNT/.lustre/fid
13641
13642         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
13643         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
13644                 error "touch invalid fid should fail."
13645
13646         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
13647         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
13648                 error "touch non-normal fid should fail."
13649
13650         echo "rename $tdir to $MOUNT/.lustre/fid"
13651         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
13652                 error "rename to $MOUNT/.lustre/fid should fail."
13653
13654         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
13655         then            # LU-3547
13656                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
13657                 local new_obf_mode=777
13658
13659                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
13660                 chmod $new_obf_mode $DIR/.lustre/fid ||
13661                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
13662
13663                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
13664                 [ $obf_mode -eq $new_obf_mode ] ||
13665                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
13666
13667                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
13668                 chmod $old_obf_mode $DIR/.lustre/fid ||
13669                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
13670         fi
13671
13672         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
13673         fid=$($LFS path2fid $test_dir/$tfile-2)
13674
13675         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
13676         then # LU-5424
13677                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
13678                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
13679                         error "create lov data thru .lustre failed"
13680         fi
13681         echo "cp /etc/passwd $test_dir/$tfile-2"
13682         cp /etc/passwd $test_dir/$tfile-2 ||
13683                 error "copy to $test_dir/$tfile-2 failed."
13684         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
13685         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
13686                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
13687
13688         rm -rf $test_dir/tfile.lnk
13689         rm -rf $test_dir/$tfile-2
13690 }
13691
13692 test_154A() {
13693         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13694                 skip "Need MDS version at least 2.4.1"
13695
13696         local tf=$DIR/$tfile
13697         touch $tf
13698
13699         local fid=$($LFS path2fid $tf)
13700         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
13701
13702         # check that we get the same pathname back
13703         local rootpath
13704         local found
13705         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
13706                 echo "$rootpath $fid"
13707                 found=$($LFS fid2path $rootpath "$fid")
13708                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
13709                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
13710         done
13711
13712         # check wrong root path format
13713         rootpath=$MOUNT"_wrong"
13714         found=$($LFS fid2path $rootpath "$fid")
13715         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
13716 }
13717 run_test 154A "lfs path2fid and fid2path basic checks"
13718
13719 test_154B() {
13720         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13721                 skip "Need MDS version at least 2.4.1"
13722
13723         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
13724         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
13725         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
13726         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
13727
13728         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
13729         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
13730
13731         # check that we get the same pathname
13732         echo "PFID: $PFID, name: $name"
13733         local FOUND=$($LFS fid2path $MOUNT "$PFID")
13734         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
13735         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
13736                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
13737
13738         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
13739 }
13740 run_test 154B "verify the ll_decode_linkea tool"
13741
13742 test_154a() {
13743         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13744         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13745         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
13746                 skip "Need MDS version at least 2.2.51"
13747         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13748
13749         cp /etc/hosts $DIR/$tfile
13750
13751         fid=$($LFS path2fid $DIR/$tfile)
13752         rc=$?
13753         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
13754
13755         dot_lustre_fid_permission_check "$fid" $DIR ||
13756                 error "dot lustre permission check $fid failed"
13757
13758         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
13759
13760         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
13761
13762         touch $MOUNT/.lustre/file &&
13763                 error "creation is not allowed under .lustre"
13764
13765         mkdir $MOUNT/.lustre/dir &&
13766                 error "mkdir is not allowed under .lustre"
13767
13768         rm -rf $DIR/$tfile
13769 }
13770 run_test 154a "Open-by-FID"
13771
13772 test_154b() {
13773         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13774         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13775         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13776         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
13777                 skip "Need MDS version at least 2.2.51"
13778
13779         local remote_dir=$DIR/$tdir/remote_dir
13780         local MDTIDX=1
13781         local rc=0
13782
13783         mkdir -p $DIR/$tdir
13784         $LFS mkdir -i $MDTIDX $remote_dir ||
13785                 error "create remote directory failed"
13786
13787         cp /etc/hosts $remote_dir/$tfile
13788
13789         fid=$($LFS path2fid $remote_dir/$tfile)
13790         rc=$?
13791         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
13792
13793         dot_lustre_fid_permission_check "$fid" $remote_dir ||
13794                 error "dot lustre permission check $fid failed"
13795         rm -rf $DIR/$tdir
13796 }
13797 run_test 154b "Open-by-FID for remote directory"
13798
13799 test_154c() {
13800         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13801                 skip "Need MDS version at least 2.4.1"
13802
13803         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
13804         local FID1=$($LFS path2fid $DIR/$tfile.1)
13805         local FID2=$($LFS path2fid $DIR/$tfile.2)
13806         local FID3=$($LFS path2fid $DIR/$tfile.3)
13807
13808         local N=1
13809         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
13810                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
13811                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
13812                 local want=FID$N
13813                 [ "$FID" = "${!want}" ] ||
13814                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
13815                 N=$((N + 1))
13816         done
13817
13818         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
13819         do
13820                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
13821                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
13822                 N=$((N + 1))
13823         done
13824 }
13825 run_test 154c "lfs path2fid and fid2path multiple arguments"
13826
13827 test_154d() {
13828         remote_mds_nodsh && skip "remote MDS with nodsh"
13829         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
13830                 skip "Need MDS version at least 2.5.53"
13831
13832         if remote_mds; then
13833                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
13834         else
13835                 nid="0@lo"
13836         fi
13837         local proc_ofile="mdt.*.exports.'$nid'.open_files"
13838         local fd
13839         local cmd
13840
13841         rm -f $DIR/$tfile
13842         touch $DIR/$tfile
13843
13844         local fid=$($LFS path2fid $DIR/$tfile)
13845         # Open the file
13846         fd=$(free_fd)
13847         cmd="exec $fd<$DIR/$tfile"
13848         eval $cmd
13849         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
13850         echo "$fid_list" | grep "$fid"
13851         rc=$?
13852
13853         cmd="exec $fd>/dev/null"
13854         eval $cmd
13855         if [ $rc -ne 0 ]; then
13856                 error "FID $fid not found in open files list $fid_list"
13857         fi
13858 }
13859 run_test 154d "Verify open file fid"
13860
13861 test_154e()
13862 {
13863         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
13864                 skip "Need MDS version at least 2.6.50"
13865
13866         if ls -a $MOUNT | grep -q '^\.lustre$'; then
13867                 error ".lustre returned by readdir"
13868         fi
13869 }
13870 run_test 154e ".lustre is not returned by readdir"
13871
13872 test_154f() {
13873         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13874
13875         # create parent directory on a single MDT to avoid cross-MDT hardlinks
13876         test_mkdir -p -c1 $DIR/$tdir/d
13877         # test dirs inherit from its stripe
13878         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
13879         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
13880         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
13881         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
13882         touch $DIR/f
13883
13884         # get fid of parents
13885         local FID0=$($LFS path2fid $DIR/$tdir/d)
13886         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
13887         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
13888         local FID3=$($LFS path2fid $DIR)
13889
13890         # check that path2fid --parents returns expected <parent_fid>/name
13891         # 1) test for a directory (single parent)
13892         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
13893         [ "$parent" == "$FID0/foo1" ] ||
13894                 error "expected parent: $FID0/foo1, got: $parent"
13895
13896         # 2) test for a file with nlink > 1 (multiple parents)
13897         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
13898         echo "$parent" | grep -F "$FID1/$tfile" ||
13899                 error "$FID1/$tfile not returned in parent list"
13900         echo "$parent" | grep -F "$FID2/link" ||
13901                 error "$FID2/link not returned in parent list"
13902
13903         # 3) get parent by fid
13904         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
13905         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13906         echo "$parent" | grep -F "$FID1/$tfile" ||
13907                 error "$FID1/$tfile not returned in parent list (by fid)"
13908         echo "$parent" | grep -F "$FID2/link" ||
13909                 error "$FID2/link not returned in parent list (by fid)"
13910
13911         # 4) test for entry in root directory
13912         parent=$($LFS path2fid --parents $DIR/f)
13913         echo "$parent" | grep -F "$FID3/f" ||
13914                 error "$FID3/f not returned in parent list"
13915
13916         # 5) test it on root directory
13917         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
13918                 error "$MOUNT should not have parents"
13919
13920         # enable xattr caching and check that linkea is correctly updated
13921         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
13922         save_lustre_params client "llite.*.xattr_cache" > $save
13923         lctl set_param llite.*.xattr_cache 1
13924
13925         # 6.1) linkea update on rename
13926         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
13927
13928         # get parents by fid
13929         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13930         # foo1 should no longer be returned in parent list
13931         echo "$parent" | grep -F "$FID1" &&
13932                 error "$FID1 should no longer be in parent list"
13933         # the new path should appear
13934         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
13935                 error "$FID2/$tfile.moved is not in parent list"
13936
13937         # 6.2) linkea update on unlink
13938         rm -f $DIR/$tdir/d/foo2/link
13939         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13940         # foo2/link should no longer be returned in parent list
13941         echo "$parent" | grep -F "$FID2/link" &&
13942                 error "$FID2/link should no longer be in parent list"
13943         true
13944
13945         rm -f $DIR/f
13946         restore_lustre_params < $save
13947         rm -f $save
13948 }
13949 run_test 154f "get parent fids by reading link ea"
13950
13951 test_154g()
13952 {
13953         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13954         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
13955            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
13956                 skip "Need MDS version at least 2.6.92"
13957
13958         mkdir -p $DIR/$tdir
13959         llapi_fid_test -d $DIR/$tdir
13960 }
13961 run_test 154g "various llapi FID tests"
13962
13963 test_155_small_load() {
13964     local temp=$TMP/$tfile
13965     local file=$DIR/$tfile
13966
13967     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
13968         error "dd of=$temp bs=6096 count=1 failed"
13969     cp $temp $file
13970     cancel_lru_locks $OSC
13971     cmp $temp $file || error "$temp $file differ"
13972
13973     $TRUNCATE $temp 6000
13974     $TRUNCATE $file 6000
13975     cmp $temp $file || error "$temp $file differ (truncate1)"
13976
13977     echo "12345" >>$temp
13978     echo "12345" >>$file
13979     cmp $temp $file || error "$temp $file differ (append1)"
13980
13981     echo "12345" >>$temp
13982     echo "12345" >>$file
13983     cmp $temp $file || error "$temp $file differ (append2)"
13984
13985     rm -f $temp $file
13986     true
13987 }
13988
13989 test_155_big_load() {
13990         remote_ost_nodsh && skip "remote OST with nodsh"
13991
13992         local temp=$TMP/$tfile
13993         local file=$DIR/$tfile
13994
13995         free_min_max
13996         local cache_size=$(do_facet ost$((MAXI+1)) \
13997                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
13998         local large_file_size=$((cache_size * 2))
13999
14000         echo "OSS cache size: $cache_size KB"
14001         echo "Large file size: $large_file_size KB"
14002
14003         [ $MAXV -le $large_file_size ] &&
14004                 skip_env "max available OST size needs > $large_file_size KB"
14005
14006         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
14007
14008         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
14009                 error "dd of=$temp bs=$large_file_size count=1k failed"
14010         cp $temp $file
14011         ls -lh $temp $file
14012         cancel_lru_locks osc
14013         cmp $temp $file || error "$temp $file differ"
14014
14015         rm -f $temp $file
14016         true
14017 }
14018
14019 save_writethrough() {
14020         local facets=$(get_facets OST)
14021
14022         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
14023 }
14024
14025 test_155a() {
14026         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14027
14028         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14029
14030         save_writethrough $p
14031
14032         set_cache read on
14033         set_cache writethrough on
14034         test_155_small_load
14035         restore_lustre_params < $p
14036         rm -f $p
14037 }
14038 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
14039
14040 test_155b() {
14041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14042
14043         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14044
14045         save_writethrough $p
14046
14047         set_cache read on
14048         set_cache writethrough off
14049         test_155_small_load
14050         restore_lustre_params < $p
14051         rm -f $p
14052 }
14053 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
14054
14055 test_155c() {
14056         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14057
14058         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14059
14060         save_writethrough $p
14061
14062         set_cache read off
14063         set_cache writethrough on
14064         test_155_small_load
14065         restore_lustre_params < $p
14066         rm -f $p
14067 }
14068 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
14069
14070 test_155d() {
14071         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14072
14073         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14074
14075         save_writethrough $p
14076
14077         set_cache read off
14078         set_cache writethrough off
14079         test_155_small_load
14080         restore_lustre_params < $p
14081         rm -f $p
14082 }
14083 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
14084
14085 test_155e() {
14086         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14087
14088         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14089
14090         save_writethrough $p
14091
14092         set_cache read on
14093         set_cache writethrough on
14094         test_155_big_load
14095         restore_lustre_params < $p
14096         rm -f $p
14097 }
14098 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
14099
14100 test_155f() {
14101         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14102
14103         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14104
14105         save_writethrough $p
14106
14107         set_cache read on
14108         set_cache writethrough off
14109         test_155_big_load
14110         restore_lustre_params < $p
14111         rm -f $p
14112 }
14113 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
14114
14115 test_155g() {
14116         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14117
14118         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14119
14120         save_writethrough $p
14121
14122         set_cache read off
14123         set_cache writethrough on
14124         test_155_big_load
14125         restore_lustre_params < $p
14126         rm -f $p
14127 }
14128 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
14129
14130 test_155h() {
14131         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14132
14133         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14134
14135         save_writethrough $p
14136
14137         set_cache read off
14138         set_cache writethrough off
14139         test_155_big_load
14140         restore_lustre_params < $p
14141         rm -f $p
14142 }
14143 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
14144
14145 test_156() {
14146         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14147         remote_ost_nodsh && skip "remote OST with nodsh"
14148         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
14149                 skip "stats not implemented on old servers"
14150         [ "$ost1_FSTYPE" = "zfs" ] &&
14151                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
14152
14153         local CPAGES=3
14154         local BEFORE
14155         local AFTER
14156         local file="$DIR/$tfile"
14157         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14158
14159         save_writethrough $p
14160         roc_hit_init
14161
14162         log "Turn on read and write cache"
14163         set_cache read on
14164         set_cache writethrough on
14165
14166         log "Write data and read it back."
14167         log "Read should be satisfied from the cache."
14168         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14169         BEFORE=$(roc_hit)
14170         cancel_lru_locks osc
14171         cat $file >/dev/null
14172         AFTER=$(roc_hit)
14173         if ! let "AFTER - BEFORE == CPAGES"; then
14174                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
14175         else
14176                 log "cache hits: before: $BEFORE, after: $AFTER"
14177         fi
14178
14179         log "Read again; it should be satisfied from the cache."
14180         BEFORE=$AFTER
14181         cancel_lru_locks osc
14182         cat $file >/dev/null
14183         AFTER=$(roc_hit)
14184         if ! let "AFTER - BEFORE == CPAGES"; then
14185                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
14186         else
14187                 log "cache hits:: before: $BEFORE, after: $AFTER"
14188         fi
14189
14190         log "Turn off the read cache and turn on the write cache"
14191         set_cache read off
14192         set_cache writethrough on
14193
14194         log "Read again; it should be satisfied from the cache."
14195         BEFORE=$(roc_hit)
14196         cancel_lru_locks osc
14197         cat $file >/dev/null
14198         AFTER=$(roc_hit)
14199         if ! let "AFTER - BEFORE == CPAGES"; then
14200                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
14201         else
14202                 log "cache hits:: before: $BEFORE, after: $AFTER"
14203         fi
14204
14205         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14206                 # > 2.12.56 uses pagecache if cached
14207                 log "Read again; it should not be satisfied from the cache."
14208                 BEFORE=$AFTER
14209                 cancel_lru_locks osc
14210                 cat $file >/dev/null
14211                 AFTER=$(roc_hit)
14212                 if ! let "AFTER - BEFORE == 0"; then
14213                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
14214                 else
14215                         log "cache hits:: before: $BEFORE, after: $AFTER"
14216                 fi
14217         fi
14218
14219         log "Write data and read it back."
14220         log "Read should be satisfied from the cache."
14221         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14222         BEFORE=$(roc_hit)
14223         cancel_lru_locks osc
14224         cat $file >/dev/null
14225         AFTER=$(roc_hit)
14226         if ! let "AFTER - BEFORE == CPAGES"; then
14227                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
14228         else
14229                 log "cache hits:: before: $BEFORE, after: $AFTER"
14230         fi
14231
14232         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14233                 # > 2.12.56 uses pagecache if cached
14234                 log "Read again; it should not be satisfied from the cache."
14235                 BEFORE=$AFTER
14236                 cancel_lru_locks osc
14237                 cat $file >/dev/null
14238                 AFTER=$(roc_hit)
14239                 if ! let "AFTER - BEFORE == 0"; then
14240                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
14241                 else
14242                         log "cache hits:: before: $BEFORE, after: $AFTER"
14243                 fi
14244         fi
14245
14246         log "Turn off read and write cache"
14247         set_cache read off
14248         set_cache writethrough off
14249
14250         log "Write data and read it back"
14251         log "It should not be satisfied from the cache."
14252         rm -f $file
14253         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14254         cancel_lru_locks osc
14255         BEFORE=$(roc_hit)
14256         cat $file >/dev/null
14257         AFTER=$(roc_hit)
14258         if ! let "AFTER - BEFORE == 0"; then
14259                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
14260         else
14261                 log "cache hits:: before: $BEFORE, after: $AFTER"
14262         fi
14263
14264         log "Turn on the read cache and turn off the write cache"
14265         set_cache read on
14266         set_cache writethrough off
14267
14268         log "Write data and read it back"
14269         log "It should not be satisfied from the cache."
14270         rm -f $file
14271         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14272         BEFORE=$(roc_hit)
14273         cancel_lru_locks osc
14274         cat $file >/dev/null
14275         AFTER=$(roc_hit)
14276         if ! let "AFTER - BEFORE == 0"; then
14277                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
14278         else
14279                 log "cache hits:: before: $BEFORE, after: $AFTER"
14280         fi
14281
14282         log "Read again; it should be satisfied from the cache."
14283         BEFORE=$(roc_hit)
14284         cancel_lru_locks osc
14285         cat $file >/dev/null
14286         AFTER=$(roc_hit)
14287         if ! let "AFTER - BEFORE == CPAGES"; then
14288                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
14289         else
14290                 log "cache hits:: before: $BEFORE, after: $AFTER"
14291         fi
14292
14293         restore_lustre_params < $p
14294         rm -f $p $file
14295 }
14296 run_test 156 "Verification of tunables"
14297
14298 test_160a() {
14299         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14300         remote_mds_nodsh && skip "remote MDS with nodsh"
14301         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14302                 skip "Need MDS version at least 2.2.0"
14303
14304         changelog_register || error "changelog_register failed"
14305         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14306         changelog_users $SINGLEMDS | grep -q $cl_user ||
14307                 error "User $cl_user not found in changelog_users"
14308
14309         # change something
14310         test_mkdir -p $DIR/$tdir/pics/2008/zachy
14311         changelog_clear 0 || error "changelog_clear failed"
14312         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
14313         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
14314         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
14315         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
14316         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
14317         rm $DIR/$tdir/pics/desktop.jpg
14318
14319         changelog_dump | tail -10
14320
14321         echo "verifying changelog mask"
14322         changelog_chmask "-MKDIR"
14323         changelog_chmask "-CLOSE"
14324
14325         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
14326         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
14327
14328         changelog_chmask "+MKDIR"
14329         changelog_chmask "+CLOSE"
14330
14331         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
14332         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
14333
14334         changelog_dump | tail -10
14335         MKDIRS=$(changelog_dump | grep -c "MKDIR")
14336         CLOSES=$(changelog_dump | grep -c "CLOSE")
14337         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
14338         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
14339
14340         # verify contents
14341         echo "verifying target fid"
14342         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
14343         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
14344         [ "$fidc" == "$fidf" ] ||
14345                 error "changelog '$tfile' fid $fidc != file fid $fidf"
14346         echo "verifying parent fid"
14347         # The FID returned from the Changelog may be the directory shard on
14348         # a different MDT, and not the FID returned by path2fid on the parent.
14349         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
14350         # since this is what will matter when recreating this file in the tree.
14351         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
14352         local pathp=$($LFS fid2path $MOUNT "$fidp")
14353         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
14354                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
14355
14356         echo "getting records for $cl_user"
14357         changelog_users $SINGLEMDS
14358         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
14359         local nclr=3
14360         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
14361                 error "changelog_clear failed"
14362         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
14363         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
14364         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
14365                 error "user index expect $user_rec1 + $nclr != $user_rec2"
14366
14367         local min0_rec=$(changelog_users $SINGLEMDS |
14368                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
14369         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
14370                           awk '{ print $1; exit; }')
14371
14372         changelog_dump | tail -n 5
14373         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
14374         [ $first_rec == $((min0_rec + 1)) ] ||
14375                 error "first index should be $min0_rec + 1 not $first_rec"
14376
14377         # LU-3446 changelog index reset on MDT restart
14378         local cur_rec1=$(changelog_users $SINGLEMDS |
14379                          awk '/^current.index:/ { print $NF }')
14380         changelog_clear 0 ||
14381                 error "clear all changelog records for $cl_user failed"
14382         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
14383         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
14384                 error "Fail to start $SINGLEMDS"
14385         local cur_rec2=$(changelog_users $SINGLEMDS |
14386                          awk '/^current.index:/ { print $NF }')
14387         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
14388         [ $cur_rec1 == $cur_rec2 ] ||
14389                 error "current index should be $cur_rec1 not $cur_rec2"
14390
14391         echo "verifying users from this test are deregistered"
14392         changelog_deregister || error "changelog_deregister failed"
14393         changelog_users $SINGLEMDS | grep -q $cl_user &&
14394                 error "User '$cl_user' still in changelog_users"
14395
14396         # lctl get_param -n mdd.*.changelog_users
14397         # current index: 144
14398         # ID    index (idle seconds)
14399         # cl3   144 (2)
14400         if ! changelog_users $SINGLEMDS | grep "^cl"; then
14401                 # this is the normal case where all users were deregistered
14402                 # make sure no new records are added when no users are present
14403                 local last_rec1=$(changelog_users $SINGLEMDS |
14404                                   awk '/^current.index:/ { print $NF }')
14405                 touch $DIR/$tdir/chloe
14406                 local last_rec2=$(changelog_users $SINGLEMDS |
14407                                   awk '/^current.index:/ { print $NF }')
14408                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
14409                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
14410         else
14411                 # any changelog users must be leftovers from a previous test
14412                 changelog_users $SINGLEMDS
14413                 echo "other changelog users; can't verify off"
14414         fi
14415 }
14416 run_test 160a "changelog sanity"
14417
14418 test_160b() { # LU-3587
14419         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14420         remote_mds_nodsh && skip "remote MDS with nodsh"
14421         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14422                 skip "Need MDS version at least 2.2.0"
14423
14424         changelog_register || error "changelog_register failed"
14425         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14426         changelog_users $SINGLEMDS | grep -q $cl_user ||
14427                 error "User '$cl_user' not found in changelog_users"
14428
14429         local longname1=$(str_repeat a 255)
14430         local longname2=$(str_repeat b 255)
14431
14432         cd $DIR
14433         echo "creating very long named file"
14434         touch $longname1 || error "create of '$longname1' failed"
14435         echo "renaming very long named file"
14436         mv $longname1 $longname2
14437
14438         changelog_dump | grep RENME | tail -n 5
14439         rm -f $longname2
14440 }
14441 run_test 160b "Verify that very long rename doesn't crash in changelog"
14442
14443 test_160c() {
14444         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14445         remote_mds_nodsh && skip "remote MDS with nodsh"
14446
14447         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
14448                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
14449                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
14450                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
14451
14452         local rc=0
14453
14454         # Registration step
14455         changelog_register || error "changelog_register failed"
14456
14457         rm -rf $DIR/$tdir
14458         mkdir -p $DIR/$tdir
14459         $MCREATE $DIR/$tdir/foo_160c
14460         changelog_chmask "-TRUNC"
14461         $TRUNCATE $DIR/$tdir/foo_160c 200
14462         changelog_chmask "+TRUNC"
14463         $TRUNCATE $DIR/$tdir/foo_160c 199
14464         changelog_dump | tail -n 5
14465         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
14466         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
14467 }
14468 run_test 160c "verify that changelog log catch the truncate event"
14469
14470 test_160d() {
14471         remote_mds_nodsh && skip "remote MDS with nodsh"
14472         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14473         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14474         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
14475                 skip "Need MDS version at least 2.7.60"
14476
14477         # Registration step
14478         changelog_register || error "changelog_register failed"
14479
14480         mkdir -p $DIR/$tdir/migrate_dir
14481         changelog_clear 0 || error "changelog_clear failed"
14482
14483         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
14484         changelog_dump | tail -n 5
14485         local migrates=$(changelog_dump | grep -c "MIGRT")
14486         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
14487 }
14488 run_test 160d "verify that changelog log catch the migrate event"
14489
14490 test_160e() {
14491         remote_mds_nodsh && skip "remote MDS with nodsh"
14492
14493         # Create a user
14494         changelog_register || error "changelog_register failed"
14495
14496         # Delete a future user (expect fail)
14497         local MDT0=$(facet_svc $SINGLEMDS)
14498         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
14499         local rc=$?
14500
14501         if [ $rc -eq 0 ]; then
14502                 error "Deleted non-existant user cl77"
14503         elif [ $rc -ne 2 ]; then
14504                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
14505         fi
14506
14507         # Clear to a bad index (1 billion should be safe)
14508         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
14509         rc=$?
14510
14511         if [ $rc -eq 0 ]; then
14512                 error "Successfully cleared to invalid CL index"
14513         elif [ $rc -ne 22 ]; then
14514                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
14515         fi
14516 }
14517 run_test 160e "changelog negative testing (should return errors)"
14518
14519 test_160f() {
14520         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14521         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14522                 skip "Need MDS version at least 2.10.56"
14523
14524         local mdts=$(comma_list $(mdts_nodes))
14525
14526         # Create a user
14527         changelog_register || error "first changelog_register failed"
14528         changelog_register || error "second changelog_register failed"
14529         local cl_users
14530         declare -A cl_user1
14531         declare -A cl_user2
14532         local user_rec1
14533         local user_rec2
14534         local i
14535
14536         # generate some changelog records to accumulate on each MDT
14537         # use fnv1a because created files should be evenly distributed
14538         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14539                 error "test_mkdir $tdir failed"
14540         log "$(date +%s): creating first files"
14541         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14542                 error "create $DIR/$tdir/$tfile failed"
14543
14544         # check changelogs have been generated
14545         local start=$SECONDS
14546         local idle_time=$((MDSCOUNT * 5 + 5))
14547         local nbcl=$(changelog_dump | wc -l)
14548         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14549
14550         for param in "changelog_max_idle_time=$idle_time" \
14551                      "changelog_gc=1" \
14552                      "changelog_min_gc_interval=2" \
14553                      "changelog_min_free_cat_entries=3"; do
14554                 local MDT0=$(facet_svc $SINGLEMDS)
14555                 local var="${param%=*}"
14556                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14557
14558                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14559                 do_nodes $mdts $LCTL set_param mdd.*.$param
14560         done
14561
14562         # force cl_user2 to be idle (1st part), but also cancel the
14563         # cl_user1 records so that it is not evicted later in the test.
14564         local sleep1=$((idle_time / 2))
14565         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
14566         sleep $sleep1
14567
14568         # simulate changelog catalog almost full
14569         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
14570         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
14571
14572         for i in $(seq $MDSCOUNT); do
14573                 cl_users=(${CL_USERS[mds$i]})
14574                 cl_user1[mds$i]="${cl_users[0]}"
14575                 cl_user2[mds$i]="${cl_users[1]}"
14576
14577                 [ -n "${cl_user1[mds$i]}" ] ||
14578                         error "mds$i: no user registered"
14579                 [ -n "${cl_user2[mds$i]}" ] ||
14580                         error "mds$i: only ${cl_user2[mds$i]} is registered"
14581
14582                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14583                 [ -n "$user_rec1" ] ||
14584                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14585                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14586                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14587                 [ -n "$user_rec2" ] ||
14588                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14589                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14590                      "$user_rec1 + 2 == $user_rec2"
14591                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14592                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14593                               "$user_rec1 + 2, but is $user_rec2"
14594                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14595                 [ -n "$user_rec2" ] ||
14596                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14597                 [ $user_rec1 == $user_rec2 ] ||
14598                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14599                               "$user_rec1, but is $user_rec2"
14600         done
14601
14602         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
14603         local sleep2=$((idle_time - (SECONDS - start) + 1))
14604         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
14605         sleep $sleep2
14606
14607         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
14608         # cl_user1 should be OK because it recently processed records.
14609         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
14610         createmany -m $DIR/$tdir/${tfile}b $((MDSCOUNT * 2)) ||
14611                 error "create $DIR/$tdir/${tfile}b failed"
14612
14613         # ensure gc thread is done
14614         for i in $(mdts_nodes); do
14615                 wait_update $i \
14616                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
14617                         error "$i: GC-thread not done"
14618         done
14619
14620         local first_rec
14621         for i in $(seq $MDSCOUNT); do
14622                 # check cl_user1 still registered
14623                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14624                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14625                 # check cl_user2 unregistered
14626                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14627                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14628
14629                 # check changelogs are present and starting at $user_rec1 + 1
14630                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14631                 [ -n "$user_rec1" ] ||
14632                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14633                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14634                             awk '{ print $1; exit; }')
14635
14636                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14637                 [ $((user_rec1 + 1)) == $first_rec ] ||
14638                         error "mds$i: first index should be $user_rec1 + 1, " \
14639                               "but is $first_rec"
14640         done
14641 }
14642 run_test 160f "changelog garbage collect (timestamped users)"
14643
14644 test_160g() {
14645         remote_mds_nodsh && skip "remote MDS with nodsh"
14646         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14647                 skip "Need MDS version at least 2.10.56"
14648
14649         local mdts=$(comma_list $(mdts_nodes))
14650
14651         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
14652         do_nodes $mdts $LCTL set_param fail_loc=0x1314
14653
14654         # Create a user
14655         changelog_register || error "first changelog_register failed"
14656         changelog_register || error "second changelog_register failed"
14657         local cl_users
14658         declare -A cl_user1
14659         declare -A cl_user2
14660         local user_rec1
14661         local user_rec2
14662         local i
14663
14664         # generate some changelog records to accumulate on each MDT
14665         # use fnv1a because created files should be evenly distributed
14666         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14667                 error "mkdir $tdir failed"
14668         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14669                 error "create $DIR/$tdir/$tfile failed"
14670
14671         # check changelogs have been generated
14672         local nbcl=$(changelog_dump | wc -l)
14673         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14674
14675         # reduce the max_idle_indexes value to make sure we exceed it
14676         max_ndx=$((nbcl / 2 - 1))
14677
14678         for param in "changelog_max_idle_indexes=$max_ndx" \
14679                      "changelog_gc=1" \
14680                      "changelog_min_gc_interval=2" \
14681                      "changelog_min_free_cat_entries=3"; do
14682                 local MDT0=$(facet_svc $SINGLEMDS)
14683                 local var="${param%=*}"
14684                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14685
14686                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14687                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
14688                         error "unable to set mdd.*.$param"
14689         done
14690
14691         # simulate changelog catalog almost full
14692         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
14693         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
14694
14695         for i in $(seq $MDSCOUNT); do
14696                 cl_users=(${CL_USERS[mds$i]})
14697                 cl_user1[mds$i]="${cl_users[0]}"
14698                 cl_user2[mds$i]="${cl_users[1]}"
14699
14700                 [ -n "${cl_user1[mds$i]}" ] ||
14701                         error "mds$i: no user registered"
14702                 [ -n "${cl_user2[mds$i]}" ] ||
14703                         error "mds$i: only ${cl_user1[mds$i]} is registered"
14704
14705                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14706                 [ -n "$user_rec1" ] ||
14707                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14708                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14709                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14710                 [ -n "$user_rec2" ] ||
14711                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14712                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14713                      "$user_rec1 + 2 == $user_rec2"
14714                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14715                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14716                               "$user_rec1 + 2, but is $user_rec2"
14717                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14718                 [ -n "$user_rec2" ] ||
14719                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14720                 [ $user_rec1 == $user_rec2 ] ||
14721                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14722                               "$user_rec1, but is $user_rec2"
14723         done
14724
14725         # ensure we are past the previous changelog_min_gc_interval set above
14726         sleep 2
14727
14728         # generate one more changelog to trigger fail_loc
14729         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14730                 error "create $DIR/$tdir/${tfile}bis failed"
14731
14732         # ensure gc thread is done
14733         for i in $(mdts_nodes); do
14734                 wait_update $i \
14735                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
14736                         error "$i: GC-thread not done"
14737         done
14738
14739         local first_rec
14740         for i in $(seq $MDSCOUNT); do
14741                 # check cl_user1 still registered
14742                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14743                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14744                 # check cl_user2 unregistered
14745                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14746                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14747
14748                 # check changelogs are present and starting at $user_rec1 + 1
14749                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14750                 [ -n "$user_rec1" ] ||
14751                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14752                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14753                             awk '{ print $1; exit; }')
14754
14755                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14756                 [ $((user_rec1 + 1)) == $first_rec ] ||
14757                         error "mds$i: first index should be $user_rec1 + 1, " \
14758                               "but is $first_rec"
14759         done
14760 }
14761 run_test 160g "changelog garbage collect (old users)"
14762
14763 test_160h() {
14764         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14765         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14766                 skip "Need MDS version at least 2.10.56"
14767
14768         local mdts=$(comma_list $(mdts_nodes))
14769
14770         # Create a user
14771         changelog_register || error "first changelog_register failed"
14772         changelog_register || error "second changelog_register failed"
14773         local cl_users
14774         declare -A cl_user1
14775         declare -A cl_user2
14776         local user_rec1
14777         local user_rec2
14778         local i
14779
14780         # generate some changelog records to accumulate on each MDT
14781         # use fnv1a because created files should be evenly distributed
14782         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14783                 error "test_mkdir $tdir failed"
14784         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14785                 error "create $DIR/$tdir/$tfile failed"
14786
14787         # check changelogs have been generated
14788         local nbcl=$(changelog_dump | wc -l)
14789         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14790
14791         for param in "changelog_max_idle_time=10" \
14792                      "changelog_gc=1" \
14793                      "changelog_min_gc_interval=2"; do
14794                 local MDT0=$(facet_svc $SINGLEMDS)
14795                 local var="${param%=*}"
14796                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14797
14798                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14799                 do_nodes $mdts $LCTL set_param mdd.*.$param
14800         done
14801
14802         # force cl_user2 to be idle (1st part)
14803         sleep 9
14804
14805         for i in $(seq $MDSCOUNT); do
14806                 cl_users=(${CL_USERS[mds$i]})
14807                 cl_user1[mds$i]="${cl_users[0]}"
14808                 cl_user2[mds$i]="${cl_users[1]}"
14809
14810                 [ -n "${cl_user1[mds$i]}" ] ||
14811                         error "mds$i: no user registered"
14812                 [ -n "${cl_user2[mds$i]}" ] ||
14813                         error "mds$i: only ${cl_user2[mds$i]} is registered"
14814
14815                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14816                 [ -n "$user_rec1" ] ||
14817                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14818                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14819                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14820                 [ -n "$user_rec2" ] ||
14821                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14822                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14823                      "$user_rec1 + 2 == $user_rec2"
14824                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14825                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14826                               "$user_rec1 + 2, but is $user_rec2"
14827                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14828                 [ -n "$user_rec2" ] ||
14829                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14830                 [ $user_rec1 == $user_rec2 ] ||
14831                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14832                               "$user_rec1, but is $user_rec2"
14833         done
14834
14835         # force cl_user2 to be idle (2nd part) and to reach
14836         # changelog_max_idle_time
14837         sleep 2
14838
14839         # force each GC-thread start and block then
14840         # one per MDT/MDD, set fail_val accordingly
14841         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
14842         do_nodes $mdts $LCTL set_param fail_loc=0x1316
14843
14844         # generate more changelogs to trigger fail_loc
14845         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14846                 error "create $DIR/$tdir/${tfile}bis failed"
14847
14848         # stop MDT to stop GC-thread, should be done in back-ground as it will
14849         # block waiting for the thread to be released and exit
14850         declare -A stop_pids
14851         for i in $(seq $MDSCOUNT); do
14852                 stop mds$i &
14853                 stop_pids[mds$i]=$!
14854         done
14855
14856         for i in $(mdts_nodes); do
14857                 local facet
14858                 local nb=0
14859                 local facets=$(facets_up_on_host $i)
14860
14861                 for facet in ${facets//,/ }; do
14862                         if [[ $facet == mds* ]]; then
14863                                 nb=$((nb + 1))
14864                         fi
14865                 done
14866                 # ensure each MDS's gc threads are still present and all in "R"
14867                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
14868                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
14869                         error "$i: expected $nb GC-thread"
14870                 wait_update $i \
14871                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
14872                         "R" 20 ||
14873                         error "$i: GC-thread not found in R-state"
14874                 # check umounts of each MDT on MDS have reached kthread_stop()
14875                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
14876                         error "$i: expected $nb umount"
14877                 wait_update $i \
14878                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
14879                         error "$i: umount not found in D-state"
14880         done
14881
14882         # release all GC-threads
14883         do_nodes $mdts $LCTL set_param fail_loc=0
14884
14885         # wait for MDT stop to complete
14886         for i in $(seq $MDSCOUNT); do
14887                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
14888         done
14889
14890         # XXX
14891         # may try to check if any orphan changelog records are present
14892         # via ldiskfs/zfs and llog_reader...
14893
14894         # re-start/mount MDTs
14895         for i in $(seq $MDSCOUNT); do
14896                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
14897                         error "Fail to start mds$i"
14898         done
14899
14900         local first_rec
14901         for i in $(seq $MDSCOUNT); do
14902                 # check cl_user1 still registered
14903                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14904                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14905                 # check cl_user2 unregistered
14906                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14907                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14908
14909                 # check changelogs are present and starting at $user_rec1 + 1
14910                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14911                 [ -n "$user_rec1" ] ||
14912                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14913                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14914                             awk '{ print $1; exit; }')
14915
14916                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14917                 [ $((user_rec1 + 1)) == $first_rec ] ||
14918                         error "mds$i: first index should be $user_rec1 + 1, " \
14919                               "but is $first_rec"
14920         done
14921 }
14922 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
14923               "during mount"
14924
14925 test_160i() {
14926
14927         local mdts=$(comma_list $(mdts_nodes))
14928
14929         changelog_register || error "first changelog_register failed"
14930
14931         # generate some changelog records to accumulate on each MDT
14932         # use fnv1a because created files should be evenly distributed
14933         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14934                 error "mkdir $tdir failed"
14935         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14936                 error "create $DIR/$tdir/$tfile failed"
14937
14938         # check changelogs have been generated
14939         local nbcl=$(changelog_dump | wc -l)
14940         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14941
14942         # simulate race between register and unregister
14943         # XXX as fail_loc is set per-MDS, with DNE configs the race
14944         # simulation will only occur for one MDT per MDS and for the
14945         # others the normal race scenario will take place
14946         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
14947         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
14948         do_nodes $mdts $LCTL set_param fail_val=1
14949
14950         # unregister 1st user
14951         changelog_deregister &
14952         local pid1=$!
14953         # wait some time for deregister work to reach race rdv
14954         sleep 2
14955         # register 2nd user
14956         changelog_register || error "2nd user register failed"
14957
14958         wait $pid1 || error "1st user deregister failed"
14959
14960         local i
14961         local last_rec
14962         declare -A LAST_REC
14963         for i in $(seq $MDSCOUNT); do
14964                 if changelog_users mds$i | grep "^cl"; then
14965                         # make sure new records are added with one user present
14966                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
14967                                           awk '/^current.index:/ { print $NF }')
14968                 else
14969                         error "mds$i has no user registered"
14970                 fi
14971         done
14972
14973         # generate more changelog records to accumulate on each MDT
14974         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14975                 error "create $DIR/$tdir/${tfile}bis failed"
14976
14977         for i in $(seq $MDSCOUNT); do
14978                 last_rec=$(changelog_users $SINGLEMDS |
14979                            awk '/^current.index:/ { print $NF }')
14980                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
14981                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
14982                         error "changelogs are off on mds$i"
14983         done
14984 }
14985 run_test 160i "changelog user register/unregister race"
14986
14987 test_160j() {
14988         remote_mds_nodsh && skip "remote MDS with nodsh"
14989         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
14990                 skip "Need MDS version at least 2.12.56"
14991
14992         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
14993         stack_trap "umount $MOUNT2" EXIT
14994
14995         changelog_register || error "first changelog_register failed"
14996         stack_trap "changelog_deregister" EXIT
14997
14998         # generate some changelog
14999         # use fnv1a because created files should be evenly distributed
15000         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
15001                 error "mkdir $tdir failed"
15002         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15003                 error "create $DIR/$tdir/${tfile}bis failed"
15004
15005         # open the changelog device
15006         exec 3>/dev/changelog-$FSNAME-MDT0000
15007         stack_trap "exec 3>&-" EXIT
15008         exec 4</dev/changelog-$FSNAME-MDT0000
15009         stack_trap "exec 4<&-" EXIT
15010
15011         # umount the first lustre mount
15012         umount $MOUNT
15013         stack_trap "mount_client $MOUNT" EXIT
15014
15015         # read changelog
15016         cat <&4 >/dev/null || error "read changelog failed"
15017
15018         # clear changelog
15019         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15020         changelog_users $SINGLEMDS | grep -q $cl_user ||
15021                 error "User $cl_user not found in changelog_users"
15022
15023         printf 'clear:'$cl_user':0' >&3
15024 }
15025 run_test 160j "client can be umounted  while its chanangelog is being used"
15026
15027 test_160k() {
15028         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15029         remote_mds_nodsh && skip "remote MDS with nodsh"
15030
15031         mkdir -p $DIR/$tdir/1/1
15032
15033         changelog_register || error "changelog_register failed"
15034         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15035
15036         changelog_users $SINGLEMDS | grep -q $cl_user ||
15037                 error "User '$cl_user' not found in changelog_users"
15038 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
15039         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
15040         rmdir $DIR/$tdir/1/1 & sleep 1
15041         mkdir $DIR/$tdir/2
15042         touch $DIR/$tdir/2/2
15043         rm -rf $DIR/$tdir/2
15044
15045         wait
15046         sleep 4
15047
15048         changelog_dump | grep rmdir || error "rmdir not recorded"
15049
15050         rm -rf $DIR/$tdir
15051         changelog_deregister
15052 }
15053 run_test 160k "Verify that changelog records are not lost"
15054
15055 # Verifies that a file passed as a parameter has recently had an operation
15056 # performed on it that has generated an MTIME changelog which contains the
15057 # correct parent FID. As files might reside on a different MDT from the
15058 # parent directory in DNE configurations, the FIDs are translated to paths
15059 # before being compared, which should be identical
15060 compare_mtime_changelog() {
15061         local file="${1}"
15062         local mdtidx
15063         local mtime
15064         local cl_fid
15065         local pdir
15066         local dir
15067
15068         mdtidx=$($LFS getstripe --mdt-index $file)
15069         mdtidx=$(printf "%04x" $mdtidx)
15070
15071         # Obtain the parent FID from the MTIME changelog
15072         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
15073         [ -z "$mtime" ] && error "MTIME changelog not recorded"
15074
15075         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
15076         [ -z "$cl_fid" ] && error "parent FID not present"
15077
15078         # Verify that the path for the parent FID is the same as the path for
15079         # the test directory
15080         pdir=$($LFS fid2path $MOUNT "$cl_fid")
15081
15082         dir=$(dirname $1)
15083
15084         [[ "${pdir%/}" == "$dir" ]] ||
15085                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
15086 }
15087
15088 test_160l() {
15089         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15090
15091         remote_mds_nodsh && skip "remote MDS with nodsh"
15092         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
15093                 skip "Need MDS version at least 2.13.55"
15094
15095         local cl_user
15096
15097         changelog_register || error "changelog_register failed"
15098         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15099
15100         changelog_users $SINGLEMDS | grep -q $cl_user ||
15101                 error "User '$cl_user' not found in changelog_users"
15102
15103         # Clear some types so that MTIME changelogs are generated
15104         changelog_chmask "-CREAT"
15105         changelog_chmask "-CLOSE"
15106
15107         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
15108
15109         # Test CL_MTIME during setattr
15110         touch $DIR/$tdir/$tfile
15111         compare_mtime_changelog $DIR/$tdir/$tfile
15112
15113         # Test CL_MTIME during close
15114         dd if=/dev/urandom of=$DIR/$tdir/${tfile}_2 bs=1M count=64 ||
15115                 error "cannot create file $DIR/$tdir/${tfile}_2"
15116         compare_mtime_changelog $DIR/$tdir/${tfile}_2
15117 }
15118 run_test 160l "Verify that MTIME changelog records contain the parent FID"
15119
15120 test_161a() {
15121         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15122
15123         test_mkdir -c1 $DIR/$tdir
15124         cp /etc/hosts $DIR/$tdir/$tfile
15125         test_mkdir -c1 $DIR/$tdir/foo1
15126         test_mkdir -c1 $DIR/$tdir/foo2
15127         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
15128         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
15129         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
15130         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
15131         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
15132         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15133                 $LFS fid2path $DIR $FID
15134                 error "bad link ea"
15135         fi
15136         # middle
15137         rm $DIR/$tdir/foo2/zachary
15138         # last
15139         rm $DIR/$tdir/foo2/thor
15140         # first
15141         rm $DIR/$tdir/$tfile
15142         # rename
15143         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
15144         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
15145                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
15146         rm $DIR/$tdir/foo2/maggie
15147
15148         # overflow the EA
15149         local longname=$tfile.avg_len_is_thirty_two_
15150         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
15151                 error_noexit 'failed to unlink many hardlinks'" EXIT
15152         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
15153                 error "failed to hardlink many files"
15154         links=$($LFS fid2path $DIR $FID | wc -l)
15155         echo -n "${links}/1000 links in link EA"
15156         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
15157 }
15158 run_test 161a "link ea sanity"
15159
15160 test_161b() {
15161         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15162         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
15163
15164         local MDTIDX=1
15165         local remote_dir=$DIR/$tdir/remote_dir
15166
15167         mkdir -p $DIR/$tdir
15168         $LFS mkdir -i $MDTIDX $remote_dir ||
15169                 error "create remote directory failed"
15170
15171         cp /etc/hosts $remote_dir/$tfile
15172         mkdir -p $remote_dir/foo1
15173         mkdir -p $remote_dir/foo2
15174         ln $remote_dir/$tfile $remote_dir/foo1/sofia
15175         ln $remote_dir/$tfile $remote_dir/foo2/zachary
15176         ln $remote_dir/$tfile $remote_dir/foo1/luna
15177         ln $remote_dir/$tfile $remote_dir/foo2/thor
15178
15179         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
15180                      tr -d ']')
15181         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15182                 $LFS fid2path $DIR $FID
15183                 error "bad link ea"
15184         fi
15185         # middle
15186         rm $remote_dir/foo2/zachary
15187         # last
15188         rm $remote_dir/foo2/thor
15189         # first
15190         rm $remote_dir/$tfile
15191         # rename
15192         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
15193         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
15194         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
15195                 $LFS fid2path $DIR $FID
15196                 error "bad link rename"
15197         fi
15198         rm $remote_dir/foo2/maggie
15199
15200         # overflow the EA
15201         local longname=filename_avg_len_is_thirty_two_
15202         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
15203                 error "failed to hardlink many files"
15204         links=$($LFS fid2path $DIR $FID | wc -l)
15205         echo -n "${links}/1000 links in link EA"
15206         [[ ${links} -gt 60 ]] ||
15207                 error "expected at least 60 links in link EA"
15208         unlinkmany $remote_dir/foo2/$longname 1000 ||
15209         error "failed to unlink many hardlinks"
15210 }
15211 run_test 161b "link ea sanity under remote directory"
15212
15213 test_161c() {
15214         remote_mds_nodsh && skip "remote MDS with nodsh"
15215         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15216         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
15217                 skip "Need MDS version at least 2.1.5"
15218
15219         # define CLF_RENAME_LAST 0x0001
15220         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
15221         changelog_register || error "changelog_register failed"
15222
15223         rm -rf $DIR/$tdir
15224         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
15225         touch $DIR/$tdir/foo_161c
15226         touch $DIR/$tdir/bar_161c
15227         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15228         changelog_dump | grep RENME | tail -n 5
15229         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15230         changelog_clear 0 || error "changelog_clear failed"
15231         if [ x$flags != "x0x1" ]; then
15232                 error "flag $flags is not 0x1"
15233         fi
15234
15235         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
15236         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
15237         touch $DIR/$tdir/foo_161c
15238         touch $DIR/$tdir/bar_161c
15239         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15240         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15241         changelog_dump | grep RENME | tail -n 5
15242         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15243         changelog_clear 0 || error "changelog_clear failed"
15244         if [ x$flags != "x0x0" ]; then
15245                 error "flag $flags is not 0x0"
15246         fi
15247         echo "rename overwrite a target having nlink > 1," \
15248                 "changelog record has flags of $flags"
15249
15250         # rename doesn't overwrite a target (changelog flag 0x0)
15251         touch $DIR/$tdir/foo_161c
15252         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
15253         changelog_dump | grep RENME | tail -n 5
15254         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
15255         changelog_clear 0 || error "changelog_clear failed"
15256         if [ x$flags != "x0x0" ]; then
15257                 error "flag $flags is not 0x0"
15258         fi
15259         echo "rename doesn't overwrite a target," \
15260                 "changelog record has flags of $flags"
15261
15262         # define CLF_UNLINK_LAST 0x0001
15263         # unlink a file having nlink = 1 (changelog flag 0x1)
15264         rm -f $DIR/$tdir/foo2_161c
15265         changelog_dump | grep UNLNK | tail -n 5
15266         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15267         changelog_clear 0 || error "changelog_clear failed"
15268         if [ x$flags != "x0x1" ]; then
15269                 error "flag $flags is not 0x1"
15270         fi
15271         echo "unlink a file having nlink = 1," \
15272                 "changelog record has flags of $flags"
15273
15274         # unlink a file having nlink > 1 (changelog flag 0x0)
15275         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15276         rm -f $DIR/$tdir/foobar_161c
15277         changelog_dump | grep UNLNK | tail -n 5
15278         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15279         changelog_clear 0 || error "changelog_clear failed"
15280         if [ x$flags != "x0x0" ]; then
15281                 error "flag $flags is not 0x0"
15282         fi
15283         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
15284 }
15285 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
15286
15287 test_161d() {
15288         remote_mds_nodsh && skip "remote MDS with nodsh"
15289         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
15290
15291         local pid
15292         local fid
15293
15294         changelog_register || error "changelog_register failed"
15295
15296         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
15297         # interfer with $MOUNT/.lustre/fid/ access
15298         mkdir $DIR/$tdir
15299         [[ $? -eq 0 ]] || error "mkdir failed"
15300
15301         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
15302         $LCTL set_param fail_loc=0x8000140c
15303         # 5s pause
15304         $LCTL set_param fail_val=5
15305
15306         # create file
15307         echo foofoo > $DIR/$tdir/$tfile &
15308         pid=$!
15309
15310         # wait for create to be delayed
15311         sleep 2
15312
15313         ps -p $pid
15314         [[ $? -eq 0 ]] || error "create should be blocked"
15315
15316         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
15317         stack_trap "rm -f $tempfile"
15318         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
15319         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
15320         # some delay may occur during ChangeLog publishing and file read just
15321         # above, that could allow file write to happen finally
15322         [[ -s $tempfile ]] && echo "file should be empty"
15323
15324         $LCTL set_param fail_loc=0
15325
15326         wait $pid
15327         [[ $? -eq 0 ]] || error "create failed"
15328 }
15329 run_test 161d "create with concurrent .lustre/fid access"
15330
15331 check_path() {
15332         local expected="$1"
15333         shift
15334         local fid="$2"
15335
15336         local path
15337         path=$($LFS fid2path "$@")
15338         local rc=$?
15339
15340         if [ $rc -ne 0 ]; then
15341                 error "path looked up of '$expected' failed: rc=$rc"
15342         elif [ "$path" != "$expected" ]; then
15343                 error "path looked up '$path' instead of '$expected'"
15344         else
15345                 echo "FID '$fid' resolves to path '$path' as expected"
15346         fi
15347 }
15348
15349 test_162a() { # was test_162
15350         test_mkdir -p -c1 $DIR/$tdir/d2
15351         touch $DIR/$tdir/d2/$tfile
15352         touch $DIR/$tdir/d2/x1
15353         touch $DIR/$tdir/d2/x2
15354         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
15355         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
15356         # regular file
15357         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
15358         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
15359
15360         # softlink
15361         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
15362         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
15363         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
15364
15365         # softlink to wrong file
15366         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
15367         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
15368         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
15369
15370         # hardlink
15371         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
15372         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
15373         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
15374         # fid2path dir/fsname should both work
15375         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
15376         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
15377
15378         # hardlink count: check that there are 2 links
15379         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
15380         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
15381
15382         # hardlink indexing: remove the first link
15383         rm $DIR/$tdir/d2/p/q/r/hlink
15384         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
15385 }
15386 run_test 162a "path lookup sanity"
15387
15388 test_162b() {
15389         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15390         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15391
15392         mkdir $DIR/$tdir
15393         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
15394                                 error "create striped dir failed"
15395
15396         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
15397                                         tail -n 1 | awk '{print $2}')
15398         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
15399
15400         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
15401         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
15402
15403         # regular file
15404         for ((i=0;i<5;i++)); do
15405                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
15406                         error "get fid for f$i failed"
15407                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
15408
15409                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
15410                         error "get fid for d$i failed"
15411                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
15412         done
15413
15414         return 0
15415 }
15416 run_test 162b "striped directory path lookup sanity"
15417
15418 # LU-4239: Verify fid2path works with paths 100 or more directories deep
15419 test_162c() {
15420         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
15421                 skip "Need MDS version at least 2.7.51"
15422
15423         local lpath=$tdir.local
15424         local rpath=$tdir.remote
15425
15426         test_mkdir $DIR/$lpath
15427         test_mkdir $DIR/$rpath
15428
15429         for ((i = 0; i <= 101; i++)); do
15430                 lpath="$lpath/$i"
15431                 mkdir $DIR/$lpath
15432                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
15433                         error "get fid for local directory $DIR/$lpath failed"
15434                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
15435
15436                 rpath="$rpath/$i"
15437                 test_mkdir $DIR/$rpath
15438                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
15439                         error "get fid for remote directory $DIR/$rpath failed"
15440                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
15441         done
15442
15443         return 0
15444 }
15445 run_test 162c "fid2path works with paths 100 or more directories deep"
15446
15447 oalr_event_count() {
15448         local event="${1}"
15449         local trace="${2}"
15450
15451         awk -v name="${FSNAME}-OST0000" \
15452             -v event="${event}" \
15453             '$1 == "TRACE" && $2 == event && $3 == name' \
15454             "${trace}" |
15455         wc -l
15456 }
15457
15458 oalr_expect_event_count() {
15459         local event="${1}"
15460         local trace="${2}"
15461         local expect="${3}"
15462         local count
15463
15464         count=$(oalr_event_count "${event}" "${trace}")
15465         if ((count == expect)); then
15466                 return 0
15467         fi
15468
15469         error_noexit "${event} event count was '${count}', expected ${expect}"
15470         cat "${trace}" >&2
15471         exit 1
15472 }
15473
15474 cleanup_165() {
15475         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
15476         stop ost1
15477         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
15478 }
15479
15480 setup_165() {
15481         sync # Flush previous IOs so we can count log entries.
15482         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
15483         stack_trap cleanup_165 EXIT
15484 }
15485
15486 test_165a() {
15487         local trace="/tmp/${tfile}.trace"
15488         local rc
15489         local count
15490
15491         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15492         setup_165
15493         sleep 5
15494
15495         do_facet ost1 ofd_access_log_reader --list
15496         stop ost1
15497
15498         do_facet ost1 killall -TERM ofd_access_log_reader
15499         wait
15500         rc=$?
15501
15502         if ((rc != 0)); then
15503                 error "ofd_access_log_reader exited with rc = '${rc}'"
15504         fi
15505
15506         # Parse trace file for discovery events:
15507         oalr_expect_event_count alr_log_add "${trace}" 1
15508         oalr_expect_event_count alr_log_eof "${trace}" 1
15509         oalr_expect_event_count alr_log_free "${trace}" 1
15510 }
15511 run_test 165a "ofd access log discovery"
15512
15513 test_165b() {
15514         local trace="/tmp/${tfile}.trace"
15515         local file="${DIR}/${tfile}"
15516         local pfid1
15517         local pfid2
15518         local -a entry
15519         local rc
15520         local count
15521         local size
15522         local flags
15523
15524         setup_165
15525
15526         lfs setstripe -c 1 -i 0 "${file}"
15527         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15528         do_facet ost1 ofd_access_log_reader --list
15529
15530         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15531         sleep 5
15532         do_facet ost1 killall -TERM ofd_access_log_reader
15533         wait
15534         rc=$?
15535
15536         if ((rc != 0)); then
15537                 error "ofd_access_log_reader exited with rc = '${rc}'"
15538         fi
15539
15540         oalr_expect_event_count alr_log_entry "${trace}" 1
15541
15542         pfid1=$($LFS path2fid "${file}")
15543
15544         # 1     2             3   4    5     6   7    8    9     10
15545         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
15546         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
15547
15548         echo "entry = '${entry[*]}'" >&2
15549
15550         pfid2=${entry[4]}
15551         if [[ "${pfid1}" != "${pfid2}" ]]; then
15552                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
15553         fi
15554
15555         size=${entry[8]}
15556         if ((size != 1048576)); then
15557                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
15558         fi
15559
15560         flags=${entry[10]}
15561         if [[ "${flags}" != "w" ]]; then
15562                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
15563         fi
15564
15565         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15566         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c || error "cannot read '${file}'"
15567         sleep 5
15568         do_facet ost1 killall -TERM ofd_access_log_reader
15569         wait
15570         rc=$?
15571
15572         if ((rc != 0)); then
15573                 error "ofd_access_log_reader exited with rc = '${rc}'"
15574         fi
15575
15576         oalr_expect_event_count alr_log_entry "${trace}" 1
15577
15578         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
15579         echo "entry = '${entry[*]}'" >&2
15580
15581         pfid2=${entry[4]}
15582         if [[ "${pfid1}" != "${pfid2}" ]]; then
15583                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
15584         fi
15585
15586         size=${entry[8]}
15587         if ((size != 524288)); then
15588                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
15589         fi
15590
15591         flags=${entry[10]}
15592         if [[ "${flags}" != "r" ]]; then
15593                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
15594         fi
15595 }
15596 run_test 165b "ofd access log entries are produced and consumed"
15597
15598 test_165c() {
15599         local file="${DIR}/${tdir}/${tfile}"
15600         test_mkdir "${DIR}/${tdir}"
15601
15602         setup_165
15603
15604         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
15605
15606         # 4096 / 64 = 64. Create twice as many entries.
15607         for ((i = 0; i < 128; i++)); do
15608                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c || error "cannot create file"
15609         done
15610
15611         sync
15612         do_facet ost1 ofd_access_log_reader --list
15613         unlinkmany  "${file}-%d" 128
15614 }
15615 run_test 165c "full ofd access logs do not block IOs"
15616
15617 oal_peek_entry_count() {
15618         do_facet ost1 ofd_access_log_reader --list | awk '$1 == "_entry_count:" { print $2; }'
15619 }
15620
15621 oal_expect_entry_count() {
15622         local entry_count=$(oal_peek_entry_count)
15623         local expect="$1"
15624
15625         if ((entry_count == expect)); then
15626                 return 0
15627         fi
15628
15629         error_noexit "bad entry count, got ${entry_count}, expected ${expect}"
15630         do_facet ost1 ofd_access_log_reader --list >&2
15631         exit 1
15632 }
15633
15634 test_165d() {
15635         local trace="/tmp/${tfile}.trace"
15636         local file="${DIR}/${tdir}/${tfile}"
15637         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
15638         local entry_count
15639         test_mkdir "${DIR}/${tdir}"
15640
15641         setup_165
15642         lfs setstripe -c 1 -i 0 "${file}"
15643
15644         do_facet ost1 lctl set_param "${param}=rw"
15645         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15646         oal_expect_entry_count 1
15647
15648         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15649         oal_expect_entry_count 2
15650
15651         do_facet ost1 lctl set_param "${param}=r"
15652         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15653         oal_expect_entry_count 2
15654
15655         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15656         oal_expect_entry_count 3
15657
15658         do_facet ost1 lctl set_param "${param}=w"
15659         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15660         oal_expect_entry_count 4
15661
15662         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15663         oal_expect_entry_count 4
15664
15665         do_facet ost1 lctl set_param "${param}=0"
15666         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15667         oal_expect_entry_count 4
15668
15669         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15670         oal_expect_entry_count 4
15671 }
15672 run_test 165d "ofd_access_log mask works"
15673
15674 test_169() {
15675         # do directio so as not to populate the page cache
15676         log "creating a 10 Mb file"
15677         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
15678         log "starting reads"
15679         dd if=$DIR/$tfile of=/dev/null bs=4096 &
15680         log "truncating the file"
15681         $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
15682         log "killing dd"
15683         kill %+ || true # reads might have finished
15684         echo "wait until dd is finished"
15685         wait
15686         log "removing the temporary file"
15687         rm -rf $DIR/$tfile || error "tmp file removal failed"
15688 }
15689 run_test 169 "parallel read and truncate should not deadlock"
15690
15691 test_170() {
15692         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15693
15694         $LCTL clear     # bug 18514
15695         $LCTL debug_daemon start $TMP/${tfile}_log_good
15696         touch $DIR/$tfile
15697         $LCTL debug_daemon stop
15698         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
15699                 error "sed failed to read log_good"
15700
15701         $LCTL debug_daemon start $TMP/${tfile}_log_good
15702         rm -rf $DIR/$tfile
15703         $LCTL debug_daemon stop
15704
15705         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
15706                error "lctl df log_bad failed"
15707
15708         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
15709         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
15710
15711         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
15712         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
15713
15714         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
15715                 error "bad_line good_line1 good_line2 are empty"
15716
15717         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
15718         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
15719         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
15720
15721         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
15722         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
15723         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
15724
15725         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
15726                 error "bad_line_new good_line_new are empty"
15727
15728         local expected_good=$((good_line1 + good_line2*2))
15729
15730         rm -f $TMP/${tfile}*
15731         # LU-231, short malformed line may not be counted into bad lines
15732         if [ $bad_line -ne $bad_line_new ] &&
15733                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
15734                 error "expected $bad_line bad lines, but got $bad_line_new"
15735                 return 1
15736         fi
15737
15738         if [ $expected_good -ne $good_line_new ]; then
15739                 error "expected $expected_good good lines, but got $good_line_new"
15740                 return 2
15741         fi
15742         true
15743 }
15744 run_test 170 "test lctl df to handle corrupted log ====================="
15745
15746 test_171() { # bug20592
15747         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15748
15749         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
15750         $LCTL set_param fail_loc=0x50e
15751         $LCTL set_param fail_val=3000
15752         multiop_bg_pause $DIR/$tfile O_s || true
15753         local MULTIPID=$!
15754         kill -USR1 $MULTIPID
15755         # cause log dump
15756         sleep 3
15757         wait $MULTIPID
15758         if dmesg | grep "recursive fault"; then
15759                 error "caught a recursive fault"
15760         fi
15761         $LCTL set_param fail_loc=0
15762         true
15763 }
15764 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
15765
15766 # it would be good to share it with obdfilter-survey/iokit-libecho code
15767 setup_obdecho_osc () {
15768         local rc=0
15769         local ost_nid=$1
15770         local obdfilter_name=$2
15771         echo "Creating new osc for $obdfilter_name on $ost_nid"
15772         # make sure we can find loopback nid
15773         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
15774
15775         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
15776                            ${obdfilter_name}_osc_UUID || rc=2; }
15777         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
15778                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
15779         return $rc
15780 }
15781
15782 cleanup_obdecho_osc () {
15783         local obdfilter_name=$1
15784         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
15785         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
15786         return 0
15787 }
15788
15789 obdecho_test() {
15790         local OBD=$1
15791         local node=$2
15792         local pages=${3:-64}
15793         local rc=0
15794         local id
15795
15796         local count=10
15797         local obd_size=$(get_obd_size $node $OBD)
15798         local page_size=$(get_page_size $node)
15799         if [[ -n "$obd_size" ]]; then
15800                 local new_count=$((obd_size / (pages * page_size / 1024)))
15801                 [[ $new_count -ge $count ]] || count=$new_count
15802         fi
15803
15804         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
15805         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
15806                            rc=2; }
15807         if [ $rc -eq 0 ]; then
15808             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
15809             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
15810         fi
15811         echo "New object id is $id"
15812         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
15813                            rc=4; }
15814         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
15815                            "test_brw $count w v $pages $id" || rc=4; }
15816         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
15817                            rc=4; }
15818         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
15819                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
15820         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
15821                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
15822         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
15823         return $rc
15824 }
15825
15826 test_180a() {
15827         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15828
15829         if ! [ -d /sys/fs/lustre/echo_client ] &&
15830            ! module_loaded obdecho; then
15831                 load_module obdecho/obdecho &&
15832                         stack_trap "rmmod obdecho" EXIT ||
15833                         error "unable to load obdecho on client"
15834         fi
15835
15836         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
15837         local host=$($LCTL get_param -n osc.$osc.import |
15838                      awk '/current_connection:/ { print $2 }' )
15839         local target=$($LCTL get_param -n osc.$osc.import |
15840                        awk '/target:/ { print $2 }' )
15841         target=${target%_UUID}
15842
15843         if [ -n "$target" ]; then
15844                 setup_obdecho_osc $host $target &&
15845                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
15846                         { error "obdecho setup failed with $?"; return; }
15847
15848                 obdecho_test ${target}_osc client ||
15849                         error "obdecho_test failed on ${target}_osc"
15850         else
15851                 $LCTL get_param osc.$osc.import
15852                 error "there is no osc.$osc.import target"
15853         fi
15854 }
15855 run_test 180a "test obdecho on osc"
15856
15857 test_180b() {
15858         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15859         remote_ost_nodsh && skip "remote OST with nodsh"
15860
15861         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
15862                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
15863                 error "failed to load module obdecho"
15864
15865         local target=$(do_facet ost1 $LCTL dl |
15866                        awk '/obdfilter/ { print $4; exit; }')
15867
15868         if [ -n "$target" ]; then
15869                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
15870         else
15871                 do_facet ost1 $LCTL dl
15872                 error "there is no obdfilter target on ost1"
15873         fi
15874 }
15875 run_test 180b "test obdecho directly on obdfilter"
15876
15877 test_180c() { # LU-2598
15878         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15879         remote_ost_nodsh && skip "remote OST with nodsh"
15880         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
15881                 skip "Need MDS version at least 2.4.0"
15882
15883         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
15884                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
15885                 error "failed to load module obdecho"
15886
15887         local target=$(do_facet ost1 $LCTL dl |
15888                        awk '/obdfilter/ { print $4; exit; }')
15889
15890         if [ -n "$target" ]; then
15891                 local pages=16384 # 64MB bulk I/O RPC size
15892
15893                 obdecho_test "$target" ost1 "$pages" ||
15894                         error "obdecho_test with pages=$pages failed with $?"
15895         else
15896                 do_facet ost1 $LCTL dl
15897                 error "there is no obdfilter target on ost1"
15898         fi
15899 }
15900 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
15901
15902 test_181() { # bug 22177
15903         test_mkdir $DIR/$tdir
15904         # create enough files to index the directory
15905         createmany -o $DIR/$tdir/foobar 4000
15906         # print attributes for debug purpose
15907         lsattr -d .
15908         # open dir
15909         multiop_bg_pause $DIR/$tdir D_Sc || return 1
15910         MULTIPID=$!
15911         # remove the files & current working dir
15912         unlinkmany $DIR/$tdir/foobar 4000
15913         rmdir $DIR/$tdir
15914         kill -USR1 $MULTIPID
15915         wait $MULTIPID
15916         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
15917         return 0
15918 }
15919 run_test 181 "Test open-unlinked dir ========================"
15920
15921 test_182() {
15922         local fcount=1000
15923         local tcount=10
15924
15925         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
15926
15927         $LCTL set_param mdc.*.rpc_stats=clear
15928
15929         for (( i = 0; i < $tcount; i++ )) ; do
15930                 mkdir $DIR/$tdir/$i
15931         done
15932
15933         for (( i = 0; i < $tcount; i++ )) ; do
15934                 createmany -o $DIR/$tdir/$i/f- $fcount &
15935         done
15936         wait
15937
15938         for (( i = 0; i < $tcount; i++ )) ; do
15939                 unlinkmany $DIR/$tdir/$i/f- $fcount &
15940         done
15941         wait
15942
15943         $LCTL get_param mdc.*.rpc_stats
15944
15945         rm -rf $DIR/$tdir
15946 }
15947 run_test 182 "Test parallel modify metadata operations ================"
15948
15949 test_183() { # LU-2275
15950         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15951         remote_mds_nodsh && skip "remote MDS with nodsh"
15952         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
15953                 skip "Need MDS version at least 2.3.56"
15954
15955         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
15956         echo aaa > $DIR/$tdir/$tfile
15957
15958 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
15959         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
15960
15961         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
15962         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
15963
15964         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
15965
15966         # Flush negative dentry cache
15967         touch $DIR/$tdir/$tfile
15968
15969         # We are not checking for any leaked references here, they'll
15970         # become evident next time we do cleanup with module unload.
15971         rm -rf $DIR/$tdir
15972 }
15973 run_test 183 "No crash or request leak in case of strange dispositions ========"
15974
15975 # test suite 184 is for LU-2016, LU-2017
15976 test_184a() {
15977         check_swap_layouts_support
15978
15979         dir0=$DIR/$tdir/$testnum
15980         test_mkdir -p -c1 $dir0
15981         ref1=/etc/passwd
15982         ref2=/etc/group
15983         file1=$dir0/f1
15984         file2=$dir0/f2
15985         $LFS setstripe -c1 $file1
15986         cp $ref1 $file1
15987         $LFS setstripe -c2 $file2
15988         cp $ref2 $file2
15989         gen1=$($LFS getstripe -g $file1)
15990         gen2=$($LFS getstripe -g $file2)
15991
15992         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
15993         gen=$($LFS getstripe -g $file1)
15994         [[ $gen1 != $gen ]] ||
15995                 "Layout generation on $file1 does not change"
15996         gen=$($LFS getstripe -g $file2)
15997         [[ $gen2 != $gen ]] ||
15998                 "Layout generation on $file2 does not change"
15999
16000         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
16001         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
16002
16003         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
16004 }
16005 run_test 184a "Basic layout swap"
16006
16007 test_184b() {
16008         check_swap_layouts_support
16009
16010         dir0=$DIR/$tdir/$testnum
16011         mkdir -p $dir0 || error "creating dir $dir0"
16012         file1=$dir0/f1
16013         file2=$dir0/f2
16014         file3=$dir0/f3
16015         dir1=$dir0/d1
16016         dir2=$dir0/d2
16017         mkdir $dir1 $dir2
16018         $LFS setstripe -c1 $file1
16019         $LFS setstripe -c2 $file2
16020         $LFS setstripe -c1 $file3
16021         chown $RUNAS_ID $file3
16022         gen1=$($LFS getstripe -g $file1)
16023         gen2=$($LFS getstripe -g $file2)
16024
16025         $LFS swap_layouts $dir1 $dir2 &&
16026                 error "swap of directories layouts should fail"
16027         $LFS swap_layouts $dir1 $file1 &&
16028                 error "swap of directory and file layouts should fail"
16029         $RUNAS $LFS swap_layouts $file1 $file2 &&
16030                 error "swap of file we cannot write should fail"
16031         $LFS swap_layouts $file1 $file3 &&
16032                 error "swap of file with different owner should fail"
16033         /bin/true # to clear error code
16034 }
16035 run_test 184b "Forbidden layout swap (will generate errors)"
16036
16037 test_184c() {
16038         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
16039         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
16040         check_swap_layouts_support
16041         check_swap_layout_no_dom $DIR
16042
16043         local dir0=$DIR/$tdir/$testnum
16044         mkdir -p $dir0 || error "creating dir $dir0"
16045
16046         local ref1=$dir0/ref1
16047         local ref2=$dir0/ref2
16048         local file1=$dir0/file1
16049         local file2=$dir0/file2
16050         # create a file large enough for the concurrent test
16051         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
16052         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
16053         echo "ref file size: ref1($(stat -c %s $ref1))," \
16054              "ref2($(stat -c %s $ref2))"
16055
16056         cp $ref2 $file2
16057         dd if=$ref1 of=$file1 bs=16k &
16058         local DD_PID=$!
16059
16060         # Make sure dd starts to copy file, but wait at most 5 seconds
16061         local loops=0
16062         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
16063
16064         $LFS swap_layouts $file1 $file2
16065         local rc=$?
16066         wait $DD_PID
16067         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
16068         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
16069
16070         # how many bytes copied before swapping layout
16071         local copied=$(stat -c %s $file2)
16072         local remaining=$(stat -c %s $ref1)
16073         remaining=$((remaining - copied))
16074         echo "Copied $copied bytes before swapping layout..."
16075
16076         cmp -n $copied $file1 $ref2 | grep differ &&
16077                 error "Content mismatch [0, $copied) of ref2 and file1"
16078         cmp -n $copied $file2 $ref1 ||
16079                 error "Content mismatch [0, $copied) of ref1 and file2"
16080         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
16081                 error "Content mismatch [$copied, EOF) of ref1 and file1"
16082
16083         # clean up
16084         rm -f $ref1 $ref2 $file1 $file2
16085 }
16086 run_test 184c "Concurrent write and layout swap"
16087
16088 test_184d() {
16089         check_swap_layouts_support
16090         check_swap_layout_no_dom $DIR
16091         [ -z "$(which getfattr 2>/dev/null)" ] &&
16092                 skip_env "no getfattr command"
16093
16094         local file1=$DIR/$tdir/$tfile-1
16095         local file2=$DIR/$tdir/$tfile-2
16096         local file3=$DIR/$tdir/$tfile-3
16097         local lovea1
16098         local lovea2
16099
16100         mkdir -p $DIR/$tdir
16101         touch $file1 || error "create $file1 failed"
16102         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
16103                 error "create $file2 failed"
16104         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
16105                 error "create $file3 failed"
16106         lovea1=$(get_layout_param $file1)
16107
16108         $LFS swap_layouts $file2 $file3 ||
16109                 error "swap $file2 $file3 layouts failed"
16110         $LFS swap_layouts $file1 $file2 ||
16111                 error "swap $file1 $file2 layouts failed"
16112
16113         lovea2=$(get_layout_param $file2)
16114         echo "$lovea1"
16115         echo "$lovea2"
16116         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
16117
16118         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
16119         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
16120 }
16121 run_test 184d "allow stripeless layouts swap"
16122
16123 test_184e() {
16124         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
16125                 skip "Need MDS version at least 2.6.94"
16126         check_swap_layouts_support
16127         check_swap_layout_no_dom $DIR
16128         [ -z "$(which getfattr 2>/dev/null)" ] &&
16129                 skip_env "no getfattr command"
16130
16131         local file1=$DIR/$tdir/$tfile-1
16132         local file2=$DIR/$tdir/$tfile-2
16133         local file3=$DIR/$tdir/$tfile-3
16134         local lovea
16135
16136         mkdir -p $DIR/$tdir
16137         touch $file1 || error "create $file1 failed"
16138         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
16139                 error "create $file2 failed"
16140         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
16141                 error "create $file3 failed"
16142
16143         $LFS swap_layouts $file1 $file2 ||
16144                 error "swap $file1 $file2 layouts failed"
16145
16146         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
16147         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
16148
16149         echo 123 > $file1 || error "Should be able to write into $file1"
16150
16151         $LFS swap_layouts $file1 $file3 ||
16152                 error "swap $file1 $file3 layouts failed"
16153
16154         echo 123 > $file1 || error "Should be able to write into $file1"
16155
16156         rm -rf $file1 $file2 $file3
16157 }
16158 run_test 184e "Recreate layout after stripeless layout swaps"
16159
16160 test_184f() {
16161         # Create a file with name longer than sizeof(struct stat) ==
16162         # 144 to see if we can get chars from the file name to appear
16163         # in the returned striping. Note that 'f' == 0x66.
16164         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
16165
16166         mkdir -p $DIR/$tdir
16167         mcreate $DIR/$tdir/$file
16168         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
16169                 error "IOC_MDC_GETFILEINFO returned garbage striping"
16170         fi
16171 }
16172 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
16173
16174 test_185() { # LU-2441
16175         # LU-3553 - no volatile file support in old servers
16176         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
16177                 skip "Need MDS version at least 2.3.60"
16178
16179         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16180         touch $DIR/$tdir/spoo
16181         local mtime1=$(stat -c "%Y" $DIR/$tdir)
16182         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
16183                 error "cannot create/write a volatile file"
16184         [ "$FILESET" == "" ] &&
16185         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
16186                 error "FID is still valid after close"
16187
16188         multiop_bg_pause $DIR/$tdir vVw4096_c
16189         local multi_pid=$!
16190
16191         local OLD_IFS=$IFS
16192         IFS=":"
16193         local fidv=($fid)
16194         IFS=$OLD_IFS
16195         # assume that the next FID for this client is sequential, since stdout
16196         # is unfortunately eaten by multiop_bg_pause
16197         local n=$((${fidv[1]} + 1))
16198         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
16199         if [ "$FILESET" == "" ]; then
16200                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
16201                         error "FID is missing before close"
16202         fi
16203         kill -USR1 $multi_pid
16204         # 1 second delay, so if mtime change we will see it
16205         sleep 1
16206         local mtime2=$(stat -c "%Y" $DIR/$tdir)
16207         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
16208 }
16209 run_test 185 "Volatile file support"
16210
16211 function create_check_volatile() {
16212         local idx=$1
16213         local tgt
16214
16215         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
16216         local PID=$!
16217         sleep 1
16218         local FID=$(cat /tmp/${tfile}.fid)
16219         [ "$FID" == "" ] && error "can't get FID for volatile"
16220         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
16221         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
16222         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
16223         kill -USR1 $PID
16224         wait
16225         sleep 1
16226         cancel_lru_locks mdc # flush opencache
16227         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
16228         return 0
16229 }
16230
16231 test_185a(){
16232         # LU-12516 - volatile creation via .lustre
16233         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
16234                 skip "Need MDS version at least 2.3.55"
16235
16236         create_check_volatile 0
16237         [ $MDSCOUNT -lt 2 ] && return 0
16238
16239         # DNE case
16240         create_check_volatile 1
16241
16242         return 0
16243 }
16244 run_test 185a "Volatile file creation in .lustre/fid/"
16245
16246 test_187a() {
16247         remote_mds_nodsh && skip "remote MDS with nodsh"
16248         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
16249                 skip "Need MDS version at least 2.3.0"
16250
16251         local dir0=$DIR/$tdir/$testnum
16252         mkdir -p $dir0 || error "creating dir $dir0"
16253
16254         local file=$dir0/file1
16255         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
16256         local dv1=$($LFS data_version $file)
16257         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
16258         local dv2=$($LFS data_version $file)
16259         [[ $dv1 != $dv2 ]] ||
16260                 error "data version did not change on write $dv1 == $dv2"
16261
16262         # clean up
16263         rm -f $file1
16264 }
16265 run_test 187a "Test data version change"
16266
16267 test_187b() {
16268         remote_mds_nodsh && skip "remote MDS with nodsh"
16269         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
16270                 skip "Need MDS version at least 2.3.0"
16271
16272         local dir0=$DIR/$tdir/$testnum
16273         mkdir -p $dir0 || error "creating dir $dir0"
16274
16275         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
16276         [[ ${DV[0]} != ${DV[1]} ]] ||
16277                 error "data version did not change on write"\
16278                       " ${DV[0]} == ${DV[1]}"
16279
16280         # clean up
16281         rm -f $file1
16282 }
16283 run_test 187b "Test data version change on volatile file"
16284
16285 test_200() {
16286         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16287         remote_mgs_nodsh && skip "remote MGS with nodsh"
16288         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16289
16290         local POOL=${POOL:-cea1}
16291         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
16292         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
16293         # Pool OST targets
16294         local first_ost=0
16295         local last_ost=$(($OSTCOUNT - 1))
16296         local ost_step=2
16297         local ost_list=$(seq $first_ost $ost_step $last_ost)
16298         local ost_range="$first_ost $last_ost $ost_step"
16299         local test_path=$POOL_ROOT/$POOL_DIR_NAME
16300         local file_dir=$POOL_ROOT/file_tst
16301         local subdir=$test_path/subdir
16302         local rc=0
16303
16304         while : ; do
16305                 # former test_200a test_200b
16306                 pool_add $POOL                          || { rc=$? ; break; }
16307                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
16308                 # former test_200c test_200d
16309                 mkdir -p $test_path
16310                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
16311                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
16312                 mkdir -p $subdir
16313                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
16314                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
16315                                                         || { rc=$? ; break; }
16316                 # former test_200e test_200f
16317                 local files=$((OSTCOUNT*3))
16318                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
16319                                                         || { rc=$? ; break; }
16320                 pool_create_files $POOL $file_dir $files "$ost_list" \
16321                                                         || { rc=$? ; break; }
16322                 # former test_200g test_200h
16323                 pool_lfs_df $POOL                       || { rc=$? ; break; }
16324                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
16325
16326                 # former test_201a test_201b test_201c
16327                 pool_remove_first_target $POOL          || { rc=$? ; break; }
16328
16329                 local f=$test_path/$tfile
16330                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
16331                 pool_remove $POOL $f                    || { rc=$? ; break; }
16332                 break
16333         done
16334
16335         destroy_test_pools
16336
16337         return $rc
16338 }
16339 run_test 200 "OST pools"
16340
16341 # usage: default_attr <count | size | offset>
16342 default_attr() {
16343         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
16344 }
16345
16346 # usage: check_default_stripe_attr
16347 check_default_stripe_attr() {
16348         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
16349         case $1 in
16350         --stripe-count|-c)
16351                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
16352         --stripe-size|-S)
16353                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
16354         --stripe-index|-i)
16355                 EXPECTED=-1;;
16356         *)
16357                 error "unknown getstripe attr '$1'"
16358         esac
16359
16360         [ $ACTUAL == $EXPECTED ] ||
16361                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
16362 }
16363
16364 test_204a() {
16365         test_mkdir $DIR/$tdir
16366         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
16367
16368         check_default_stripe_attr --stripe-count
16369         check_default_stripe_attr --stripe-size
16370         check_default_stripe_attr --stripe-index
16371 }
16372 run_test 204a "Print default stripe attributes"
16373
16374 test_204b() {
16375         test_mkdir $DIR/$tdir
16376         $LFS setstripe --stripe-count 1 $DIR/$tdir
16377
16378         check_default_stripe_attr --stripe-size
16379         check_default_stripe_attr --stripe-index
16380 }
16381 run_test 204b "Print default stripe size and offset"
16382
16383 test_204c() {
16384         test_mkdir $DIR/$tdir
16385         $LFS setstripe --stripe-size 65536 $DIR/$tdir
16386
16387         check_default_stripe_attr --stripe-count
16388         check_default_stripe_attr --stripe-index
16389 }
16390 run_test 204c "Print default stripe count and offset"
16391
16392 test_204d() {
16393         test_mkdir $DIR/$tdir
16394         $LFS setstripe --stripe-index 0 $DIR/$tdir
16395
16396         check_default_stripe_attr --stripe-count
16397         check_default_stripe_attr --stripe-size
16398 }
16399 run_test 204d "Print default stripe count and size"
16400
16401 test_204e() {
16402         test_mkdir $DIR/$tdir
16403         $LFS setstripe -d $DIR/$tdir
16404
16405         check_default_stripe_attr --stripe-count --raw
16406         check_default_stripe_attr --stripe-size --raw
16407         check_default_stripe_attr --stripe-index --raw
16408 }
16409 run_test 204e "Print raw stripe attributes"
16410
16411 test_204f() {
16412         test_mkdir $DIR/$tdir
16413         $LFS setstripe --stripe-count 1 $DIR/$tdir
16414
16415         check_default_stripe_attr --stripe-size --raw
16416         check_default_stripe_attr --stripe-index --raw
16417 }
16418 run_test 204f "Print raw stripe size and offset"
16419
16420 test_204g() {
16421         test_mkdir $DIR/$tdir
16422         $LFS setstripe --stripe-size 65536 $DIR/$tdir
16423
16424         check_default_stripe_attr --stripe-count --raw
16425         check_default_stripe_attr --stripe-index --raw
16426 }
16427 run_test 204g "Print raw stripe count and offset"
16428
16429 test_204h() {
16430         test_mkdir $DIR/$tdir
16431         $LFS setstripe --stripe-index 0 $DIR/$tdir
16432
16433         check_default_stripe_attr --stripe-count --raw
16434         check_default_stripe_attr --stripe-size --raw
16435 }
16436 run_test 204h "Print raw stripe count and size"
16437
16438 # Figure out which job scheduler is being used, if any,
16439 # or use a fake one
16440 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
16441         JOBENV=SLURM_JOB_ID
16442 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
16443         JOBENV=LSB_JOBID
16444 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
16445         JOBENV=PBS_JOBID
16446 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
16447         JOBENV=LOADL_STEP_ID
16448 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
16449         JOBENV=JOB_ID
16450 else
16451         $LCTL list_param jobid_name > /dev/null 2>&1
16452         if [ $? -eq 0 ]; then
16453                 JOBENV=nodelocal
16454         else
16455                 JOBENV=FAKE_JOBID
16456         fi
16457 fi
16458 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
16459
16460 verify_jobstats() {
16461         local cmd=($1)
16462         shift
16463         local facets="$@"
16464
16465 # we don't really need to clear the stats for this test to work, since each
16466 # command has a unique jobid, but it makes debugging easier if needed.
16467 #       for facet in $facets; do
16468 #               local dev=$(convert_facet2label $facet)
16469 #               # clear old jobstats
16470 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
16471 #       done
16472
16473         # use a new JobID for each test, or we might see an old one
16474         [ "$JOBENV" = "FAKE_JOBID" ] &&
16475                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
16476
16477         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
16478
16479         [ "$JOBENV" = "nodelocal" ] && {
16480                 FAKE_JOBID=id.$testnum.%e.$RANDOM
16481                 $LCTL set_param jobid_name=$FAKE_JOBID
16482                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
16483         }
16484
16485         log "Test: ${cmd[*]}"
16486         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
16487
16488         if [ $JOBENV = "FAKE_JOBID" ]; then
16489                 FAKE_JOBID=$JOBVAL ${cmd[*]}
16490         else
16491                 ${cmd[*]}
16492         fi
16493
16494         # all files are created on OST0000
16495         for facet in $facets; do
16496                 local stats="*.$(convert_facet2label $facet).job_stats"
16497
16498                 # strip out libtool wrappers for in-tree executables
16499                 if [ $(do_facet $facet lctl get_param $stats |
16500                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
16501                         do_facet $facet lctl get_param $stats
16502                         error "No jobstats for $JOBVAL found on $facet::$stats"
16503                 fi
16504         done
16505 }
16506
16507 jobstats_set() {
16508         local new_jobenv=$1
16509
16510         set_persistent_param_and_check client "jobid_var" \
16511                 "$FSNAME.sys.jobid_var" $new_jobenv
16512 }
16513
16514 test_205a() { # Job stats
16515         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16516         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
16517                 skip "Need MDS version with at least 2.7.1"
16518         remote_mgs_nodsh && skip "remote MGS with nodsh"
16519         remote_mds_nodsh && skip "remote MDS with nodsh"
16520         remote_ost_nodsh && skip "remote OST with nodsh"
16521         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
16522                 skip "Server doesn't support jobstats"
16523         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
16524
16525         local old_jobenv=$($LCTL get_param -n jobid_var)
16526         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
16527
16528         if [[ $PERM_CMD == *"set_param -P"* ]]; then
16529                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
16530         else
16531                 stack_trap "do_facet mgs $PERM_CMD \
16532                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
16533         fi
16534         changelog_register
16535
16536         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
16537                                 mdt.*.job_cleanup_interval | head -n 1)
16538         local new_interval=5
16539         do_facet $SINGLEMDS \
16540                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
16541         stack_trap "do_facet $SINGLEMDS \
16542                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
16543         local start=$SECONDS
16544
16545         local cmd
16546         # mkdir
16547         cmd="mkdir $DIR/$tdir"
16548         verify_jobstats "$cmd" "$SINGLEMDS"
16549         # rmdir
16550         cmd="rmdir $DIR/$tdir"
16551         verify_jobstats "$cmd" "$SINGLEMDS"
16552         # mkdir on secondary MDT
16553         if [ $MDSCOUNT -gt 1 ]; then
16554                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
16555                 verify_jobstats "$cmd" "mds2"
16556         fi
16557         # mknod
16558         cmd="mknod $DIR/$tfile c 1 3"
16559         verify_jobstats "$cmd" "$SINGLEMDS"
16560         # unlink
16561         cmd="rm -f $DIR/$tfile"
16562         verify_jobstats "$cmd" "$SINGLEMDS"
16563         # create all files on OST0000 so verify_jobstats can find OST stats
16564         # open & close
16565         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
16566         verify_jobstats "$cmd" "$SINGLEMDS"
16567         # setattr
16568         cmd="touch $DIR/$tfile"
16569         verify_jobstats "$cmd" "$SINGLEMDS ost1"
16570         # write
16571         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
16572         verify_jobstats "$cmd" "ost1"
16573         # read
16574         cancel_lru_locks osc
16575         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
16576         verify_jobstats "$cmd" "ost1"
16577         # truncate
16578         cmd="$TRUNCATE $DIR/$tfile 0"
16579         verify_jobstats "$cmd" "$SINGLEMDS ost1"
16580         # rename
16581         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
16582         verify_jobstats "$cmd" "$SINGLEMDS"
16583         # jobstats expiry - sleep until old stats should be expired
16584         local left=$((new_interval + 5 - (SECONDS - start)))
16585         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
16586                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
16587                         "0" $left
16588         cmd="mkdir $DIR/$tdir.expire"
16589         verify_jobstats "$cmd" "$SINGLEMDS"
16590         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
16591             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
16592
16593         # Ensure that jobid are present in changelog (if supported by MDS)
16594         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
16595                 changelog_dump | tail -10
16596                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
16597                 [ $jobids -eq 9 ] ||
16598                         error "Wrong changelog jobid count $jobids != 9"
16599
16600                 # LU-5862
16601                 JOBENV="disable"
16602                 jobstats_set $JOBENV
16603                 touch $DIR/$tfile
16604                 changelog_dump | grep $tfile
16605                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
16606                 [ $jobids -eq 0 ] ||
16607                         error "Unexpected jobids when jobid_var=$JOBENV"
16608         fi
16609
16610         # test '%j' access to environment variable - if supported
16611         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
16612                 JOBENV="JOBCOMPLEX"
16613                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
16614
16615                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
16616         fi
16617
16618         # test '%j' access to per-session jobid - if supported
16619         if lctl list_param jobid_this_session > /dev/null 2>&1
16620         then
16621                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
16622                 lctl set_param jobid_this_session=$USER
16623
16624                 JOBENV="JOBCOMPLEX"
16625                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
16626
16627                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
16628         fi
16629 }
16630 run_test 205a "Verify job stats"
16631
16632 # LU-13117, LU-13597
16633 test_205b() {
16634         job_stats="mdt.*.job_stats"
16635         $LCTL set_param $job_stats=clear
16636         # Setting jobid_var to USER might not be supported
16637         $LCTL set_param jobid_var=USER || true
16638         $LCTL set_param jobid_name="%e.%u"
16639         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
16640         do_facet $SINGLEMDS $LCTL get_param $job_stats |
16641                 grep "job_id:.*foolish" &&
16642                         error "Unexpected jobid found"
16643         do_facet $SINGLEMDS $LCTL get_param $job_stats |
16644                 grep "open:.*min.*max.*sum" ||
16645                         error "wrong job_stats format found"
16646 }
16647 run_test 205b "Verify job stats jobid and output format"
16648
16649 # LU-13733
16650 test_205c() {
16651         $LCTL set_param llite.*.stats=0
16652         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
16653         $LCTL get_param llite.*.stats
16654         $LCTL get_param llite.*.stats | grep \
16655                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
16656                         error "wrong client stats format found"
16657 }
16658 run_test 205c "Verify client stats format"
16659
16660 # LU-1480, LU-1773 and LU-1657
16661 test_206() {
16662         mkdir -p $DIR/$tdir
16663         $LFS setstripe -c -1 $DIR/$tdir
16664 #define OBD_FAIL_LOV_INIT 0x1403
16665         $LCTL set_param fail_loc=0xa0001403
16666         $LCTL set_param fail_val=1
16667         touch $DIR/$tdir/$tfile || true
16668 }
16669 run_test 206 "fail lov_init_raid0() doesn't lbug"
16670
16671 test_207a() {
16672         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
16673         local fsz=`stat -c %s $DIR/$tfile`
16674         cancel_lru_locks mdc
16675
16676         # do not return layout in getattr intent
16677 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
16678         $LCTL set_param fail_loc=0x170
16679         local sz=`stat -c %s $DIR/$tfile`
16680
16681         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
16682
16683         rm -rf $DIR/$tfile
16684 }
16685 run_test 207a "can refresh layout at glimpse"
16686
16687 test_207b() {
16688         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
16689         local cksum=`md5sum $DIR/$tfile`
16690         local fsz=`stat -c %s $DIR/$tfile`
16691         cancel_lru_locks mdc
16692         cancel_lru_locks osc
16693
16694         # do not return layout in getattr intent
16695 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
16696         $LCTL set_param fail_loc=0x171
16697
16698         # it will refresh layout after the file is opened but before read issues
16699         echo checksum is "$cksum"
16700         echo "$cksum" |md5sum -c --quiet || error "file differs"
16701
16702         rm -rf $DIR/$tfile
16703 }
16704 run_test 207b "can refresh layout at open"
16705
16706 test_208() {
16707         # FIXME: in this test suite, only RD lease is used. This is okay
16708         # for now as only exclusive open is supported. After generic lease
16709         # is done, this test suite should be revised. - Jinshan
16710
16711         remote_mds_nodsh && skip "remote MDS with nodsh"
16712         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
16713                 skip "Need MDS version at least 2.4.52"
16714
16715         echo "==== test 1: verify get lease work"
16716         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
16717
16718         echo "==== test 2: verify lease can be broken by upcoming open"
16719         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
16720         local PID=$!
16721         sleep 1
16722
16723         $MULTIOP $DIR/$tfile oO_RDONLY:c
16724         kill -USR1 $PID && wait $PID || error "break lease error"
16725
16726         echo "==== test 3: verify lease can't be granted if an open already exists"
16727         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
16728         local PID=$!
16729         sleep 1
16730
16731         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
16732         kill -USR1 $PID && wait $PID || error "open file error"
16733
16734         echo "==== test 4: lease can sustain over recovery"
16735         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
16736         PID=$!
16737         sleep 1
16738
16739         fail mds1
16740
16741         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
16742
16743         echo "==== test 5: lease broken can't be regained by replay"
16744         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
16745         PID=$!
16746         sleep 1
16747
16748         # open file to break lease and then recovery
16749         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
16750         fail mds1
16751
16752         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
16753
16754         rm -f $DIR/$tfile
16755 }
16756 run_test 208 "Exclusive open"
16757
16758 test_209() {
16759         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
16760                 skip_env "must have disp_stripe"
16761
16762         touch $DIR/$tfile
16763         sync; sleep 5; sync;
16764
16765         echo 3 > /proc/sys/vm/drop_caches
16766         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
16767                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
16768         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
16769
16770         # open/close 500 times
16771         for i in $(seq 500); do
16772                 cat $DIR/$tfile
16773         done
16774
16775         echo 3 > /proc/sys/vm/drop_caches
16776         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
16777                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
16778         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
16779
16780         echo "before: $req_before, after: $req_after"
16781         [ $((req_after - req_before)) -ge 300 ] &&
16782                 error "open/close requests are not freed"
16783         return 0
16784 }
16785 run_test 209 "read-only open/close requests should be freed promptly"
16786
16787 test_210() {
16788         local pid
16789
16790         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
16791         pid=$!
16792         sleep 1
16793
16794         $LFS getstripe $DIR/$tfile
16795         kill -USR1 $pid
16796         wait $pid || error "multiop failed"
16797
16798         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
16799         pid=$!
16800         sleep 1
16801
16802         $LFS getstripe $DIR/$tfile
16803         kill -USR1 $pid
16804         wait $pid || error "multiop failed"
16805 }
16806 run_test 210 "lfs getstripe does not break leases"
16807
16808 test_212() {
16809         size=`date +%s`
16810         size=$((size % 8192 + 1))
16811         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
16812         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
16813         rm -f $DIR/f212 $DIR/f212.xyz
16814 }
16815 run_test 212 "Sendfile test ============================================"
16816
16817 test_213() {
16818         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
16819         cancel_lru_locks osc
16820         lctl set_param fail_loc=0x8000040f
16821         # generate a read lock
16822         cat $DIR/$tfile > /dev/null
16823         # write to the file, it will try to cancel the above read lock.
16824         cat /etc/hosts >> $DIR/$tfile
16825 }
16826 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
16827
16828 test_214() { # for bug 20133
16829         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
16830         for (( i=0; i < 340; i++ )) ; do
16831                 touch $DIR/$tdir/d214c/a$i
16832         done
16833
16834         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
16835         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
16836         ls $DIR/d214c || error "ls $DIR/d214c failed"
16837         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
16838         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
16839 }
16840 run_test 214 "hash-indexed directory test - bug 20133"
16841
16842 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
16843 create_lnet_proc_files() {
16844         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
16845 }
16846
16847 # counterpart of create_lnet_proc_files
16848 remove_lnet_proc_files() {
16849         rm -f $TMP/lnet_$1.sys
16850 }
16851
16852 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
16853 # 3rd arg as regexp for body
16854 check_lnet_proc_stats() {
16855         local l=$(cat "$TMP/lnet_$1" |wc -l)
16856         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
16857
16858         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
16859 }
16860
16861 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
16862 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
16863 # optional and can be regexp for 2nd line (lnet.routes case)
16864 check_lnet_proc_entry() {
16865         local blp=2          # blp stands for 'position of 1st line of body'
16866         [ -z "$5" ] || blp=3 # lnet.routes case
16867
16868         local l=$(cat "$TMP/lnet_$1" |wc -l)
16869         # subtracting one from $blp because the body can be empty
16870         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
16871
16872         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
16873                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
16874
16875         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
16876                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
16877
16878         # bail out if any unexpected line happened
16879         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
16880         [ "$?" != 0 ] || error "$2 misformatted"
16881 }
16882
16883 test_215() { # for bugs 18102, 21079, 21517
16884         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16885
16886         local N='(0|[1-9][0-9]*)'       # non-negative numeric
16887         local P='[1-9][0-9]*'           # positive numeric
16888         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
16889         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
16890         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
16891         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
16892
16893         local L1 # regexp for 1st line
16894         local L2 # regexp for 2nd line (optional)
16895         local BR # regexp for the rest (body)
16896
16897         # lnet.stats should look as 11 space-separated non-negative numerics
16898         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
16899         create_lnet_proc_files "stats"
16900         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
16901         remove_lnet_proc_files "stats"
16902
16903         # lnet.routes should look like this:
16904         # Routing disabled/enabled
16905         # net hops priority state router
16906         # where net is a string like tcp0, hops > 0, priority >= 0,
16907         # state is up/down,
16908         # router is a string like 192.168.1.1@tcp2
16909         L1="^Routing (disabled|enabled)$"
16910         L2="^net +hops +priority +state +router$"
16911         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
16912         create_lnet_proc_files "routes"
16913         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
16914         remove_lnet_proc_files "routes"
16915
16916         # lnet.routers should look like this:
16917         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
16918         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
16919         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
16920         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
16921         L1="^ref +rtr_ref +alive +router$"
16922         BR="^$P +$P +(up|down) +$NID$"
16923         create_lnet_proc_files "routers"
16924         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
16925         remove_lnet_proc_files "routers"
16926
16927         # lnet.peers should look like this:
16928         # nid refs state last max rtr min tx min queue
16929         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
16930         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
16931         # numeric (0 or >0 or <0), queue >= 0.
16932         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
16933         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
16934         create_lnet_proc_files "peers"
16935         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
16936         remove_lnet_proc_files "peers"
16937
16938         # lnet.buffers  should look like this:
16939         # pages count credits min
16940         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
16941         L1="^pages +count +credits +min$"
16942         BR="^ +$N +$N +$I +$I$"
16943         create_lnet_proc_files "buffers"
16944         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
16945         remove_lnet_proc_files "buffers"
16946
16947         # lnet.nis should look like this:
16948         # nid status alive refs peer rtr max tx min
16949         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
16950         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
16951         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
16952         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
16953         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
16954         create_lnet_proc_files "nis"
16955         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
16956         remove_lnet_proc_files "nis"
16957
16958         # can we successfully write to lnet.stats?
16959         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
16960 }
16961 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
16962
16963 test_216() { # bug 20317
16964         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16965         remote_ost_nodsh && skip "remote OST with nodsh"
16966
16967         local node
16968         local facets=$(get_facets OST)
16969         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16970
16971         save_lustre_params client "osc.*.contention_seconds" > $p
16972         save_lustre_params $facets \
16973                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
16974         save_lustre_params $facets \
16975                 "ldlm.namespaces.filter-*.contended_locks" >> $p
16976         save_lustre_params $facets \
16977                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
16978         clear_stats osc.*.osc_stats
16979
16980         # agressive lockless i/o settings
16981         do_nodes $(comma_list $(osts_nodes)) \
16982                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
16983                         ldlm.namespaces.filter-*.contended_locks=0 \
16984                         ldlm.namespaces.filter-*.contention_seconds=60"
16985         lctl set_param -n osc.*.contention_seconds=60
16986
16987         $DIRECTIO write $DIR/$tfile 0 10 4096
16988         $CHECKSTAT -s 40960 $DIR/$tfile
16989
16990         # disable lockless i/o
16991         do_nodes $(comma_list $(osts_nodes)) \
16992                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
16993                         ldlm.namespaces.filter-*.contended_locks=32 \
16994                         ldlm.namespaces.filter-*.contention_seconds=0"
16995         lctl set_param -n osc.*.contention_seconds=0
16996         clear_stats osc.*.osc_stats
16997
16998         dd if=/dev/zero of=$DIR/$tfile count=0
16999         $CHECKSTAT -s 0 $DIR/$tfile
17000
17001         restore_lustre_params <$p
17002         rm -f $p
17003         rm $DIR/$tfile
17004 }
17005 run_test 216 "check lockless direct write updates file size and kms correctly"
17006
17007 test_217() { # bug 22430
17008         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17009
17010         local node
17011         local nid
17012
17013         for node in $(nodes_list); do
17014                 nid=$(host_nids_address $node $NETTYPE)
17015                 if [[ $nid = *-* ]] ; then
17016                         echo "lctl ping $(h2nettype $nid)"
17017                         lctl ping $(h2nettype $nid)
17018                 else
17019                         echo "skipping $node (no hyphen detected)"
17020                 fi
17021         done
17022 }
17023 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
17024
17025 test_218() {
17026        # do directio so as not to populate the page cache
17027        log "creating a 10 Mb file"
17028        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
17029        log "starting reads"
17030        dd if=$DIR/$tfile of=/dev/null bs=4096 &
17031        log "truncating the file"
17032        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
17033        log "killing dd"
17034        kill %+ || true # reads might have finished
17035        echo "wait until dd is finished"
17036        wait
17037        log "removing the temporary file"
17038        rm -rf $DIR/$tfile || error "tmp file removal failed"
17039 }
17040 run_test 218 "parallel read and truncate should not deadlock"
17041
17042 test_219() {
17043         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17044
17045         # write one partial page
17046         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
17047         # set no grant so vvp_io_commit_write will do sync write
17048         $LCTL set_param fail_loc=0x411
17049         # write a full page at the end of file
17050         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
17051
17052         $LCTL set_param fail_loc=0
17053         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
17054         $LCTL set_param fail_loc=0x411
17055         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
17056
17057         # LU-4201
17058         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
17059         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
17060 }
17061 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
17062
17063 test_220() { #LU-325
17064         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17065         remote_ost_nodsh && skip "remote OST with nodsh"
17066         remote_mds_nodsh && skip "remote MDS with nodsh"
17067         remote_mgs_nodsh && skip "remote MGS with nodsh"
17068
17069         local OSTIDX=0
17070
17071         # create on MDT0000 so the last_id and next_id are correct
17072         mkdir $DIR/$tdir
17073         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
17074         OST=${OST%_UUID}
17075
17076         # on the mdt's osc
17077         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
17078         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
17079                         osp.$mdtosc_proc1.prealloc_last_id)
17080         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
17081                         osp.$mdtosc_proc1.prealloc_next_id)
17082
17083         $LFS df -i
17084
17085         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
17086         #define OBD_FAIL_OST_ENOINO              0x229
17087         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
17088         create_pool $FSNAME.$TESTNAME || return 1
17089         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
17090
17091         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
17092
17093         MDSOBJS=$((last_id - next_id))
17094         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
17095
17096         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
17097         echo "OST still has $count kbytes free"
17098
17099         echo "create $MDSOBJS files @next_id..."
17100         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
17101
17102         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
17103                         osp.$mdtosc_proc1.prealloc_last_id)
17104         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
17105                         osp.$mdtosc_proc1.prealloc_next_id)
17106
17107         echo "after creation, last_id=$last_id2, next_id=$next_id2"
17108         $LFS df -i
17109
17110         echo "cleanup..."
17111
17112         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
17113         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
17114
17115         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
17116                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
17117         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
17118                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
17119         echo "unlink $MDSOBJS files @$next_id..."
17120         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
17121 }
17122 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
17123
17124 test_221() {
17125         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17126
17127         dd if=`which date` of=$MOUNT/date oflag=sync
17128         chmod +x $MOUNT/date
17129
17130         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
17131         $LCTL set_param fail_loc=0x80001401
17132
17133         $MOUNT/date > /dev/null
17134         rm -f $MOUNT/date
17135 }
17136 run_test 221 "make sure fault and truncate race to not cause OOM"
17137
17138 test_222a () {
17139         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17140
17141         rm -rf $DIR/$tdir
17142         test_mkdir $DIR/$tdir
17143         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17144         createmany -o $DIR/$tdir/$tfile 10
17145         cancel_lru_locks mdc
17146         cancel_lru_locks osc
17147         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
17148         $LCTL set_param fail_loc=0x31a
17149         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
17150         $LCTL set_param fail_loc=0
17151         rm -r $DIR/$tdir
17152 }
17153 run_test 222a "AGL for ls should not trigger CLIO lock failure"
17154
17155 test_222b () {
17156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17157
17158         rm -rf $DIR/$tdir
17159         test_mkdir $DIR/$tdir
17160         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17161         createmany -o $DIR/$tdir/$tfile 10
17162         cancel_lru_locks mdc
17163         cancel_lru_locks osc
17164         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
17165         $LCTL set_param fail_loc=0x31a
17166         rm -r $DIR/$tdir || error "AGL for rmdir failed"
17167         $LCTL set_param fail_loc=0
17168 }
17169 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
17170
17171 test_223 () {
17172         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17173
17174         rm -rf $DIR/$tdir
17175         test_mkdir $DIR/$tdir
17176         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17177         createmany -o $DIR/$tdir/$tfile 10
17178         cancel_lru_locks mdc
17179         cancel_lru_locks osc
17180         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
17181         $LCTL set_param fail_loc=0x31b
17182         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
17183         $LCTL set_param fail_loc=0
17184         rm -r $DIR/$tdir
17185 }
17186 run_test 223 "osc reenqueue if without AGL lock granted ======================="
17187
17188 test_224a() { # LU-1039, MRP-303
17189         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17190
17191         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
17192         $LCTL set_param fail_loc=0x508
17193         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
17194         $LCTL set_param fail_loc=0
17195         df $DIR
17196 }
17197 run_test 224a "Don't panic on bulk IO failure"
17198
17199 test_224b() { # LU-1039, MRP-303
17200         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17201
17202         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
17203         cancel_lru_locks osc
17204         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
17205         $LCTL set_param fail_loc=0x515
17206         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
17207         $LCTL set_param fail_loc=0
17208         df $DIR
17209 }
17210 run_test 224b "Don't panic on bulk IO failure"
17211
17212 test_224c() { # LU-6441
17213         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17214         remote_mds_nodsh && skip "remote MDS with nodsh"
17215
17216         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17217         save_writethrough $p
17218         set_cache writethrough on
17219
17220         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
17221         local at_max=$($LCTL get_param -n at_max)
17222         local timeout=$($LCTL get_param -n timeout)
17223         local test_at="at_max"
17224         local param_at="$FSNAME.sys.at_max"
17225         local test_timeout="timeout"
17226         local param_timeout="$FSNAME.sys.timeout"
17227
17228         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
17229
17230         set_persistent_param_and_check client "$test_at" "$param_at" 0
17231         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
17232
17233         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
17234         do_facet ost1 "$LCTL set_param fail_loc=0x520"
17235         $LFS setstripe -c 1 -i 0 $DIR/$tfile
17236         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
17237         sync
17238         do_facet ost1 "$LCTL set_param fail_loc=0"
17239
17240         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
17241         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
17242                 $timeout
17243
17244         $LCTL set_param -n $pages_per_rpc
17245         restore_lustre_params < $p
17246         rm -f $p
17247 }
17248 run_test 224c "Don't hang if one of md lost during large bulk RPC"
17249
17250 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
17251 test_225a () {
17252         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17253         if [ -z ${MDSSURVEY} ]; then
17254                 skip_env "mds-survey not found"
17255         fi
17256         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
17257                 skip "Need MDS version at least 2.2.51"
17258
17259         local mds=$(facet_host $SINGLEMDS)
17260         local target=$(do_nodes $mds 'lctl dl' |
17261                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17262
17263         local cmd1="file_count=1000 thrhi=4"
17264         local cmd2="dir_count=2 layer=mdd stripe_count=0"
17265         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17266         local cmd="$cmd1 $cmd2 $cmd3"
17267
17268         rm -f ${TMP}/mds_survey*
17269         echo + $cmd
17270         eval $cmd || error "mds-survey with zero-stripe failed"
17271         cat ${TMP}/mds_survey*
17272         rm -f ${TMP}/mds_survey*
17273 }
17274 run_test 225a "Metadata survey sanity with zero-stripe"
17275
17276 test_225b () {
17277         if [ -z ${MDSSURVEY} ]; then
17278                 skip_env "mds-survey not found"
17279         fi
17280         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
17281                 skip "Need MDS version at least 2.2.51"
17282         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17283         remote_mds_nodsh && skip "remote MDS with nodsh"
17284         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
17285                 skip_env "Need to mount OST to test"
17286         fi
17287
17288         local mds=$(facet_host $SINGLEMDS)
17289         local target=$(do_nodes $mds 'lctl dl' |
17290                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17291
17292         local cmd1="file_count=1000 thrhi=4"
17293         local cmd2="dir_count=2 layer=mdd stripe_count=1"
17294         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17295         local cmd="$cmd1 $cmd2 $cmd3"
17296
17297         rm -f ${TMP}/mds_survey*
17298         echo + $cmd
17299         eval $cmd || error "mds-survey with stripe_count failed"
17300         cat ${TMP}/mds_survey*
17301         rm -f ${TMP}/mds_survey*
17302 }
17303 run_test 225b "Metadata survey sanity with stripe_count = 1"
17304
17305 mcreate_path2fid () {
17306         local mode=$1
17307         local major=$2
17308         local minor=$3
17309         local name=$4
17310         local desc=$5
17311         local path=$DIR/$tdir/$name
17312         local fid
17313         local rc
17314         local fid_path
17315
17316         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
17317                 error "cannot create $desc"
17318
17319         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
17320         rc=$?
17321         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
17322
17323         fid_path=$($LFS fid2path $MOUNT $fid)
17324         rc=$?
17325         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
17326
17327         [ "$path" == "$fid_path" ] ||
17328                 error "fid2path returned $fid_path, expected $path"
17329
17330         echo "pass with $path and $fid"
17331 }
17332
17333 test_226a () {
17334         rm -rf $DIR/$tdir
17335         mkdir -p $DIR/$tdir
17336
17337         mcreate_path2fid 0010666 0 0 fifo "FIFO"
17338         mcreate_path2fid 0020666 1 3 null "character special file (null)"
17339         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
17340         mcreate_path2fid 0040666 0 0 dir "directory"
17341         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
17342         mcreate_path2fid 0100666 0 0 file "regular file"
17343         mcreate_path2fid 0120666 0 0 link "symbolic link"
17344         mcreate_path2fid 0140666 0 0 sock "socket"
17345 }
17346 run_test 226a "call path2fid and fid2path on files of all type"
17347
17348 test_226b () {
17349         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17350
17351         local MDTIDX=1
17352
17353         rm -rf $DIR/$tdir
17354         mkdir -p $DIR/$tdir
17355         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
17356                 error "create remote directory failed"
17357         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
17358         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
17359                                 "character special file (null)"
17360         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
17361                                 "character special file (no device)"
17362         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
17363         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
17364                                 "block special file (loop)"
17365         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
17366         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
17367         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
17368 }
17369 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
17370
17371 test_226c () {
17372         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17373         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
17374                 skip "Need MDS version at least 2.13.55"
17375
17376         local submnt=/mnt/submnt
17377         local srcfile=/etc/passwd
17378         local dstfile=$submnt/passwd
17379         local path
17380         local fid
17381
17382         rm -rf $DIR/$tdir
17383         rm -rf $submnt
17384         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
17385                 error "create remote directory failed"
17386         mkdir -p $submnt || error "create $submnt failed"
17387         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
17388                 error "mount $submnt failed"
17389         stack_trap "umount $submnt" EXIT
17390
17391         cp $srcfile $dstfile
17392         fid=$($LFS path2fid $dstfile)
17393         path=$($LFS fid2path $submnt "$fid")
17394         [ "$path" = "$dstfile" ] ||
17395                 error "fid2path $submnt $fid failed ($path != $dstfile)"
17396 }
17397 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
17398
17399 # LU-1299 Executing or running ldd on a truncated executable does not
17400 # cause an out-of-memory condition.
17401 test_227() {
17402         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17403         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
17404
17405         dd if=$(which date) of=$MOUNT/date bs=1k count=1
17406         chmod +x $MOUNT/date
17407
17408         $MOUNT/date > /dev/null
17409         ldd $MOUNT/date > /dev/null
17410         rm -f $MOUNT/date
17411 }
17412 run_test 227 "running truncated executable does not cause OOM"
17413
17414 # LU-1512 try to reuse idle OI blocks
17415 test_228a() {
17416         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17417         remote_mds_nodsh && skip "remote MDS with nodsh"
17418         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17419
17420         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17421         local myDIR=$DIR/$tdir
17422
17423         mkdir -p $myDIR
17424         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17425         $LCTL set_param fail_loc=0x80001002
17426         createmany -o $myDIR/t- 10000
17427         $LCTL set_param fail_loc=0
17428         # The guard is current the largest FID holder
17429         touch $myDIR/guard
17430         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17431                     tr -d '[')
17432         local IDX=$(($SEQ % 64))
17433
17434         do_facet $SINGLEMDS sync
17435         # Make sure journal flushed.
17436         sleep 6
17437         local blk1=$(do_facet $SINGLEMDS \
17438                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17439                      grep Blockcount | awk '{print $4}')
17440
17441         # Remove old files, some OI blocks will become idle.
17442         unlinkmany $myDIR/t- 10000
17443         # Create new files, idle OI blocks should be reused.
17444         createmany -o $myDIR/t- 2000
17445         do_facet $SINGLEMDS sync
17446         # Make sure journal flushed.
17447         sleep 6
17448         local blk2=$(do_facet $SINGLEMDS \
17449                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17450                      grep Blockcount | awk '{print $4}')
17451
17452         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17453 }
17454 run_test 228a "try to reuse idle OI blocks"
17455
17456 test_228b() {
17457         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17458         remote_mds_nodsh && skip "remote MDS with nodsh"
17459         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17460
17461         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17462         local myDIR=$DIR/$tdir
17463
17464         mkdir -p $myDIR
17465         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17466         $LCTL set_param fail_loc=0x80001002
17467         createmany -o $myDIR/t- 10000
17468         $LCTL set_param fail_loc=0
17469         # The guard is current the largest FID holder
17470         touch $myDIR/guard
17471         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17472                     tr -d '[')
17473         local IDX=$(($SEQ % 64))
17474
17475         do_facet $SINGLEMDS sync
17476         # Make sure journal flushed.
17477         sleep 6
17478         local blk1=$(do_facet $SINGLEMDS \
17479                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17480                      grep Blockcount | awk '{print $4}')
17481
17482         # Remove old files, some OI blocks will become idle.
17483         unlinkmany $myDIR/t- 10000
17484
17485         # stop the MDT
17486         stop $SINGLEMDS || error "Fail to stop MDT."
17487         # remount the MDT
17488         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
17489
17490         df $MOUNT || error "Fail to df."
17491         # Create new files, idle OI blocks should be reused.
17492         createmany -o $myDIR/t- 2000
17493         do_facet $SINGLEMDS sync
17494         # Make sure journal flushed.
17495         sleep 6
17496         local blk2=$(do_facet $SINGLEMDS \
17497                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17498                      grep Blockcount | awk '{print $4}')
17499
17500         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17501 }
17502 run_test 228b "idle OI blocks can be reused after MDT restart"
17503
17504 #LU-1881
17505 test_228c() {
17506         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17507         remote_mds_nodsh && skip "remote MDS with nodsh"
17508         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17509
17510         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17511         local myDIR=$DIR/$tdir
17512
17513         mkdir -p $myDIR
17514         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17515         $LCTL set_param fail_loc=0x80001002
17516         # 20000 files can guarantee there are index nodes in the OI file
17517         createmany -o $myDIR/t- 20000
17518         $LCTL set_param fail_loc=0
17519         # The guard is current the largest FID holder
17520         touch $myDIR/guard
17521         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17522                     tr -d '[')
17523         local IDX=$(($SEQ % 64))
17524
17525         do_facet $SINGLEMDS sync
17526         # Make sure journal flushed.
17527         sleep 6
17528         local blk1=$(do_facet $SINGLEMDS \
17529                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17530                      grep Blockcount | awk '{print $4}')
17531
17532         # Remove old files, some OI blocks will become idle.
17533         unlinkmany $myDIR/t- 20000
17534         rm -f $myDIR/guard
17535         # The OI file should become empty now
17536
17537         # Create new files, idle OI blocks should be reused.
17538         createmany -o $myDIR/t- 2000
17539         do_facet $SINGLEMDS sync
17540         # Make sure journal flushed.
17541         sleep 6
17542         local blk2=$(do_facet $SINGLEMDS \
17543                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17544                      grep Blockcount | awk '{print $4}')
17545
17546         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17547 }
17548 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
17549
17550 test_229() { # LU-2482, LU-3448
17551         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17552         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
17553         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
17554                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
17555
17556         rm -f $DIR/$tfile
17557
17558         # Create a file with a released layout and stripe count 2.
17559         $MULTIOP $DIR/$tfile H2c ||
17560                 error "failed to create file with released layout"
17561
17562         $LFS getstripe -v $DIR/$tfile
17563
17564         local pattern=$($LFS getstripe -L $DIR/$tfile)
17565         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
17566
17567         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
17568                 error "getstripe"
17569         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
17570         stat $DIR/$tfile || error "failed to stat released file"
17571
17572         chown $RUNAS_ID $DIR/$tfile ||
17573                 error "chown $RUNAS_ID $DIR/$tfile failed"
17574
17575         chgrp $RUNAS_ID $DIR/$tfile ||
17576                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
17577
17578         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
17579         rm $DIR/$tfile || error "failed to remove released file"
17580 }
17581 run_test 229 "getstripe/stat/rm/attr changes work on released files"
17582
17583 test_230a() {
17584         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17585         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17586         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17587                 skip "Need MDS version at least 2.11.52"
17588
17589         local MDTIDX=1
17590
17591         test_mkdir $DIR/$tdir
17592         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
17593         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
17594         [ $mdt_idx -ne 0 ] &&
17595                 error "create local directory on wrong MDT $mdt_idx"
17596
17597         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
17598                         error "create remote directory failed"
17599         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
17600         [ $mdt_idx -ne $MDTIDX ] &&
17601                 error "create remote directory on wrong MDT $mdt_idx"
17602
17603         createmany -o $DIR/$tdir/test_230/t- 10 ||
17604                 error "create files on remote directory failed"
17605         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
17606         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
17607         rm -r $DIR/$tdir || error "unlink remote directory failed"
17608 }
17609 run_test 230a "Create remote directory and files under the remote directory"
17610
17611 test_230b() {
17612         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17613         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17614         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17615                 skip "Need MDS version at least 2.11.52"
17616
17617         local MDTIDX=1
17618         local mdt_index
17619         local i
17620         local file
17621         local pid
17622         local stripe_count
17623         local migrate_dir=$DIR/$tdir/migrate_dir
17624         local other_dir=$DIR/$tdir/other_dir
17625
17626         test_mkdir $DIR/$tdir
17627         test_mkdir -i0 -c1 $migrate_dir
17628         test_mkdir -i0 -c1 $other_dir
17629         for ((i=0; i<10; i++)); do
17630                 mkdir -p $migrate_dir/dir_${i}
17631                 createmany -o $migrate_dir/dir_${i}/f 10 ||
17632                         error "create files under remote dir failed $i"
17633         done
17634
17635         cp /etc/passwd $migrate_dir/$tfile
17636         cp /etc/passwd $other_dir/$tfile
17637         chattr +SAD $migrate_dir
17638         chattr +SAD $migrate_dir/$tfile
17639
17640         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17641         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17642         local old_dir_mode=$(stat -c%f $migrate_dir)
17643         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
17644
17645         mkdir -p $migrate_dir/dir_default_stripe2
17646         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
17647         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
17648
17649         mkdir -p $other_dir
17650         ln $migrate_dir/$tfile $other_dir/luna
17651         ln $migrate_dir/$tfile $migrate_dir/sofia
17652         ln $other_dir/$tfile $migrate_dir/david
17653         ln -s $migrate_dir/$tfile $other_dir/zachary
17654         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
17655         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
17656
17657         local len
17658         local lnktgt
17659
17660         # inline symlink
17661         for len in 58 59 60; do
17662                 lnktgt=$(str_repeat 'l' $len)
17663                 touch $migrate_dir/$lnktgt
17664                 ln -s $lnktgt $migrate_dir/${len}char_ln
17665         done
17666
17667         # PATH_MAX
17668         for len in 4094 4095; do
17669                 lnktgt=$(str_repeat 'l' $len)
17670                 ln -s $lnktgt $migrate_dir/${len}char_ln
17671         done
17672
17673         # NAME_MAX
17674         for len in 254 255; do
17675                 touch $migrate_dir/$(str_repeat 'l' $len)
17676         done
17677
17678         $LFS migrate -m $MDTIDX $migrate_dir ||
17679                 error "fails on migrating remote dir to MDT1"
17680
17681         echo "migratate to MDT1, then checking.."
17682         for ((i = 0; i < 10; i++)); do
17683                 for file in $(find $migrate_dir/dir_${i}); do
17684                         mdt_index=$($LFS getstripe -m $file)
17685                         # broken symlink getstripe will fail
17686                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
17687                                 error "$file is not on MDT${MDTIDX}"
17688                 done
17689         done
17690
17691         # the multiple link file should still in MDT0
17692         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
17693         [ $mdt_index == 0 ] ||
17694                 error "$file is not on MDT${MDTIDX}"
17695
17696         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17697         [ "$old_dir_flag" = "$new_dir_flag" ] ||
17698                 error " expect $old_dir_flag get $new_dir_flag"
17699
17700         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17701         [ "$old_file_flag" = "$new_file_flag" ] ||
17702                 error " expect $old_file_flag get $new_file_flag"
17703
17704         local new_dir_mode=$(stat -c%f $migrate_dir)
17705         [ "$old_dir_mode" = "$new_dir_mode" ] ||
17706                 error "expect mode $old_dir_mode get $new_dir_mode"
17707
17708         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
17709         [ "$old_file_mode" = "$new_file_mode" ] ||
17710                 error "expect mode $old_file_mode get $new_file_mode"
17711
17712         diff /etc/passwd $migrate_dir/$tfile ||
17713                 error "$tfile different after migration"
17714
17715         diff /etc/passwd $other_dir/luna ||
17716                 error "luna different after migration"
17717
17718         diff /etc/passwd $migrate_dir/sofia ||
17719                 error "sofia different after migration"
17720
17721         diff /etc/passwd $migrate_dir/david ||
17722                 error "david different after migration"
17723
17724         diff /etc/passwd $other_dir/zachary ||
17725                 error "zachary different after migration"
17726
17727         diff /etc/passwd $migrate_dir/${tfile}_ln ||
17728                 error "${tfile}_ln different after migration"
17729
17730         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
17731                 error "${tfile}_ln_other different after migration"
17732
17733         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
17734         [ $stripe_count = 2 ] ||
17735                 error "dir strpe_count $d != 2 after migration."
17736
17737         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
17738         [ $stripe_count = 2 ] ||
17739                 error "file strpe_count $d != 2 after migration."
17740
17741         #migrate back to MDT0
17742         MDTIDX=0
17743
17744         $LFS migrate -m $MDTIDX $migrate_dir ||
17745                 error "fails on migrating remote dir to MDT0"
17746
17747         echo "migrate back to MDT0, checking.."
17748         for file in $(find $migrate_dir); do
17749                 mdt_index=$($LFS getstripe -m $file)
17750                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
17751                         error "$file is not on MDT${MDTIDX}"
17752         done
17753
17754         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17755         [ "$old_dir_flag" = "$new_dir_flag" ] ||
17756                 error " expect $old_dir_flag get $new_dir_flag"
17757
17758         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17759         [ "$old_file_flag" = "$new_file_flag" ] ||
17760                 error " expect $old_file_flag get $new_file_flag"
17761
17762         local new_dir_mode=$(stat -c%f $migrate_dir)
17763         [ "$old_dir_mode" = "$new_dir_mode" ] ||
17764                 error "expect mode $old_dir_mode get $new_dir_mode"
17765
17766         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
17767         [ "$old_file_mode" = "$new_file_mode" ] ||
17768                 error "expect mode $old_file_mode get $new_file_mode"
17769
17770         diff /etc/passwd ${migrate_dir}/$tfile ||
17771                 error "$tfile different after migration"
17772
17773         diff /etc/passwd ${other_dir}/luna ||
17774                 error "luna different after migration"
17775
17776         diff /etc/passwd ${migrate_dir}/sofia ||
17777                 error "sofia different after migration"
17778
17779         diff /etc/passwd ${other_dir}/zachary ||
17780                 error "zachary different after migration"
17781
17782         diff /etc/passwd $migrate_dir/${tfile}_ln ||
17783                 error "${tfile}_ln different after migration"
17784
17785         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
17786                 error "${tfile}_ln_other different after migration"
17787
17788         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
17789         [ $stripe_count = 2 ] ||
17790                 error "dir strpe_count $d != 2 after migration."
17791
17792         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
17793         [ $stripe_count = 2 ] ||
17794                 error "file strpe_count $d != 2 after migration."
17795
17796         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17797 }
17798 run_test 230b "migrate directory"
17799
17800 test_230c() {
17801         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17802         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17803         remote_mds_nodsh && skip "remote MDS with nodsh"
17804         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17805                 skip "Need MDS version at least 2.11.52"
17806
17807         local MDTIDX=1
17808         local total=3
17809         local mdt_index
17810         local file
17811         local migrate_dir=$DIR/$tdir/migrate_dir
17812
17813         #If migrating directory fails in the middle, all entries of
17814         #the directory is still accessiable.
17815         test_mkdir $DIR/$tdir
17816         test_mkdir -i0 -c1 $migrate_dir
17817         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
17818         stat $migrate_dir
17819         createmany -o $migrate_dir/f $total ||
17820                 error "create files under ${migrate_dir} failed"
17821
17822         # fail after migrating top dir, and this will fail only once, so the
17823         # first sub file migration will fail (currently f3), others succeed.
17824         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
17825         do_facet mds1 lctl set_param fail_loc=0x1801
17826         local t=$(ls $migrate_dir | wc -l)
17827         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
17828                 error "migrate should fail"
17829         local u=$(ls $migrate_dir | wc -l)
17830         [ "$u" == "$t" ] || error "$u != $t during migration"
17831
17832         # add new dir/file should succeed
17833         mkdir $migrate_dir/dir ||
17834                 error "mkdir failed under migrating directory"
17835         touch $migrate_dir/file ||
17836                 error "create file failed under migrating directory"
17837
17838         # add file with existing name should fail
17839         for file in $migrate_dir/f*; do
17840                 stat $file > /dev/null || error "stat $file failed"
17841                 $OPENFILE -f O_CREAT:O_EXCL $file &&
17842                         error "open(O_CREAT|O_EXCL) $file should fail"
17843                 $MULTIOP $file m && error "create $file should fail"
17844                 touch $DIR/$tdir/remote_dir/$tfile ||
17845                         error "touch $tfile failed"
17846                 ln $DIR/$tdir/remote_dir/$tfile $file &&
17847                         error "link $file should fail"
17848                 mdt_index=$($LFS getstripe -m $file)
17849                 if [ $mdt_index == 0 ]; then
17850                         # file failed to migrate is not allowed to rename to
17851                         mv $DIR/$tdir/remote_dir/$tfile $file &&
17852                                 error "rename to $file should fail"
17853                 else
17854                         mv $DIR/$tdir/remote_dir/$tfile $file ||
17855                                 error "rename to $file failed"
17856                 fi
17857                 echo hello >> $file || error "write $file failed"
17858         done
17859
17860         # resume migration with different options should fail
17861         $LFS migrate -m 0 $migrate_dir &&
17862                 error "migrate -m 0 $migrate_dir should fail"
17863
17864         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
17865                 error "migrate -c 2 $migrate_dir should fail"
17866
17867         # resume migration should succeed
17868         $LFS migrate -m $MDTIDX $migrate_dir ||
17869                 error "migrate $migrate_dir failed"
17870
17871         echo "Finish migration, then checking.."
17872         for file in $(find $migrate_dir); do
17873                 mdt_index=$($LFS getstripe -m $file)
17874                 [ $mdt_index == $MDTIDX ] ||
17875                         error "$file is not on MDT${MDTIDX}"
17876         done
17877
17878         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17879 }
17880 run_test 230c "check directory accessiblity if migration failed"
17881
17882 test_230d() {
17883         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17884         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17885         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17886                 skip "Need MDS version at least 2.11.52"
17887         # LU-11235
17888         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
17889
17890         local migrate_dir=$DIR/$tdir/migrate_dir
17891         local old_index
17892         local new_index
17893         local old_count
17894         local new_count
17895         local new_hash
17896         local mdt_index
17897         local i
17898         local j
17899
17900         old_index=$((RANDOM % MDSCOUNT))
17901         old_count=$((MDSCOUNT - old_index))
17902         new_index=$((RANDOM % MDSCOUNT))
17903         new_count=$((MDSCOUNT - new_index))
17904         new_hash=1 # for all_char
17905
17906         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
17907         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
17908
17909         test_mkdir $DIR/$tdir
17910         test_mkdir -i $old_index -c $old_count $migrate_dir
17911
17912         for ((i=0; i<100; i++)); do
17913                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
17914                 createmany -o $migrate_dir/dir_${i}/f 100 ||
17915                         error "create files under remote dir failed $i"
17916         done
17917
17918         echo -n "Migrate from MDT$old_index "
17919         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
17920         echo -n "to MDT$new_index"
17921         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
17922         echo
17923
17924         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
17925         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
17926                 error "migrate remote dir error"
17927
17928         echo "Finish migration, then checking.."
17929         for file in $(find $migrate_dir); do
17930                 mdt_index=$($LFS getstripe -m $file)
17931                 if [ $mdt_index -lt $new_index ] ||
17932                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
17933                         error "$file is on MDT$mdt_index"
17934                 fi
17935         done
17936
17937         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17938 }
17939 run_test 230d "check migrate big directory"
17940
17941 test_230e() {
17942         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17943         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17944         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17945                 skip "Need MDS version at least 2.11.52"
17946
17947         local i
17948         local j
17949         local a_fid
17950         local b_fid
17951
17952         mkdir -p $DIR/$tdir
17953         mkdir $DIR/$tdir/migrate_dir
17954         mkdir $DIR/$tdir/other_dir
17955         touch $DIR/$tdir/migrate_dir/a
17956         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
17957         ls $DIR/$tdir/other_dir
17958
17959         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
17960                 error "migrate dir fails"
17961
17962         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
17963         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
17964
17965         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17966         [ $mdt_index == 0 ] || error "a is not on MDT0"
17967
17968         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
17969                 error "migrate dir fails"
17970
17971         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
17972         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
17973
17974         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17975         [ $mdt_index == 1 ] || error "a is not on MDT1"
17976
17977         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
17978         [ $mdt_index == 1 ] || error "b is not on MDT1"
17979
17980         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
17981         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
17982
17983         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
17984
17985         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17986 }
17987 run_test 230e "migrate mulitple local link files"
17988
17989 test_230f() {
17990         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17991         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17992         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17993                 skip "Need MDS version at least 2.11.52"
17994
17995         local a_fid
17996         local ln_fid
17997
17998         mkdir -p $DIR/$tdir
17999         mkdir $DIR/$tdir/migrate_dir
18000         $LFS mkdir -i1 $DIR/$tdir/other_dir
18001         touch $DIR/$tdir/migrate_dir/a
18002         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
18003         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
18004         ls $DIR/$tdir/other_dir
18005
18006         # a should be migrated to MDT1, since no other links on MDT0
18007         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18008                 error "#1 migrate dir fails"
18009         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
18010         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
18011         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18012         [ $mdt_index == 1 ] || error "a is not on MDT1"
18013
18014         # a should stay on MDT1, because it is a mulitple link file
18015         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
18016                 error "#2 migrate dir fails"
18017         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18018         [ $mdt_index == 1 ] || error "a is not on MDT1"
18019
18020         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18021                 error "#3 migrate dir fails"
18022
18023         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
18024         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
18025         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
18026
18027         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
18028         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
18029
18030         # a should be migrated to MDT0, since no other links on MDT1
18031         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
18032                 error "#4 migrate dir fails"
18033         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18034         [ $mdt_index == 0 ] || error "a is not on MDT0"
18035
18036         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18037 }
18038 run_test 230f "migrate mulitple remote link files"
18039
18040 test_230g() {
18041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18042         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18043         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18044                 skip "Need MDS version at least 2.11.52"
18045
18046         mkdir -p $DIR/$tdir/migrate_dir
18047
18048         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
18049                 error "migrating dir to non-exist MDT succeeds"
18050         true
18051 }
18052 run_test 230g "migrate dir to non-exist MDT"
18053
18054 test_230h() {
18055         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18056         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18057         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18058                 skip "Need MDS version at least 2.11.52"
18059
18060         local mdt_index
18061
18062         mkdir -p $DIR/$tdir/migrate_dir
18063
18064         $LFS migrate -m1 $DIR &&
18065                 error "migrating mountpoint1 should fail"
18066
18067         $LFS migrate -m1 $DIR/$tdir/.. &&
18068                 error "migrating mountpoint2 should fail"
18069
18070         # same as mv
18071         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
18072                 error "migrating $tdir/migrate_dir/.. should fail"
18073
18074         true
18075 }
18076 run_test 230h "migrate .. and root"
18077
18078 test_230i() {
18079         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18080         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18081         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18082                 skip "Need MDS version at least 2.11.52"
18083
18084         mkdir -p $DIR/$tdir/migrate_dir
18085
18086         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
18087                 error "migration fails with a tailing slash"
18088
18089         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
18090                 error "migration fails with two tailing slashes"
18091 }
18092 run_test 230i "lfs migrate -m tolerates trailing slashes"
18093
18094 test_230j() {
18095         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18096         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
18097                 skip "Need MDS version at least 2.11.52"
18098
18099         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
18100         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
18101                 error "create $tfile failed"
18102         cat /etc/passwd > $DIR/$tdir/$tfile
18103
18104         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
18105
18106         cmp /etc/passwd $DIR/$tdir/$tfile ||
18107                 error "DoM file mismatch after migration"
18108 }
18109 run_test 230j "DoM file data not changed after dir migration"
18110
18111 test_230k() {
18112         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
18113         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18114                 skip "Need MDS version at least 2.11.56"
18115
18116         local total=20
18117         local files_on_starting_mdt=0
18118
18119         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
18120         $LFS getdirstripe $DIR/$tdir
18121         for i in $(seq $total); do
18122                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
18123                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
18124                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18125         done
18126
18127         echo "$files_on_starting_mdt files on MDT0"
18128
18129         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
18130         $LFS getdirstripe $DIR/$tdir
18131
18132         files_on_starting_mdt=0
18133         for i in $(seq $total); do
18134                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
18135                         error "file $tfile.$i mismatch after migration"
18136                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
18137                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18138         done
18139
18140         echo "$files_on_starting_mdt files on MDT1 after migration"
18141         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
18142
18143         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
18144         $LFS getdirstripe $DIR/$tdir
18145
18146         files_on_starting_mdt=0
18147         for i in $(seq $total); do
18148                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
18149                         error "file $tfile.$i mismatch after 2nd migration"
18150                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
18151                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18152         done
18153
18154         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
18155         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
18156
18157         true
18158 }
18159 run_test 230k "file data not changed after dir migration"
18160
18161 test_230l() {
18162         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18163         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18164                 skip "Need MDS version at least 2.11.56"
18165
18166         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
18167         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
18168                 error "create files under remote dir failed $i"
18169         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
18170 }
18171 run_test 230l "readdir between MDTs won't crash"
18172
18173 test_230m() {
18174         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18175         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18176                 skip "Need MDS version at least 2.11.56"
18177
18178         local MDTIDX=1
18179         local mig_dir=$DIR/$tdir/migrate_dir
18180         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
18181         local shortstr="b"
18182         local val
18183
18184         echo "Creating files and dirs with xattrs"
18185         test_mkdir $DIR/$tdir
18186         test_mkdir -i0 -c1 $mig_dir
18187         mkdir $mig_dir/dir
18188         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
18189                 error "cannot set xattr attr1 on dir"
18190         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
18191                 error "cannot set xattr attr2 on dir"
18192         touch $mig_dir/dir/f0
18193         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
18194                 error "cannot set xattr attr1 on file"
18195         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
18196                 error "cannot set xattr attr2 on file"
18197         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18198         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18199         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
18200         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18201         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
18202         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18203         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
18204         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18205         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
18206
18207         echo "Migrating to MDT1"
18208         $LFS migrate -m $MDTIDX $mig_dir ||
18209                 error "fails on migrating dir to MDT1"
18210
18211         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18212         echo "Checking xattrs"
18213         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18214         [ "$val" = $longstr ] ||
18215                 error "expecting xattr1 $longstr on dir, found $val"
18216         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18217         [ "$val" = $shortstr ] ||
18218                 error "expecting xattr2 $shortstr on dir, found $val"
18219         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18220         [ "$val" = $longstr ] ||
18221                 error "expecting xattr1 $longstr on file, found $val"
18222         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18223         [ "$val" = $shortstr ] ||
18224                 error "expecting xattr2 $shortstr on file, found $val"
18225 }
18226 run_test 230m "xattrs not changed after dir migration"
18227
18228 test_230n() {
18229         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18230         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
18231                 skip "Need MDS version at least 2.13.53"
18232
18233         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
18234         cat /etc/hosts > $DIR/$tdir/$tfile
18235         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
18236         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
18237
18238         cmp /etc/hosts $DIR/$tdir/$tfile ||
18239                 error "File data mismatch after migration"
18240 }
18241 run_test 230n "Dir migration with mirrored file"
18242
18243 test_230o() {
18244         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18245         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18246                 skip "Need MDS version at least 2.13.52"
18247
18248         local mdts=$(comma_list $(mdts_nodes))
18249         local timeout=100
18250
18251         local restripe_status
18252         local delta
18253         local i
18254         local j
18255
18256         [[ $(facet_fstype mds1) == zfs ]] && timeout=300
18257
18258         # in case "crush" hash type is not set
18259         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18260
18261         restripe_status=$(do_facet mds1 $LCTL get_param -n \
18262                            mdt.*MDT0000.enable_dir_restripe)
18263         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
18264         stack_trap "do_nodes $mdts $LCTL set_param \
18265                     mdt.*.enable_dir_restripe=$restripe_status"
18266
18267         mkdir $DIR/$tdir
18268         createmany -m $DIR/$tdir/f 100 ||
18269                 error "create files under remote dir failed $i"
18270         createmany -d $DIR/$tdir/d 100 ||
18271                 error "create dirs under remote dir failed $i"
18272
18273         for i in $(seq 2 $MDSCOUNT); do
18274                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
18275                 $LFS setdirstripe -c $i $DIR/$tdir ||
18276                         error "split -c $i $tdir failed"
18277                 wait_update $HOSTNAME \
18278                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
18279                         error "dir split not finished"
18280                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18281                         awk '/migrate/ {sum += $2} END { print sum }')
18282                 echo "$delta files migrated when dir split from $((i - 1)) to $i stripes"
18283                 # delta is around total_files/stripe_count
18284                 [ $delta -lt $((200 /(i - 1))) ] ||
18285                         error "$delta files migrated"
18286         done
18287 }
18288 run_test 230o "dir split"
18289
18290 test_230p() {
18291         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18292         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18293                 skip "Need MDS version at least 2.13.52"
18294
18295         local mdts=$(comma_list $(mdts_nodes))
18296         local timeout=100
18297
18298         local restripe_status
18299         local delta
18300         local i
18301         local j
18302
18303         [[ $(facet_fstype mds1) == zfs ]] && timeout=300
18304
18305         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18306
18307         restripe_status=$(do_facet mds1 $LCTL get_param -n \
18308                            mdt.*MDT0000.enable_dir_restripe)
18309         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
18310         stack_trap "do_nodes $mdts $LCTL set_param \
18311                     mdt.*.enable_dir_restripe=$restripe_status"
18312
18313         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
18314         createmany -m $DIR/$tdir/f 100 ||
18315                 error "create files under remote dir failed $i"
18316         createmany -d $DIR/$tdir/d 100 ||
18317                 error "create dirs under remote dir failed $i"
18318
18319         for i in $(seq $((MDSCOUNT - 1)) -1 1); do
18320                 local mdt_hash="crush"
18321
18322                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
18323                 $LFS setdirstripe -c $i $DIR/$tdir ||
18324                         error "split -c $i $tdir failed"
18325                 [ $i -eq 1 ] && mdt_hash="none"
18326                 wait_update $HOSTNAME \
18327                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
18328                         error "dir merge not finished"
18329                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18330                         awk '/migrate/ {sum += $2} END { print sum }')
18331                 echo "$delta files migrated when dir merge from $((i + 1)) to $i stripes"
18332                 # delta is around total_files/stripe_count
18333                 [ $delta -lt $((200 / i)) ] ||
18334                         error "$delta files migrated"
18335         done
18336 }
18337 run_test 230p "dir merge"
18338
18339 test_230q() {
18340         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18341         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18342                 skip "Need MDS version at least 2.13.52"
18343
18344         local mdts=$(comma_list $(mdts_nodes))
18345         local saved_threshold=$(do_facet mds1 \
18346                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
18347         local saved_delta=$(do_facet mds1 \
18348                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
18349         local threshold=100
18350         local delta=2
18351         local total=0
18352         local stripe_count=0
18353         local stripe_index
18354         local nr_files
18355
18356         stack_trap "do_nodes $mdts $LCTL set_param \
18357                     mdt.*.dir_split_count=$saved_threshold"
18358         stack_trap "do_nodes $mdts $LCTL set_param \
18359                     mdt.*.dir_split_delta=$saved_delta"
18360         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
18361         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
18362         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
18363         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
18364         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
18365         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18366
18367         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
18368         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
18369
18370         while [ $stripe_count -lt $MDSCOUNT ]; do
18371                 createmany -m $DIR/$tdir/f $total $((threshold * 3 / 2)) ||
18372                         error "create sub files failed"
18373                 stat $DIR/$tdir > /dev/null
18374                 total=$((total + threshold * 3 / 2))
18375                 stripe_count=$((stripe_count + delta))
18376                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
18377
18378                 wait_update $HOSTNAME \
18379                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
18380                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
18381
18382                 wait_update $HOSTNAME \
18383                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
18384                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
18385
18386                 nr_files=$($LFS getstripe -m $DIR/$tdir/* |
18387                            grep -w $stripe_index | wc -l)
18388                 echo "$nr_files files on MDT$stripe_index after split"
18389                 [ $nr_files -lt $((total / (stripe_count - 1))) ] ||
18390                         error "$nr_files files on MDT$stripe_index after split"
18391
18392                 nr_files=$(ls $DIR/$tdir | wc -w)
18393                 [ $nr_files -eq $total ] ||
18394                         error "total sub files $nr_files != $total"
18395         done
18396 }
18397 run_test 230q "dir auto split"
18398
18399 test_230r() {
18400         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18401         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
18402         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
18403                 skip "Need MDS version at least 2.13.54"
18404
18405         # maximum amount of local locks:
18406         # parent striped dir - 2 locks
18407         # new stripe in parent to migrate to - 1 lock
18408         # source and target - 2 locks
18409         # Total 5 locks for regular file
18410         mkdir -p $DIR/$tdir
18411         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
18412         touch $DIR/$tdir/dir1/eee
18413
18414         # create 4 hardlink for 4 more locks
18415         # Total: 9 locks > RS_MAX_LOCKS (8)
18416         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
18417         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
18418         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
18419         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
18420         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
18421         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
18422         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
18423         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
18424
18425         cancel_lru_locks mdc
18426
18427         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
18428                 error "migrate dir fails"
18429
18430         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18431 }
18432 run_test 230r "migrate with too many local locks"
18433
18434 test_231a()
18435 {
18436         # For simplicity this test assumes that max_pages_per_rpc
18437         # is the same across all OSCs
18438         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
18439         local bulk_size=$((max_pages * PAGE_SIZE))
18440         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
18441                                        head -n 1)
18442
18443         mkdir -p $DIR/$tdir
18444         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
18445                 error "failed to set stripe with -S ${brw_size}M option"
18446
18447         # clear the OSC stats
18448         $LCTL set_param osc.*.stats=0 &>/dev/null
18449         stop_writeback
18450
18451         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
18452         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
18453                 oflag=direct &>/dev/null || error "dd failed"
18454
18455         sync; sleep 1; sync # just to be safe
18456         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
18457         if [ x$nrpcs != "x1" ]; then
18458                 $LCTL get_param osc.*.stats
18459                 error "found $nrpcs ost_write RPCs, not 1 as expected"
18460         fi
18461
18462         start_writeback
18463         # Drop the OSC cache, otherwise we will read from it
18464         cancel_lru_locks osc
18465
18466         # clear the OSC stats
18467         $LCTL set_param osc.*.stats=0 &>/dev/null
18468
18469         # Client reads $bulk_size.
18470         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
18471                 iflag=direct &>/dev/null || error "dd failed"
18472
18473         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
18474         if [ x$nrpcs != "x1" ]; then
18475                 $LCTL get_param osc.*.stats
18476                 error "found $nrpcs ost_read RPCs, not 1 as expected"
18477         fi
18478 }
18479 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
18480
18481 test_231b() {
18482         mkdir -p $DIR/$tdir
18483         local i
18484         for i in {0..1023}; do
18485                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
18486                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
18487                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
18488         done
18489         sync
18490 }
18491 run_test 231b "must not assert on fully utilized OST request buffer"
18492
18493 test_232a() {
18494         mkdir -p $DIR/$tdir
18495         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
18496
18497         #define OBD_FAIL_LDLM_OST_LVB            0x31c
18498         do_facet ost1 $LCTL set_param fail_loc=0x31c
18499
18500         # ignore dd failure
18501         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
18502
18503         do_facet ost1 $LCTL set_param fail_loc=0
18504         umount_client $MOUNT || error "umount failed"
18505         mount_client $MOUNT || error "mount failed"
18506         stop ost1 || error "cannot stop ost1"
18507         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18508 }
18509 run_test 232a "failed lock should not block umount"
18510
18511 test_232b() {
18512         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
18513                 skip "Need MDS version at least 2.10.58"
18514
18515         mkdir -p $DIR/$tdir
18516         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
18517         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
18518         sync
18519         cancel_lru_locks osc
18520
18521         #define OBD_FAIL_LDLM_OST_LVB            0x31c
18522         do_facet ost1 $LCTL set_param fail_loc=0x31c
18523
18524         # ignore failure
18525         $LFS data_version $DIR/$tdir/$tfile || true
18526
18527         do_facet ost1 $LCTL set_param fail_loc=0
18528         umount_client $MOUNT || error "umount failed"
18529         mount_client $MOUNT || error "mount failed"
18530         stop ost1 || error "cannot stop ost1"
18531         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18532 }
18533 run_test 232b "failed data version lock should not block umount"
18534
18535 test_233a() {
18536         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
18537                 skip "Need MDS version at least 2.3.64"
18538         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
18539
18540         local fid=$($LFS path2fid $MOUNT)
18541
18542         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18543                 error "cannot access $MOUNT using its FID '$fid'"
18544 }
18545 run_test 233a "checking that OBF of the FS root succeeds"
18546
18547 test_233b() {
18548         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
18549                 skip "Need MDS version at least 2.5.90"
18550         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
18551
18552         local fid=$($LFS path2fid $MOUNT/.lustre)
18553
18554         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18555                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
18556
18557         fid=$($LFS path2fid $MOUNT/.lustre/fid)
18558         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18559                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
18560 }
18561 run_test 233b "checking that OBF of the FS .lustre succeeds"
18562
18563 test_234() {
18564         local p="$TMP/sanityN-$TESTNAME.parameters"
18565         save_lustre_params client "llite.*.xattr_cache" > $p
18566         lctl set_param llite.*.xattr_cache 1 ||
18567                 skip_env "xattr cache is not supported"
18568
18569         mkdir -p $DIR/$tdir || error "mkdir failed"
18570         touch $DIR/$tdir/$tfile || error "touch failed"
18571         # OBD_FAIL_LLITE_XATTR_ENOMEM
18572         $LCTL set_param fail_loc=0x1405
18573         getfattr -n user.attr $DIR/$tdir/$tfile &&
18574                 error "getfattr should have failed with ENOMEM"
18575         $LCTL set_param fail_loc=0x0
18576         rm -rf $DIR/$tdir
18577
18578         restore_lustre_params < $p
18579         rm -f $p
18580 }
18581 run_test 234 "xattr cache should not crash on ENOMEM"
18582
18583 test_235() {
18584         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
18585                 skip "Need MDS version at least 2.4.52"
18586
18587         flock_deadlock $DIR/$tfile
18588         local RC=$?
18589         case $RC in
18590                 0)
18591                 ;;
18592                 124) error "process hangs on a deadlock"
18593                 ;;
18594                 *) error "error executing flock_deadlock $DIR/$tfile"
18595                 ;;
18596         esac
18597 }
18598 run_test 235 "LU-1715: flock deadlock detection does not work properly"
18599
18600 #LU-2935
18601 test_236() {
18602         check_swap_layouts_support
18603
18604         local ref1=/etc/passwd
18605         local ref2=/etc/group
18606         local file1=$DIR/$tdir/f1
18607         local file2=$DIR/$tdir/f2
18608
18609         test_mkdir -c1 $DIR/$tdir
18610         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
18611         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
18612         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
18613         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
18614         local fd=$(free_fd)
18615         local cmd="exec $fd<>$file2"
18616         eval $cmd
18617         rm $file2
18618         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
18619                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
18620         cmd="exec $fd>&-"
18621         eval $cmd
18622         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
18623
18624         #cleanup
18625         rm -rf $DIR/$tdir
18626 }
18627 run_test 236 "Layout swap on open unlinked file"
18628
18629 # LU-4659 linkea consistency
18630 test_238() {
18631         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
18632                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
18633                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
18634                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
18635
18636         touch $DIR/$tfile
18637         ln $DIR/$tfile $DIR/$tfile.lnk
18638         touch $DIR/$tfile.new
18639         mv $DIR/$tfile.new $DIR/$tfile
18640         local fid1=$($LFS path2fid $DIR/$tfile)
18641         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
18642         local path1=$($LFS fid2path $FSNAME "$fid1")
18643         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
18644         local path2=$($LFS fid2path $FSNAME "$fid2")
18645         [ $tfile.lnk == $path2 ] ||
18646                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
18647         rm -f $DIR/$tfile*
18648 }
18649 run_test 238 "Verify linkea consistency"
18650
18651 test_239A() { # was test_239
18652         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
18653                 skip "Need MDS version at least 2.5.60"
18654
18655         local list=$(comma_list $(mdts_nodes))
18656
18657         mkdir -p $DIR/$tdir
18658         createmany -o $DIR/$tdir/f- 5000
18659         unlinkmany $DIR/$tdir/f- 5000
18660         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
18661                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
18662         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
18663                         osp.*MDT*.sync_in_flight" | calc_sum)
18664         [ "$changes" -eq 0 ] || error "$changes not synced"
18665 }
18666 run_test 239A "osp_sync test"
18667
18668 test_239a() { #LU-5297
18669         remote_mds_nodsh && skip "remote MDS with nodsh"
18670
18671         touch $DIR/$tfile
18672         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
18673         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
18674         chgrp $RUNAS_GID $DIR/$tfile
18675         wait_delete_completed
18676 }
18677 run_test 239a "process invalid osp sync record correctly"
18678
18679 test_239b() { #LU-5297
18680         remote_mds_nodsh && skip "remote MDS with nodsh"
18681
18682         touch $DIR/$tfile1
18683         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
18684         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
18685         chgrp $RUNAS_GID $DIR/$tfile1
18686         wait_delete_completed
18687         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
18688         touch $DIR/$tfile2
18689         chgrp $RUNAS_GID $DIR/$tfile2
18690         wait_delete_completed
18691 }
18692 run_test 239b "process osp sync record with ENOMEM error correctly"
18693
18694 test_240() {
18695         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18696         remote_mds_nodsh && skip "remote MDS with nodsh"
18697
18698         mkdir -p $DIR/$tdir
18699
18700         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
18701                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
18702         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
18703                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
18704
18705         umount_client $MOUNT || error "umount failed"
18706         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
18707         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
18708         mount_client $MOUNT || error "failed to mount client"
18709
18710         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
18711         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
18712 }
18713 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
18714
18715 test_241_bio() {
18716         local count=$1
18717         local bsize=$2
18718
18719         for LOOP in $(seq $count); do
18720                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
18721                 cancel_lru_locks $OSC || true
18722         done
18723 }
18724
18725 test_241_dio() {
18726         local count=$1
18727         local bsize=$2
18728
18729         for LOOP in $(seq $1); do
18730                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
18731                         2>/dev/null
18732         done
18733 }
18734
18735 test_241a() { # was test_241
18736         local bsize=$PAGE_SIZE
18737
18738         (( bsize < 40960 )) && bsize=40960
18739         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
18740         ls -la $DIR/$tfile
18741         cancel_lru_locks $OSC
18742         test_241_bio 1000 $bsize &
18743         PID=$!
18744         test_241_dio 1000 $bsize
18745         wait $PID
18746 }
18747 run_test 241a "bio vs dio"
18748
18749 test_241b() {
18750         local bsize=$PAGE_SIZE
18751
18752         (( bsize < 40960 )) && bsize=40960
18753         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
18754         ls -la $DIR/$tfile
18755         test_241_dio 1000 $bsize &
18756         PID=$!
18757         test_241_dio 1000 $bsize
18758         wait $PID
18759 }
18760 run_test 241b "dio vs dio"
18761
18762 test_242() {
18763         remote_mds_nodsh && skip "remote MDS with nodsh"
18764
18765         mkdir -p $DIR/$tdir
18766         touch $DIR/$tdir/$tfile
18767
18768         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
18769         do_facet mds1 lctl set_param fail_loc=0x105
18770         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
18771
18772         do_facet mds1 lctl set_param fail_loc=0
18773         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
18774 }
18775 run_test 242 "mdt_readpage failure should not cause directory unreadable"
18776
18777 test_243()
18778 {
18779         test_mkdir $DIR/$tdir
18780         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
18781 }
18782 run_test 243 "various group lock tests"
18783
18784 test_244a()
18785 {
18786         test_mkdir $DIR/$tdir
18787         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
18788         sendfile_grouplock $DIR/$tdir/$tfile || \
18789                 error "sendfile+grouplock failed"
18790         rm -rf $DIR/$tdir
18791 }
18792 run_test 244a "sendfile with group lock tests"
18793
18794 test_244b()
18795 {
18796         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
18797
18798         local threads=50
18799         local size=$((1024*1024))
18800
18801         test_mkdir $DIR/$tdir
18802         for i in $(seq 1 $threads); do
18803                 local file=$DIR/$tdir/file_$((i / 10))
18804                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
18805                 local pids[$i]=$!
18806         done
18807         for i in $(seq 1 $threads); do
18808                 wait ${pids[$i]}
18809         done
18810 }
18811 run_test 244b "multi-threaded write with group lock"
18812
18813 test_245() {
18814         local flagname="multi_mod_rpcs"
18815         local connect_data_name="max_mod_rpcs"
18816         local out
18817
18818         # check if multiple modify RPCs flag is set
18819         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
18820                 grep "connect_flags:")
18821         echo "$out"
18822
18823         echo "$out" | grep -qw $flagname
18824         if [ $? -ne 0 ]; then
18825                 echo "connect flag $flagname is not set"
18826                 return
18827         fi
18828
18829         # check if multiple modify RPCs data is set
18830         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
18831         echo "$out"
18832
18833         echo "$out" | grep -qw $connect_data_name ||
18834                 error "import should have connect data $connect_data_name"
18835 }
18836 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
18837
18838 cleanup_247() {
18839         local submount=$1
18840
18841         trap 0
18842         umount_client $submount
18843         rmdir $submount
18844 }
18845
18846 test_247a() {
18847         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
18848                 grep -q subtree ||
18849                 skip_env "Fileset feature is not supported"
18850
18851         local submount=${MOUNT}_$tdir
18852
18853         mkdir $MOUNT/$tdir
18854         mkdir -p $submount || error "mkdir $submount failed"
18855         FILESET="$FILESET/$tdir" mount_client $submount ||
18856                 error "mount $submount failed"
18857         trap "cleanup_247 $submount" EXIT
18858         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
18859         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
18860                 error "read $MOUNT/$tdir/$tfile failed"
18861         cleanup_247 $submount
18862 }
18863 run_test 247a "mount subdir as fileset"
18864
18865 test_247b() {
18866         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18867                 skip_env "Fileset feature is not supported"
18868
18869         local submount=${MOUNT}_$tdir
18870
18871         rm -rf $MOUNT/$tdir
18872         mkdir -p $submount || error "mkdir $submount failed"
18873         SKIP_FILESET=1
18874         FILESET="$FILESET/$tdir" mount_client $submount &&
18875                 error "mount $submount should fail"
18876         rmdir $submount
18877 }
18878 run_test 247b "mount subdir that dose not exist"
18879
18880 test_247c() {
18881         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18882                 skip_env "Fileset feature is not supported"
18883
18884         local submount=${MOUNT}_$tdir
18885
18886         mkdir -p $MOUNT/$tdir/dir1
18887         mkdir -p $submount || error "mkdir $submount failed"
18888         trap "cleanup_247 $submount" EXIT
18889         FILESET="$FILESET/$tdir" mount_client $submount ||
18890                 error "mount $submount failed"
18891         local fid=$($LFS path2fid $MOUNT/)
18892         $LFS fid2path $submount $fid && error "fid2path should fail"
18893         cleanup_247 $submount
18894 }
18895 run_test 247c "running fid2path outside subdirectory root"
18896
18897 test_247d() {
18898         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18899                 skip "Fileset feature is not supported"
18900
18901         local submount=${MOUNT}_$tdir
18902
18903         mkdir -p $MOUNT/$tdir/dir1
18904         mkdir -p $submount || error "mkdir $submount failed"
18905         FILESET="$FILESET/$tdir" mount_client $submount ||
18906                 error "mount $submount failed"
18907         trap "cleanup_247 $submount" EXIT
18908
18909         local td=$submount/dir1
18910         local fid=$($LFS path2fid $td)
18911         [ -z "$fid" ] && error "path2fid unable to get $td FID"
18912
18913         # check that we get the same pathname back
18914         local rootpath
18915         local found
18916         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
18917                 echo "$rootpath $fid"
18918                 found=$($LFS fid2path $rootpath "$fid")
18919                 [ -n "found" ] || error "fid2path should succeed"
18920                 [ "$found" == "$td" ] || error "fid2path $found != $td"
18921         done
18922         # check wrong root path format
18923         rootpath=$submount"_wrong"
18924         found=$($LFS fid2path $rootpath "$fid")
18925         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
18926
18927         cleanup_247 $submount
18928 }
18929 run_test 247d "running fid2path inside subdirectory root"
18930
18931 # LU-8037
18932 test_247e() {
18933         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
18934                 grep -q subtree ||
18935                 skip "Fileset feature is not supported"
18936
18937         local submount=${MOUNT}_$tdir
18938
18939         mkdir $MOUNT/$tdir
18940         mkdir -p $submount || error "mkdir $submount failed"
18941         FILESET="$FILESET/.." mount_client $submount &&
18942                 error "mount $submount should fail"
18943         rmdir $submount
18944 }
18945 run_test 247e "mount .. as fileset"
18946
18947 test_247f() {
18948         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18949         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
18950                 skip "Need at least version 2.13.52"
18951         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
18952                 grep -q subtree ||
18953                 skip "Fileset feature is not supported"
18954
18955         mkdir $DIR/$tdir || error "mkdir $tdir failed"
18956         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
18957                 error "mkdir remote failed"
18958         mkdir $DIR/$tdir/remote/subdir || error "mkdir remote/subdir failed"
18959         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped ||
18960                 error "mkdir striped failed"
18961         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
18962
18963         local submount=${MOUNT}_$tdir
18964
18965         mkdir -p $submount || error "mkdir $submount failed"
18966
18967         local dir
18968         local fileset=$FILESET
18969
18970         for dir in $tdir/remote $tdir/remote/subdir \
18971                    $tdir/striped $tdir/striped/subdir $tdir/striped/. ; do
18972                 FILESET="$fileset/$dir" mount_client $submount ||
18973                         error "mount $dir failed"
18974                 umount_client $submount
18975         done
18976 }
18977 run_test 247f "mount striped or remote directory as fileset"
18978
18979 test_248a() {
18980         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
18981         [ -z "$fast_read_sav" ] && skip "no fast read support"
18982
18983         # create a large file for fast read verification
18984         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
18985
18986         # make sure the file is created correctly
18987         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
18988                 { rm -f $DIR/$tfile; skip "file creation error"; }
18989
18990         echo "Test 1: verify that fast read is 4 times faster on cache read"
18991
18992         # small read with fast read enabled
18993         $LCTL set_param -n llite.*.fast_read=1
18994         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
18995                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
18996                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
18997         # small read with fast read disabled
18998         $LCTL set_param -n llite.*.fast_read=0
18999         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
19000                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19001                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19002
19003         # verify that fast read is 4 times faster for cache read
19004         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
19005                 error_not_in_vm "fast read was not 4 times faster: " \
19006                            "$t_fast vs $t_slow"
19007
19008         echo "Test 2: verify the performance between big and small read"
19009         $LCTL set_param -n llite.*.fast_read=1
19010
19011         # 1k non-cache read
19012         cancel_lru_locks osc
19013         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
19014                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19015                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19016
19017         # 1M non-cache read
19018         cancel_lru_locks osc
19019         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
19020                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19021                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19022
19023         # verify that big IO is not 4 times faster than small IO
19024         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
19025                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
19026
19027         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
19028         rm -f $DIR/$tfile
19029 }
19030 run_test 248a "fast read verification"
19031
19032 test_248b() {
19033         # Default short_io_bytes=16384, try both smaller and larger sizes.
19034         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
19035         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
19036         echo "bs=53248 count=113 normal buffered write"
19037         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
19038                 error "dd of initial data file failed"
19039         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
19040
19041         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
19042         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
19043                 error "dd with sync normal writes failed"
19044         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
19045
19046         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
19047         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
19048                 error "dd with sync small writes failed"
19049         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
19050
19051         cancel_lru_locks osc
19052
19053         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
19054         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
19055         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
19056         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
19057                 iflag=direct || error "dd with O_DIRECT small read failed"
19058         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
19059         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
19060                 error "compare $TMP/$tfile.1 failed"
19061
19062         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
19063         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
19064
19065         # just to see what the maximum tunable value is, and test parsing
19066         echo "test invalid parameter 2MB"
19067         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
19068                 error "too-large short_io_bytes allowed"
19069         echo "test maximum parameter 512KB"
19070         # if we can set a larger short_io_bytes, run test regardless of version
19071         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
19072                 # older clients may not allow setting it this large, that's OK
19073                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
19074                         skip "Need at least client version 2.13.50"
19075                 error "medium short_io_bytes failed"
19076         fi
19077         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
19078         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
19079
19080         echo "test large parameter 64KB"
19081         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
19082         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
19083
19084         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
19085         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
19086                 error "dd with sync large writes failed"
19087         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
19088
19089         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
19090         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
19091         num=$((113 * 4096 / PAGE_SIZE))
19092         echo "bs=$size count=$num oflag=direct large write $tfile.3"
19093         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
19094                 error "dd with O_DIRECT large writes failed"
19095         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
19096                 error "compare $DIR/$tfile.3 failed"
19097
19098         cancel_lru_locks osc
19099
19100         echo "bs=$size count=$num iflag=direct large read $tfile.2"
19101         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
19102                 error "dd with O_DIRECT large read failed"
19103         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
19104                 error "compare $TMP/$tfile.2 failed"
19105
19106         echo "bs=$size count=$num iflag=direct large read $tfile.3"
19107         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
19108                 error "dd with O_DIRECT large read failed"
19109         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
19110                 error "compare $TMP/$tfile.3 failed"
19111 }
19112 run_test 248b "test short_io read and write for both small and large sizes"
19113
19114 test_249() { # LU-7890
19115         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
19116                 skip "Need at least version 2.8.54"
19117
19118         rm -f $DIR/$tfile
19119         $LFS setstripe -c 1 $DIR/$tfile
19120         # Offset 2T == 4k * 512M
19121         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
19122                 error "dd to 2T offset failed"
19123 }
19124 run_test 249 "Write above 2T file size"
19125
19126 test_250() {
19127         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
19128          && skip "no 16TB file size limit on ZFS"
19129
19130         $LFS setstripe -c 1 $DIR/$tfile
19131         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
19132         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
19133         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
19134         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
19135                 conv=notrunc,fsync && error "append succeeded"
19136         return 0
19137 }
19138 run_test 250 "Write above 16T limit"
19139
19140 test_251() {
19141         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
19142
19143         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
19144         #Skip once - writing the first stripe will succeed
19145         $LCTL set_param fail_loc=0xa0001407 fail_val=1
19146         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
19147                 error "short write happened"
19148
19149         $LCTL set_param fail_loc=0xa0001407 fail_val=1
19150         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
19151                 error "short read happened"
19152
19153         rm -f $DIR/$tfile
19154 }
19155 run_test 251 "Handling short read and write correctly"
19156
19157 test_252() {
19158         remote_mds_nodsh && skip "remote MDS with nodsh"
19159         remote_ost_nodsh && skip "remote OST with nodsh"
19160         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
19161                 skip_env "ldiskfs only test"
19162         fi
19163
19164         local tgt
19165         local dev
19166         local out
19167         local uuid
19168         local num
19169         local gen
19170
19171         # check lr_reader on OST0000
19172         tgt=ost1
19173         dev=$(facet_device $tgt)
19174         out=$(do_facet $tgt $LR_READER $dev)
19175         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19176         echo "$out"
19177         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
19178         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
19179                 error "Invalid uuid returned by $LR_READER on target $tgt"
19180         echo -e "uuid returned by $LR_READER is '$uuid'\n"
19181
19182         # check lr_reader -c on MDT0000
19183         tgt=mds1
19184         dev=$(facet_device $tgt)
19185         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
19186                 skip "$LR_READER does not support additional options"
19187         fi
19188         out=$(do_facet $tgt $LR_READER -c $dev)
19189         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19190         echo "$out"
19191         num=$(echo "$out" | grep -c "mdtlov")
19192         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
19193                 error "Invalid number of mdtlov clients returned by $LR_READER"
19194         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
19195
19196         # check lr_reader -cr on MDT0000
19197         out=$(do_facet $tgt $LR_READER -cr $dev)
19198         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19199         echo "$out"
19200         echo "$out" | grep -q "^reply_data:$" ||
19201                 error "$LR_READER should have returned 'reply_data' section"
19202         num=$(echo "$out" | grep -c "client_generation")
19203         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
19204 }
19205 run_test 252 "check lr_reader tool"
19206
19207 test_253() {
19208         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19209         remote_mds_nodsh && skip "remote MDS with nodsh"
19210         remote_mgs_nodsh && skip "remote MGS with nodsh"
19211
19212         local ostidx=0
19213         local rc=0
19214         local ost_name=$(ostname_from_index $ostidx)
19215
19216         # on the mdt's osc
19217         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
19218         do_facet $SINGLEMDS $LCTL get_param -n \
19219                 osp.$mdtosc_proc1.reserved_mb_high ||
19220                 skip  "remote MDS does not support reserved_mb_high"
19221
19222         rm -rf $DIR/$tdir
19223         wait_mds_ost_sync
19224         wait_delete_completed
19225         mkdir $DIR/$tdir
19226
19227         pool_add $TESTNAME || error "Pool creation failed"
19228         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
19229
19230         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
19231                 error "Setstripe failed"
19232
19233         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
19234
19235         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
19236                     grep "watermarks")
19237         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
19238
19239         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
19240                         osp.$mdtosc_proc1.prealloc_status)
19241         echo "prealloc_status $oa_status"
19242
19243         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
19244                 error "File creation should fail"
19245
19246         #object allocation was stopped, but we still able to append files
19247         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
19248                 oflag=append || error "Append failed"
19249
19250         rm -f $DIR/$tdir/$tfile.0
19251
19252         # For this test, we want to delete the files we created to go out of
19253         # space but leave the watermark, so we remain nearly out of space
19254         ost_watermarks_enospc_delete_files $tfile $ostidx
19255
19256         wait_delete_completed
19257
19258         sleep_maxage
19259
19260         for i in $(seq 10 12); do
19261                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
19262                         2>/dev/null || error "File creation failed after rm"
19263         done
19264
19265         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
19266                         osp.$mdtosc_proc1.prealloc_status)
19267         echo "prealloc_status $oa_status"
19268
19269         if (( oa_status != 0 )); then
19270                 error "Object allocation still disable after rm"
19271         fi
19272 }
19273 run_test 253 "Check object allocation limit"
19274
19275 test_254() {
19276         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19277         remote_mds_nodsh && skip "remote MDS with nodsh"
19278         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
19279                 skip "MDS does not support changelog_size"
19280
19281         local cl_user
19282         local MDT0=$(facet_svc $SINGLEMDS)
19283
19284         changelog_register || error "changelog_register failed"
19285
19286         changelog_clear 0 || error "changelog_clear failed"
19287
19288         local size1=$(do_facet $SINGLEMDS \
19289                       $LCTL get_param -n mdd.$MDT0.changelog_size)
19290         echo "Changelog size $size1"
19291
19292         rm -rf $DIR/$tdir
19293         $LFS mkdir -i 0 $DIR/$tdir
19294         # change something
19295         mkdir -p $DIR/$tdir/pics/2008/zachy
19296         touch $DIR/$tdir/pics/2008/zachy/timestamp
19297         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
19298         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
19299         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
19300         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
19301         rm $DIR/$tdir/pics/desktop.jpg
19302
19303         local size2=$(do_facet $SINGLEMDS \
19304                       $LCTL get_param -n mdd.$MDT0.changelog_size)
19305         echo "Changelog size after work $size2"
19306
19307         (( $size2 > $size1 )) ||
19308                 error "new Changelog size=$size2 less than old size=$size1"
19309 }
19310 run_test 254 "Check changelog size"
19311
19312 ladvise_no_type()
19313 {
19314         local type=$1
19315         local file=$2
19316
19317         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
19318                 awk -F: '{print $2}' | grep $type > /dev/null
19319         if [ $? -ne 0 ]; then
19320                 return 0
19321         fi
19322         return 1
19323 }
19324
19325 ladvise_no_ioctl()
19326 {
19327         local file=$1
19328
19329         lfs ladvise -a willread $file > /dev/null 2>&1
19330         if [ $? -eq 0 ]; then
19331                 return 1
19332         fi
19333
19334         lfs ladvise -a willread $file 2>&1 |
19335                 grep "Inappropriate ioctl for device" > /dev/null
19336         if [ $? -eq 0 ]; then
19337                 return 0
19338         fi
19339         return 1
19340 }
19341
19342 percent() {
19343         bc <<<"scale=2; ($1 - $2) * 100 / $2"
19344 }
19345
19346 # run a random read IO workload
19347 # usage: random_read_iops <filename> <filesize> <iosize>
19348 random_read_iops() {
19349         local file=$1
19350         local fsize=$2
19351         local iosize=${3:-4096}
19352
19353         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
19354                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
19355 }
19356
19357 drop_file_oss_cache() {
19358         local file="$1"
19359         local nodes="$2"
19360
19361         $LFS ladvise -a dontneed $file 2>/dev/null ||
19362                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
19363 }
19364
19365 ladvise_willread_performance()
19366 {
19367         local repeat=10
19368         local average_origin=0
19369         local average_cache=0
19370         local average_ladvise=0
19371
19372         for ((i = 1; i <= $repeat; i++)); do
19373                 echo "Iter $i/$repeat: reading without willread hint"
19374                 cancel_lru_locks osc
19375                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
19376                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
19377                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
19378                 average_origin=$(bc <<<"$average_origin + $speed_origin")
19379
19380                 cancel_lru_locks osc
19381                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
19382                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
19383                 average_cache=$(bc <<<"$average_cache + $speed_cache")
19384
19385                 cancel_lru_locks osc
19386                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
19387                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
19388                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
19389                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
19390                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
19391         done
19392         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
19393         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
19394         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
19395
19396         speedup_cache=$(percent $average_cache $average_origin)
19397         speedup_ladvise=$(percent $average_ladvise $average_origin)
19398
19399         echo "Average uncached read: $average_origin"
19400         echo "Average speedup with OSS cached read: " \
19401                 "$average_cache = +$speedup_cache%"
19402         echo "Average speedup with ladvise willread: " \
19403                 "$average_ladvise = +$speedup_ladvise%"
19404
19405         local lowest_speedup=20
19406         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
19407                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
19408                         "got $average_cache%. Skipping ladvise willread check."
19409                 return 0
19410         fi
19411
19412         # the test won't work on ZFS until it supports 'ladvise dontneed', but
19413         # it is still good to run until then to exercise 'ladvise willread'
19414         ! $LFS ladvise -a dontneed $DIR/$tfile &&
19415                 [ "$ost1_FSTYPE" = "zfs" ] &&
19416                 echo "osd-zfs does not support dontneed or drop_caches" &&
19417                 return 0
19418
19419         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
19420         [[ ${average_ladvise%.*} > $lowest_speedup ]] ||
19421                 error_not_in_vm "Speedup with willread is less than " \
19422                         "$lowest_speedup%, got $average_ladvise%"
19423 }
19424
19425 test_255a() {
19426         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
19427                 skip "lustre < 2.8.54 does not support ladvise "
19428         remote_ost_nodsh && skip "remote OST with nodsh"
19429
19430         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
19431
19432         ladvise_no_type willread $DIR/$tfile &&
19433                 skip "willread ladvise is not supported"
19434
19435         ladvise_no_ioctl $DIR/$tfile &&
19436                 skip "ladvise ioctl is not supported"
19437
19438         local size_mb=100
19439         local size=$((size_mb * 1048576))
19440         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
19441                 error "dd to $DIR/$tfile failed"
19442
19443         lfs ladvise -a willread $DIR/$tfile ||
19444                 error "Ladvise failed with no range argument"
19445
19446         lfs ladvise -a willread -s 0 $DIR/$tfile ||
19447                 error "Ladvise failed with no -l or -e argument"
19448
19449         lfs ladvise -a willread -e 1 $DIR/$tfile ||
19450                 error "Ladvise failed with only -e argument"
19451
19452         lfs ladvise -a willread -l 1 $DIR/$tfile ||
19453                 error "Ladvise failed with only -l argument"
19454
19455         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
19456                 error "End offset should not be smaller than start offset"
19457
19458         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
19459                 error "End offset should not be equal to start offset"
19460
19461         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
19462                 error "Ladvise failed with overflowing -s argument"
19463
19464         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
19465                 error "Ladvise failed with overflowing -e argument"
19466
19467         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
19468                 error "Ladvise failed with overflowing -l argument"
19469
19470         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
19471                 error "Ladvise succeeded with conflicting -l and -e arguments"
19472
19473         echo "Synchronous ladvise should wait"
19474         local delay=4
19475 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
19476         do_nodes $(comma_list $(osts_nodes)) \
19477                 $LCTL set_param fail_val=$delay fail_loc=0x237
19478
19479         local start_ts=$SECONDS
19480         lfs ladvise -a willread $DIR/$tfile ||
19481                 error "Ladvise failed with no range argument"
19482         local end_ts=$SECONDS
19483         local inteval_ts=$((end_ts - start_ts))
19484
19485         if [ $inteval_ts -lt $(($delay - 1)) ]; then
19486                 error "Synchronous advice didn't wait reply"
19487         fi
19488
19489         echo "Asynchronous ladvise shouldn't wait"
19490         local start_ts=$SECONDS
19491         lfs ladvise -a willread -b $DIR/$tfile ||
19492                 error "Ladvise failed with no range argument"
19493         local end_ts=$SECONDS
19494         local inteval_ts=$((end_ts - start_ts))
19495
19496         if [ $inteval_ts -gt $(($delay / 2)) ]; then
19497                 error "Asynchronous advice blocked"
19498         fi
19499
19500         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
19501         ladvise_willread_performance
19502 }
19503 run_test 255a "check 'lfs ladvise -a willread'"
19504
19505 facet_meminfo() {
19506         local facet=$1
19507         local info=$2
19508
19509         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
19510 }
19511
19512 test_255b() {
19513         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
19514                 skip "lustre < 2.8.54 does not support ladvise "
19515         remote_ost_nodsh && skip "remote OST with nodsh"
19516
19517         lfs setstripe -c 1 -i 0 $DIR/$tfile
19518
19519         ladvise_no_type dontneed $DIR/$tfile &&
19520                 skip "dontneed ladvise is not supported"
19521
19522         ladvise_no_ioctl $DIR/$tfile &&
19523                 skip "ladvise ioctl is not supported"
19524
19525         ! $LFS ladvise -a dontneed $DIR/$tfile &&
19526                 [ "$ost1_FSTYPE" = "zfs" ] &&
19527                 skip "zfs-osd does not support 'ladvise dontneed'"
19528
19529         local size_mb=100
19530         local size=$((size_mb * 1048576))
19531         # In order to prevent disturbance of other processes, only check 3/4
19532         # of the memory usage
19533         local kibibytes=$((size_mb * 1024 * 3 / 4))
19534
19535         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
19536                 error "dd to $DIR/$tfile failed"
19537
19538         #force write to complete before dropping OST cache & checking memory
19539         sync
19540
19541         local total=$(facet_meminfo ost1 MemTotal)
19542         echo "Total memory: $total KiB"
19543
19544         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
19545         local before_read=$(facet_meminfo ost1 Cached)
19546         echo "Cache used before read: $before_read KiB"
19547
19548         lfs ladvise -a willread $DIR/$tfile ||
19549                 error "Ladvise willread failed"
19550         local after_read=$(facet_meminfo ost1 Cached)
19551         echo "Cache used after read: $after_read KiB"
19552
19553         lfs ladvise -a dontneed $DIR/$tfile ||
19554                 error "Ladvise dontneed again failed"
19555         local no_read=$(facet_meminfo ost1 Cached)
19556         echo "Cache used after dontneed ladvise: $no_read KiB"
19557
19558         if [ $total -lt $((before_read + kibibytes)) ]; then
19559                 echo "Memory is too small, abort checking"
19560                 return 0
19561         fi
19562
19563         if [ $((before_read + kibibytes)) -gt $after_read ]; then
19564                 error "Ladvise willread should use more memory" \
19565                         "than $kibibytes KiB"
19566         fi
19567
19568         if [ $((no_read + kibibytes)) -gt $after_read ]; then
19569                 error "Ladvise dontneed should release more memory" \
19570                         "than $kibibytes KiB"
19571         fi
19572 }
19573 run_test 255b "check 'lfs ladvise -a dontneed'"
19574
19575 test_255c() {
19576         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
19577                 skip "lustre < 2.10.50 does not support lockahead"
19578
19579         local count
19580         local new_count
19581         local difference
19582         local i
19583         local rc
19584
19585         test_mkdir -p $DIR/$tdir
19586         $LFS setstripe -i 0 -c 1 $DIR/$tdir
19587
19588         #test 10 returns only success/failure
19589         i=10
19590         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19591         rc=$?
19592         if [ $rc -eq 255 ]; then
19593                 error "Ladvise test${i} failed, ${rc}"
19594         fi
19595
19596         #test 11 counts lock enqueue requests, all others count new locks
19597         i=11
19598         count=$(do_facet ost1 \
19599                 $LCTL get_param -n ost.OSS.ost.stats)
19600         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
19601
19602         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19603         rc=$?
19604         if [ $rc -eq 255 ]; then
19605                 error "Ladvise test${i} failed, ${rc}"
19606         fi
19607
19608         new_count=$(do_facet ost1 \
19609                 $LCTL get_param -n ost.OSS.ost.stats)
19610         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
19611                    awk '{ print $2 }')
19612
19613         difference="$((new_count - count))"
19614         if [ $difference -ne $rc ]; then
19615                 error "Ladvise test${i}, bad enqueue count, returned " \
19616                       "${rc}, actual ${difference}"
19617         fi
19618
19619         for i in $(seq 12 21); do
19620                 # If we do not do this, we run the risk of having too many
19621                 # locks and starting lock cancellation while we are checking
19622                 # lock counts.
19623                 cancel_lru_locks osc
19624
19625                 count=$($LCTL get_param -n \
19626                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
19627
19628                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
19629                 rc=$?
19630                 if [ $rc -eq 255 ]; then
19631                         error "Ladvise test ${i} failed, ${rc}"
19632                 fi
19633
19634                 new_count=$($LCTL get_param -n \
19635                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
19636                 difference="$((new_count - count))"
19637
19638                 # Test 15 output is divided by 100 to map down to valid return
19639                 if [ $i -eq 15 ]; then
19640                         rc="$((rc * 100))"
19641                 fi
19642
19643                 if [ $difference -ne $rc ]; then
19644                         error "Ladvise test ${i}, bad lock count, returned " \
19645                               "${rc}, actual ${difference}"
19646                 fi
19647         done
19648
19649         #test 22 returns only success/failure
19650         i=22
19651         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19652         rc=$?
19653         if [ $rc -eq 255 ]; then
19654                 error "Ladvise test${i} failed, ${rc}"
19655         fi
19656 }
19657 run_test 255c "suite of ladvise lockahead tests"
19658
19659 test_256() {
19660         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19661         remote_mds_nodsh && skip "remote MDS with nodsh"
19662         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
19663         changelog_users $SINGLEMDS | grep "^cl" &&
19664                 skip "active changelog user"
19665
19666         local cl_user
19667         local cat_sl
19668         local mdt_dev
19669
19670         mdt_dev=$(mdsdevname 1)
19671         echo $mdt_dev
19672
19673         changelog_register || error "changelog_register failed"
19674
19675         rm -rf $DIR/$tdir
19676         mkdir -p $DIR/$tdir
19677
19678         changelog_clear 0 || error "changelog_clear failed"
19679
19680         # change something
19681         touch $DIR/$tdir/{1..10}
19682
19683         # stop the MDT
19684         stop $SINGLEMDS || error "Fail to stop MDT"
19685
19686         # remount the MDT
19687
19688         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
19689
19690         #after mount new plainllog is used
19691         touch $DIR/$tdir/{11..19}
19692         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
19693         stack_trap "rm -f $tmpfile"
19694         cat_sl=$(do_facet $SINGLEMDS "sync; \
19695                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
19696                  llog_reader $tmpfile | grep -c type=1064553b")
19697         do_facet $SINGLEMDS llog_reader $tmpfile
19698
19699         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
19700
19701         changelog_clear 0 || error "changelog_clear failed"
19702
19703         cat_sl=$(do_facet $SINGLEMDS "sync; \
19704                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
19705                  llog_reader $tmpfile | grep -c type=1064553b")
19706
19707         if (( cat_sl == 2 )); then
19708                 error "Empty plain llog was not deleted from changelog catalog"
19709         elif (( cat_sl != 1 )); then
19710                 error "Active plain llog shouldn't be deleted from catalog"
19711         fi
19712 }
19713 run_test 256 "Check llog delete for empty and not full state"
19714
19715 test_257() {
19716         remote_mds_nodsh && skip "remote MDS with nodsh"
19717         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
19718                 skip "Need MDS version at least 2.8.55"
19719
19720         test_mkdir $DIR/$tdir
19721
19722         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
19723                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
19724         stat $DIR/$tdir
19725
19726 #define OBD_FAIL_MDS_XATTR_REP                  0x161
19727         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
19728         local facet=mds$((mdtidx + 1))
19729         set_nodes_failloc $(facet_active_host $facet) 0x80000161
19730         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
19731
19732         stop $facet || error "stop MDS failed"
19733         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
19734                 error "start MDS fail"
19735         wait_recovery_complete $facet
19736 }
19737 run_test 257 "xattr locks are not lost"
19738
19739 # Verify we take the i_mutex when security requires it
19740 test_258a() {
19741 #define OBD_FAIL_IMUTEX_SEC 0x141c
19742         $LCTL set_param fail_loc=0x141c
19743         touch $DIR/$tfile
19744         chmod u+s $DIR/$tfile
19745         chmod a+rwx $DIR/$tfile
19746         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
19747         RC=$?
19748         if [ $RC -ne 0 ]; then
19749                 error "error, failed to take i_mutex, rc=$?"
19750         fi
19751         rm -f $DIR/$tfile
19752 }
19753 run_test 258a "verify i_mutex security behavior when suid attributes is set"
19754
19755 # Verify we do NOT take the i_mutex in the normal case
19756 test_258b() {
19757 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
19758         $LCTL set_param fail_loc=0x141d
19759         touch $DIR/$tfile
19760         chmod a+rwx $DIR
19761         chmod a+rw $DIR/$tfile
19762         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
19763         RC=$?
19764         if [ $RC -ne 0 ]; then
19765                 error "error, took i_mutex unnecessarily, rc=$?"
19766         fi
19767         rm -f $DIR/$tfile
19768
19769 }
19770 run_test 258b "verify i_mutex security behavior"
19771
19772 test_259() {
19773         local file=$DIR/$tfile
19774         local before
19775         local after
19776
19777         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
19778
19779         stack_trap "rm -f $file" EXIT
19780
19781         wait_delete_completed
19782         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19783         echo "before: $before"
19784
19785         $LFS setstripe -i 0 -c 1 $file
19786         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
19787         sync_all_data
19788         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19789         echo "after write: $after"
19790
19791 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
19792         do_facet ost1 $LCTL set_param fail_loc=0x2301
19793         $TRUNCATE $file 0
19794         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19795         echo "after truncate: $after"
19796
19797         stop ost1
19798         do_facet ost1 $LCTL set_param fail_loc=0
19799         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19800         sleep 2
19801         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19802         echo "after restart: $after"
19803         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
19804                 error "missing truncate?"
19805
19806         return 0
19807 }
19808 run_test 259 "crash at delayed truncate"
19809
19810 test_260() {
19811 #define OBD_FAIL_MDC_CLOSE               0x806
19812         $LCTL set_param fail_loc=0x80000806
19813         touch $DIR/$tfile
19814
19815 }
19816 run_test 260 "Check mdc_close fail"
19817
19818 ### Data-on-MDT sanity tests ###
19819 test_270a() {
19820         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19821                 skip "Need MDS version at least 2.10.55 for DoM"
19822
19823         # create DoM file
19824         local dom=$DIR/$tdir/dom_file
19825         local tmp=$DIR/$tdir/tmp_file
19826
19827         mkdir -p $DIR/$tdir
19828
19829         # basic checks for DoM component creation
19830         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
19831                 error "Can set MDT layout to non-first entry"
19832
19833         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
19834                 error "Can define multiple entries as MDT layout"
19835
19836         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
19837
19838         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
19839         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
19840         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
19841
19842         local mdtidx=$($LFS getstripe -m $dom)
19843         local mdtname=MDT$(printf %04x $mdtidx)
19844         local facet=mds$((mdtidx + 1))
19845         local space_check=1
19846
19847         # Skip free space checks with ZFS
19848         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
19849
19850         # write
19851         sync
19852         local size_tmp=$((65536 * 3))
19853         local mdtfree1=$(do_facet $facet \
19854                          lctl get_param -n osd*.*$mdtname.kbytesfree)
19855
19856         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
19857         # check also direct IO along write
19858         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
19859         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
19860         sync
19861         cmp $tmp $dom || error "file data is different"
19862         [ $(stat -c%s $dom) == $size_tmp ] ||
19863                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
19864         if [ $space_check == 1 ]; then
19865                 local mdtfree2=$(do_facet $facet \
19866                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
19867
19868                 # increase in usage from by $size_tmp
19869                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
19870                         error "MDT free space wrong after write: " \
19871                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
19872         fi
19873
19874         # truncate
19875         local size_dom=10000
19876
19877         $TRUNCATE $dom $size_dom
19878         [ $(stat -c%s $dom) == $size_dom ] ||
19879                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
19880         if [ $space_check == 1 ]; then
19881                 mdtfree1=$(do_facet $facet \
19882                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19883                 # decrease in usage from $size_tmp to new $size_dom
19884                 [ $(($mdtfree1 - $mdtfree2)) -ge \
19885                   $(((size_tmp - size_dom) / 1024)) ] ||
19886                         error "MDT free space is wrong after truncate: " \
19887                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
19888         fi
19889
19890         # append
19891         cat $tmp >> $dom
19892         sync
19893         size_dom=$((size_dom + size_tmp))
19894         [ $(stat -c%s $dom) == $size_dom ] ||
19895                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
19896         if [ $space_check == 1 ]; then
19897                 mdtfree2=$(do_facet $facet \
19898                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19899                 # increase in usage by $size_tmp from previous
19900                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
19901                         error "MDT free space is wrong after append: " \
19902                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
19903         fi
19904
19905         # delete
19906         rm $dom
19907         if [ $space_check == 1 ]; then
19908                 mdtfree1=$(do_facet $facet \
19909                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19910                 # decrease in usage by $size_dom from previous
19911                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
19912                         error "MDT free space is wrong after removal: " \
19913                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
19914         fi
19915
19916         # combined striping
19917         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
19918                 error "Can't create DoM + OST striping"
19919
19920         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
19921         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
19922         # check also direct IO along write
19923         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
19924         sync
19925         cmp $tmp $dom || error "file data is different"
19926         [ $(stat -c%s $dom) == $size_tmp ] ||
19927                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
19928         rm $dom $tmp
19929
19930         return 0
19931 }
19932 run_test 270a "DoM: basic functionality tests"
19933
19934 test_270b() {
19935         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19936                 skip "Need MDS version at least 2.10.55"
19937
19938         local dom=$DIR/$tdir/dom_file
19939         local max_size=1048576
19940
19941         mkdir -p $DIR/$tdir
19942         $LFS setstripe -E $max_size -L mdt $dom
19943
19944         # truncate over the limit
19945         $TRUNCATE $dom $(($max_size + 1)) &&
19946                 error "successful truncate over the maximum size"
19947         # write over the limit
19948         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
19949                 error "successful write over the maximum size"
19950         # append over the limit
19951         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
19952         echo "12345" >> $dom && error "successful append over the maximum size"
19953         rm $dom
19954
19955         return 0
19956 }
19957 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
19958
19959 test_270c() {
19960         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19961                 skip "Need MDS version at least 2.10.55"
19962
19963         mkdir -p $DIR/$tdir
19964         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
19965
19966         # check files inherit DoM EA
19967         touch $DIR/$tdir/first
19968         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
19969                 error "bad pattern"
19970         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
19971                 error "bad stripe count"
19972         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
19973                 error "bad stripe size"
19974
19975         # check directory inherits DoM EA and uses it as default
19976         mkdir $DIR/$tdir/subdir
19977         touch $DIR/$tdir/subdir/second
19978         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
19979                 error "bad pattern in sub-directory"
19980         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
19981                 error "bad stripe count in sub-directory"
19982         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
19983                 error "bad stripe size in sub-directory"
19984         return 0
19985 }
19986 run_test 270c "DoM: DoM EA inheritance tests"
19987
19988 test_270d() {
19989         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19990                 skip "Need MDS version at least 2.10.55"
19991
19992         mkdir -p $DIR/$tdir
19993         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
19994
19995         # inherit default DoM striping
19996         mkdir $DIR/$tdir/subdir
19997         touch $DIR/$tdir/subdir/f1
19998
19999         # change default directory striping
20000         $LFS setstripe -c 1 $DIR/$tdir/subdir
20001         touch $DIR/$tdir/subdir/f2
20002         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
20003                 error "wrong default striping in file 2"
20004         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
20005                 error "bad pattern in file 2"
20006         return 0
20007 }
20008 run_test 270d "DoM: change striping from DoM to RAID0"
20009
20010 test_270e() {
20011         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20012                 skip "Need MDS version at least 2.10.55"
20013
20014         mkdir -p $DIR/$tdir/dom
20015         mkdir -p $DIR/$tdir/norm
20016         DOMFILES=20
20017         NORMFILES=10
20018         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
20019         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
20020
20021         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
20022         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
20023
20024         # find DoM files by layout
20025         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
20026         [ $NUM -eq  $DOMFILES ] ||
20027                 error "lfs find -L: found $NUM, expected $DOMFILES"
20028         echo "Test 1: lfs find 20 DOM files by layout: OK"
20029
20030         # there should be 1 dir with default DOM striping
20031         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
20032         [ $NUM -eq  1 ] ||
20033                 error "lfs find -L: found $NUM, expected 1 dir"
20034         echo "Test 2: lfs find 1 DOM dir by layout: OK"
20035
20036         # find DoM files by stripe size
20037         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
20038         [ $NUM -eq  $DOMFILES ] ||
20039                 error "lfs find -S: found $NUM, expected $DOMFILES"
20040         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
20041
20042         # find files by stripe offset except DoM files
20043         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
20044         [ $NUM -eq  $NORMFILES ] ||
20045                 error "lfs find -i: found $NUM, expected $NORMFILES"
20046         echo "Test 5: lfs find no DOM files by stripe index: OK"
20047         return 0
20048 }
20049 run_test 270e "DoM: lfs find with DoM files test"
20050
20051 test_270f() {
20052         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20053                 skip "Need MDS version at least 2.10.55"
20054
20055         local mdtname=${FSNAME}-MDT0000-mdtlov
20056         local dom=$DIR/$tdir/dom_file
20057         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
20058                                                 lod.$mdtname.dom_stripesize)
20059         local dom_limit=131072
20060
20061         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
20062         local dom_current=$(do_facet mds1 $LCTL get_param -n \
20063                                                 lod.$mdtname.dom_stripesize)
20064         [ ${dom_limit} -eq ${dom_current} ] ||
20065                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
20066
20067         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20068         $LFS setstripe -d $DIR/$tdir
20069         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
20070                 error "Can't set directory default striping"
20071
20072         # exceed maximum stripe size
20073         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
20074                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
20075         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
20076                 error "Able to create DoM component size more than LOD limit"
20077
20078         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
20079         dom_current=$(do_facet mds1 $LCTL get_param -n \
20080                                                 lod.$mdtname.dom_stripesize)
20081         [ 0 -eq ${dom_current} ] ||
20082                 error "Can't set zero DoM stripe limit"
20083         rm $dom
20084
20085         # attempt to create DoM file on server with disabled DoM should
20086         # remove DoM entry from layout and be succeed
20087         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
20088                 error "Can't create DoM file (DoM is disabled)"
20089         [ $($LFS getstripe -L $dom) == "mdt" ] &&
20090                 error "File has DoM component while DoM is disabled"
20091         rm $dom
20092
20093         # attempt to create DoM file with only DoM stripe should return error
20094         $LFS setstripe -E $dom_limit -L mdt $dom &&
20095                 error "Able to create DoM-only file while DoM is disabled"
20096
20097         # too low values to be aligned with smallest stripe size 64K
20098         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
20099         dom_current=$(do_facet mds1 $LCTL get_param -n \
20100                                                 lod.$mdtname.dom_stripesize)
20101         [ 30000 -eq ${dom_current} ] &&
20102                 error "Can set too small DoM stripe limit"
20103
20104         # 64K is a minimal stripe size in Lustre, expect limit of that size
20105         [ 65536 -eq ${dom_current} ] ||
20106                 error "Limit is not set to 64K but ${dom_current}"
20107
20108         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
20109         dom_current=$(do_facet mds1 $LCTL get_param -n \
20110                                                 lod.$mdtname.dom_stripesize)
20111         echo $dom_current
20112         [ 2147483648 -eq ${dom_current} ] &&
20113                 error "Can set too large DoM stripe limit"
20114
20115         do_facet mds1 $LCTL set_param -n \
20116                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
20117         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
20118                 error "Can't create DoM component size after limit change"
20119         do_facet mds1 $LCTL set_param -n \
20120                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
20121         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
20122                 error "Can't create DoM file after limit decrease"
20123         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
20124                 error "Can create big DoM component after limit decrease"
20125         touch ${dom}_def ||
20126                 error "Can't create file with old default layout"
20127
20128         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
20129         return 0
20130 }
20131 run_test 270f "DoM: maximum DoM stripe size checks"
20132
20133 test_270g() {
20134         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20135                 skip "Need MDS version at least 2.13.52"
20136         local dom=$DIR/$tdir/$tfile
20137
20138         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20139         local lodname=${FSNAME}-MDT0000-mdtlov
20140
20141         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20142         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
20143         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
20144         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20145
20146         local dom_limit=1024
20147         local dom_threshold="50%"
20148
20149         $LFS setstripe -d $DIR/$tdir
20150         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
20151                 error "Can't set directory default striping"
20152
20153         do_facet mds1 $LCTL set_param -n \
20154                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
20155         # set 0 threshold and create DOM file to change tunable stripesize
20156         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
20157         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
20158                 error "Failed to create $dom file"
20159         # now tunable dom_cur_stripesize should reach maximum
20160         local dom_current=$(do_facet mds1 $LCTL get_param -n \
20161                                         lod.${lodname}.dom_stripesize_cur_kb)
20162         [[ $dom_current == $dom_limit ]] ||
20163                 error "Current DOM stripesize is not maximum"
20164         rm $dom
20165
20166         # set threshold for further tests
20167         do_facet mds1 $LCTL set_param -n \
20168                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
20169         echo "DOM threshold is $dom_threshold free space"
20170         local dom_def
20171         local dom_set
20172         # Spoof bfree to exceed threshold
20173         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
20174         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
20175         for spfree in 40 20 0 15 30 55; do
20176                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
20177                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
20178                         error "Failed to create $dom file"
20179                 dom_def=$(do_facet mds1 $LCTL get_param -n \
20180                                         lod.${lodname}.dom_stripesize_cur_kb)
20181                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
20182                 [[ $dom_def != $dom_current ]] ||
20183                         error "Default stripe size was not changed"
20184                 if [[ $spfree > 0 ]] ; then
20185                         dom_set=$($LFS getstripe -S $dom)
20186                         [[ $dom_set == $((dom_def * 1024)) ]] ||
20187                                 error "DOM component size is still old"
20188                 else
20189                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
20190                                 error "DoM component is set with no free space"
20191                 fi
20192                 rm $dom
20193                 dom_current=$dom_def
20194         done
20195 }
20196 run_test 270g "DoM: default DoM stripe size depends on free space"
20197
20198 test_270h() {
20199         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20200                 skip "Need MDS version at least 2.13.53"
20201
20202         local mdtname=${FSNAME}-MDT0000-mdtlov
20203         local dom=$DIR/$tdir/$tfile
20204         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20205
20206         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
20207         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20208
20209         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20210         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
20211                 error "can't create OST file"
20212         # mirrored file with DOM entry in the second mirror
20213         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
20214                 error "can't create mirror with DoM component"
20215
20216         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
20217
20218         # DOM component in the middle and has other enries in the same mirror,
20219         # should succeed but lost DoM component
20220         $LFS setstripe --copy=${dom}_1 $dom ||
20221                 error "Can't create file from OST|DOM mirror layout"
20222         # check new file has no DoM layout after all
20223         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
20224                 error "File has DoM component while DoM is disabled"
20225 }
20226 run_test 270h "DoM: DoM stripe removal when disabled on server"
20227
20228 test_271a() {
20229         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20230                 skip "Need MDS version at least 2.10.55"
20231
20232         local dom=$DIR/$tdir/dom
20233
20234         mkdir -p $DIR/$tdir
20235
20236         $LFS setstripe -E 1024K -L mdt $dom
20237
20238         lctl set_param -n mdc.*.stats=clear
20239         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
20240         cat $dom > /dev/null
20241         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
20242         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
20243         ls $dom
20244         rm -f $dom
20245 }
20246 run_test 271a "DoM: data is cached for read after write"
20247
20248 test_271b() {
20249         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20250                 skip "Need MDS version at least 2.10.55"
20251
20252         local dom=$DIR/$tdir/dom
20253
20254         mkdir -p $DIR/$tdir
20255
20256         $LFS setstripe -E 1024K -L mdt -E EOF $dom
20257
20258         lctl set_param -n mdc.*.stats=clear
20259         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
20260         cancel_lru_locks mdc
20261         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
20262         # second stat to check size is cached on client
20263         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
20264         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
20265         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
20266         rm -f $dom
20267 }
20268 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
20269
20270 test_271ba() {
20271         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20272                 skip "Need MDS version at least 2.10.55"
20273
20274         local dom=$DIR/$tdir/dom
20275
20276         mkdir -p $DIR/$tdir
20277
20278         $LFS setstripe -E 1024K -L mdt -E EOF $dom
20279
20280         lctl set_param -n mdc.*.stats=clear
20281         lctl set_param -n osc.*.stats=clear
20282         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
20283         cancel_lru_locks mdc
20284         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
20285         # second stat to check size is cached on client
20286         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
20287         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
20288         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
20289         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
20290         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
20291         rm -f $dom
20292 }
20293 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
20294
20295
20296 get_mdc_stats() {
20297         local mdtidx=$1
20298         local param=$2
20299         local mdt=MDT$(printf %04x $mdtidx)
20300
20301         if [ -z $param ]; then
20302                 lctl get_param -n mdc.*$mdt*.stats
20303         else
20304                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
20305         fi
20306 }
20307
20308 test_271c() {
20309         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20310                 skip "Need MDS version at least 2.10.55"
20311
20312         local dom=$DIR/$tdir/dom
20313
20314         mkdir -p $DIR/$tdir
20315
20316         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20317
20318         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
20319         local facet=mds$((mdtidx + 1))
20320
20321         cancel_lru_locks mdc
20322         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
20323         createmany -o $dom 1000
20324         lctl set_param -n mdc.*.stats=clear
20325         smalliomany -w $dom 1000 200
20326         get_mdc_stats $mdtidx
20327         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
20328         # Each file has 1 open, 1 IO enqueues, total 2000
20329         # but now we have also +1 getxattr for security.capability, total 3000
20330         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
20331         unlinkmany $dom 1000
20332
20333         cancel_lru_locks mdc
20334         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
20335         createmany -o $dom 1000
20336         lctl set_param -n mdc.*.stats=clear
20337         smalliomany -w $dom 1000 200
20338         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
20339         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
20340         # for OPEN and IO lock.
20341         [ $((enq - enq_2)) -ge 1000 ] ||
20342                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
20343         unlinkmany $dom 1000
20344         return 0
20345 }
20346 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
20347
20348 cleanup_271def_tests() {
20349         trap 0
20350         rm -f $1
20351 }
20352
20353 test_271d() {
20354         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
20355                 skip "Need MDS version at least 2.10.57"
20356
20357         local dom=$DIR/$tdir/dom
20358         local tmp=$TMP/$tfile
20359         trap "cleanup_271def_tests $tmp" EXIT
20360
20361         mkdir -p $DIR/$tdir
20362
20363         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20364
20365         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
20366
20367         cancel_lru_locks mdc
20368         dd if=/dev/urandom of=$tmp bs=1000 count=1
20369         dd if=$tmp of=$dom bs=1000 count=1
20370         cancel_lru_locks mdc
20371
20372         cat /etc/hosts >> $tmp
20373         lctl set_param -n mdc.*.stats=clear
20374
20375         # append data to the same file it should update local page
20376         echo "Append to the same page"
20377         cat /etc/hosts >> $dom
20378         local num=$(get_mdc_stats $mdtidx ost_read)
20379         local ra=$(get_mdc_stats $mdtidx req_active)
20380         local rw=$(get_mdc_stats $mdtidx req_waittime)
20381
20382         [ -z $num ] || error "$num READ RPC occured"
20383         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20384         echo "... DONE"
20385
20386         # compare content
20387         cmp $tmp $dom || error "file miscompare"
20388
20389         cancel_lru_locks mdc
20390         lctl set_param -n mdc.*.stats=clear
20391
20392         echo "Open and read file"
20393         cat $dom > /dev/null
20394         local num=$(get_mdc_stats $mdtidx ost_read)
20395         local ra=$(get_mdc_stats $mdtidx req_active)
20396         local rw=$(get_mdc_stats $mdtidx req_waittime)
20397
20398         [ -z $num ] || error "$num READ RPC occured"
20399         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20400         echo "... DONE"
20401
20402         # compare content
20403         cmp $tmp $dom || error "file miscompare"
20404
20405         return 0
20406 }
20407 run_test 271d "DoM: read on open (1K file in reply buffer)"
20408
20409 test_271f() {
20410         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
20411                 skip "Need MDS version at least 2.10.57"
20412
20413         local dom=$DIR/$tdir/dom
20414         local tmp=$TMP/$tfile
20415         trap "cleanup_271def_tests $tmp" EXIT
20416
20417         mkdir -p $DIR/$tdir
20418
20419         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20420
20421         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
20422
20423         cancel_lru_locks mdc
20424         dd if=/dev/urandom of=$tmp bs=265000 count=1
20425         dd if=$tmp of=$dom bs=265000 count=1
20426         cancel_lru_locks mdc
20427         cat /etc/hosts >> $tmp
20428         lctl set_param -n mdc.*.stats=clear
20429
20430         echo "Append to the same page"
20431         cat /etc/hosts >> $dom
20432         local num=$(get_mdc_stats $mdtidx ost_read)
20433         local ra=$(get_mdc_stats $mdtidx req_active)
20434         local rw=$(get_mdc_stats $mdtidx req_waittime)
20435
20436         [ -z $num ] || error "$num READ RPC occured"
20437         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20438         echo "... DONE"
20439
20440         # compare content
20441         cmp $tmp $dom || error "file miscompare"
20442
20443         cancel_lru_locks mdc
20444         lctl set_param -n mdc.*.stats=clear
20445
20446         echo "Open and read file"
20447         cat $dom > /dev/null
20448         local num=$(get_mdc_stats $mdtidx ost_read)
20449         local ra=$(get_mdc_stats $mdtidx req_active)
20450         local rw=$(get_mdc_stats $mdtidx req_waittime)
20451
20452         [ -z $num ] && num=0
20453         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
20454         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20455         echo "... DONE"
20456
20457         # compare content
20458         cmp $tmp $dom || error "file miscompare"
20459
20460         return 0
20461 }
20462 run_test 271f "DoM: read on open (200K file and read tail)"
20463
20464 test_271g() {
20465         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
20466                 skip "Skipping due to old client or server version"
20467
20468         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
20469         # to get layout
20470         $CHECKSTAT -t file $DIR1/$tfile
20471
20472         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
20473         MULTIOP_PID=$!
20474         sleep 1
20475         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
20476         $LCTL set_param fail_loc=0x80000314
20477         rm $DIR1/$tfile || error "Unlink fails"
20478         RC=$?
20479         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
20480         [ $RC -eq 0 ] || error "Failed write to stale object"
20481 }
20482 run_test 271g "Discard DoM data vs client flush race"
20483
20484 test_272a() {
20485         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20486                 skip "Need MDS version at least 2.11.50"
20487
20488         local dom=$DIR/$tdir/dom
20489         mkdir -p $DIR/$tdir
20490
20491         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
20492         dd if=/dev/urandom of=$dom bs=512K count=1 ||
20493                 error "failed to write data into $dom"
20494         local old_md5=$(md5sum $dom)
20495
20496         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
20497                 error "failed to migrate to the same DoM component"
20498
20499         local new_md5=$(md5sum $dom)
20500
20501         [ "$old_md5" == "$new_md5" ] ||
20502                 error "md5sum differ: $old_md5, $new_md5"
20503
20504         [ $($LFS getstripe -c $dom) -eq 2 ] ||
20505                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
20506 }
20507 run_test 272a "DoM migration: new layout with the same DOM component"
20508
20509 test_272b() {
20510         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20511                 skip "Need MDS version at least 2.11.50"
20512
20513         local dom=$DIR/$tdir/dom
20514         mkdir -p $DIR/$tdir
20515         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20516
20517         local mdtidx=$($LFS getstripe -m $dom)
20518         local mdtname=MDT$(printf %04x $mdtidx)
20519         local facet=mds$((mdtidx + 1))
20520
20521         local mdtfree1=$(do_facet $facet \
20522                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20523         dd if=/dev/urandom of=$dom bs=2M count=1 ||
20524                 error "failed to write data into $dom"
20525         local old_md5=$(md5sum $dom)
20526         cancel_lru_locks mdc
20527         local mdtfree1=$(do_facet $facet \
20528                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20529
20530         $LFS migrate -c2 $dom ||
20531                 error "failed to migrate to the new composite layout"
20532         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20533                 error "MDT stripe was not removed"
20534
20535         cancel_lru_locks mdc
20536         local new_md5=$(md5sum $dom)
20537         [ "$old_md5" == "$new_md5" ] ||
20538                 error "$old_md5 != $new_md5"
20539
20540         # Skip free space checks with ZFS
20541         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20542                 local mdtfree2=$(do_facet $facet \
20543                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20544                 [ $mdtfree2 -gt $mdtfree1 ] ||
20545                         error "MDT space is not freed after migration"
20546         fi
20547         return 0
20548 }
20549 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
20550
20551 test_272c() {
20552         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20553                 skip "Need MDS version at least 2.11.50"
20554
20555         local dom=$DIR/$tdir/$tfile
20556         mkdir -p $DIR/$tdir
20557         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20558
20559         local mdtidx=$($LFS getstripe -m $dom)
20560         local mdtname=MDT$(printf %04x $mdtidx)
20561         local facet=mds$((mdtidx + 1))
20562
20563         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
20564                 error "failed to write data into $dom"
20565         local old_md5=$(md5sum $dom)
20566         cancel_lru_locks mdc
20567         local mdtfree1=$(do_facet $facet \
20568                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20569
20570         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
20571                 error "failed to migrate to the new composite layout"
20572         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
20573                 error "MDT stripe was not removed"
20574
20575         cancel_lru_locks mdc
20576         local new_md5=$(md5sum $dom)
20577         [ "$old_md5" == "$new_md5" ] ||
20578                 error "$old_md5 != $new_md5"
20579
20580         # Skip free space checks with ZFS
20581         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20582                 local mdtfree2=$(do_facet $facet \
20583                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20584                 [ $mdtfree2 -gt $mdtfree1 ] ||
20585                         error "MDS space is not freed after migration"
20586         fi
20587         return 0
20588 }
20589 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
20590
20591 test_272d() {
20592         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20593                 skip "Need MDS version at least 2.12.55"
20594
20595         local dom=$DIR/$tdir/$tfile
20596         mkdir -p $DIR/$tdir
20597         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20598
20599         local mdtidx=$($LFS getstripe -m $dom)
20600         local mdtname=MDT$(printf %04x $mdtidx)
20601         local facet=mds$((mdtidx + 1))
20602
20603         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
20604                 error "failed to write data into $dom"
20605         local old_md5=$(md5sum $dom)
20606         cancel_lru_locks mdc
20607         local mdtfree1=$(do_facet $facet \
20608                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20609
20610         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
20611                 error "failed mirroring to the new composite layout"
20612         $LFS mirror resync $dom ||
20613                 error "failed mirror resync"
20614         $LFS mirror split --mirror-id 1 -d $dom ||
20615                 error "failed mirror split"
20616
20617         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20618                 error "MDT stripe was not removed"
20619
20620         cancel_lru_locks mdc
20621         local new_md5=$(md5sum $dom)
20622         [ "$old_md5" == "$new_md5" ] ||
20623                 error "$old_md5 != $new_md5"
20624
20625         # Skip free space checks with ZFS
20626         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20627                 local mdtfree2=$(do_facet $facet \
20628                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20629                 [ $mdtfree2 -gt $mdtfree1 ] ||
20630                         error "MDS space is not freed after DOM mirror deletion"
20631         fi
20632         return 0
20633 }
20634 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
20635
20636 test_272e() {
20637         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20638                 skip "Need MDS version at least 2.12.55"
20639
20640         local dom=$DIR/$tdir/$tfile
20641         mkdir -p $DIR/$tdir
20642         $LFS setstripe -c 2 $dom
20643
20644         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
20645                 error "failed to write data into $dom"
20646         local old_md5=$(md5sum $dom)
20647         cancel_lru_locks mdc
20648
20649         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
20650                 error "failed mirroring to the DOM layout"
20651         $LFS mirror resync $dom ||
20652                 error "failed mirror resync"
20653         $LFS mirror split --mirror-id 1 -d $dom ||
20654                 error "failed mirror split"
20655
20656         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20657                 error "MDT stripe was not removed"
20658
20659         cancel_lru_locks mdc
20660         local new_md5=$(md5sum $dom)
20661         [ "$old_md5" == "$new_md5" ] ||
20662                 error "$old_md5 != $new_md5"
20663
20664         return 0
20665 }
20666 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
20667
20668 test_272f() {
20669         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20670                 skip "Need MDS version at least 2.12.55"
20671
20672         local dom=$DIR/$tdir/$tfile
20673         mkdir -p $DIR/$tdir
20674         $LFS setstripe -c 2 $dom
20675
20676         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
20677                 error "failed to write data into $dom"
20678         local old_md5=$(md5sum $dom)
20679         cancel_lru_locks mdc
20680
20681         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
20682                 error "failed migrating to the DOM file"
20683
20684         cancel_lru_locks mdc
20685         local new_md5=$(md5sum $dom)
20686         [ "$old_md5" != "$new_md5" ] &&
20687                 error "$old_md5 != $new_md5"
20688
20689         return 0
20690 }
20691 run_test 272f "DoM migration: OST-striped file to DOM file"
20692
20693 test_273a() {
20694         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20695                 skip "Need MDS version at least 2.11.50"
20696
20697         # Layout swap cannot be done if either file has DOM component,
20698         # this will never be supported, migration should be used instead
20699
20700         local dom=$DIR/$tdir/$tfile
20701         mkdir -p $DIR/$tdir
20702
20703         $LFS setstripe -c2 ${dom}_plain
20704         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
20705         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
20706                 error "can swap layout with DoM component"
20707         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
20708                 error "can swap layout with DoM component"
20709
20710         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
20711         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
20712                 error "can swap layout with DoM component"
20713         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
20714                 error "can swap layout with DoM component"
20715         return 0
20716 }
20717 run_test 273a "DoM: layout swapping should fail with DOM"
20718
20719 test_275() {
20720         remote_ost_nodsh && skip "remote OST with nodsh"
20721         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
20722                 skip "Need OST version >= 2.10.57"
20723
20724         local file=$DIR/$tfile
20725         local oss
20726
20727         oss=$(comma_list $(osts_nodes))
20728
20729         dd if=/dev/urandom of=$file bs=1M count=2 ||
20730                 error "failed to create a file"
20731         cancel_lru_locks osc
20732
20733         #lock 1
20734         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
20735                 error "failed to read a file"
20736
20737 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
20738         $LCTL set_param fail_loc=0x8000031f
20739
20740         cancel_lru_locks osc &
20741         sleep 1
20742
20743 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
20744         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
20745         #IO takes another lock, but matches the PENDING one
20746         #and places it to the IO RPC
20747         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
20748                 error "failed to read a file with PENDING lock"
20749 }
20750 run_test 275 "Read on a canceled duplicate lock"
20751
20752 test_276() {
20753         remote_ost_nodsh && skip "remote OST with nodsh"
20754         local pid
20755
20756         do_facet ost1 "(while true; do \
20757                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
20758                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
20759         pid=$!
20760
20761         for LOOP in $(seq 20); do
20762                 stop ost1
20763                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
20764         done
20765         kill -9 $pid
20766         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
20767                 rm $TMP/sanity_276_pid"
20768 }
20769 run_test 276 "Race between mount and obd_statfs"
20770
20771 test_277() {
20772         $LCTL set_param ldlm.namespaces.*.lru_size=0
20773         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
20774         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
20775                         grep ^used_mb | awk '{print $2}')
20776         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
20777         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
20778                 oflag=direct conv=notrunc
20779         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
20780                         grep ^used_mb | awk '{print $2}')
20781         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
20782 }
20783 run_test 277 "Direct IO shall drop page cache"
20784
20785 test_278() {
20786         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
20787         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
20788         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
20789                 skip "needs the same host for mdt1 mdt2" && return
20790
20791         local pid1
20792         local pid2
20793
20794 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
20795         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
20796         stop mds2 &
20797         pid2=$!
20798
20799         stop mds1
20800
20801         echo "Starting MDTs"
20802         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
20803         wait $pid2
20804 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
20805 #will return NULL
20806         do_facet mds2 $LCTL set_param fail_loc=0
20807
20808         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
20809         wait_recovery_complete mds2
20810 }
20811 run_test 278 "Race starting MDS between MDTs stop/start"
20812
20813 test_280() {
20814         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
20815                 skip "Need MGS version at least 2.13.52"
20816         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20817         combined_mgs_mds || skip "needs combined MGS/MDT"
20818
20819         umount_client $MOUNT
20820 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
20821         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
20822
20823         mount_client $MOUNT &
20824         sleep 1
20825         stop mgs || error "stop mgs failed"
20826         #for a race mgs would crash
20827         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
20828         mount_client $MOUNT || error "mount client failed"
20829 }
20830 run_test 280 "Race between MGS umount and client llog processing"
20831
20832 cleanup_test_300() {
20833         trap 0
20834         umask $SAVE_UMASK
20835 }
20836 test_striped_dir() {
20837         local mdt_index=$1
20838         local stripe_count
20839         local stripe_index
20840
20841         mkdir -p $DIR/$tdir
20842
20843         SAVE_UMASK=$(umask)
20844         trap cleanup_test_300 RETURN EXIT
20845
20846         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
20847                                                 $DIR/$tdir/striped_dir ||
20848                 error "set striped dir error"
20849
20850         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
20851         [ "$mode" = "755" ] || error "expect 755 got $mode"
20852
20853         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
20854                 error "getdirstripe failed"
20855         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
20856         if [ "$stripe_count" != "2" ]; then
20857                 error "1:stripe_count is $stripe_count, expect 2"
20858         fi
20859         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
20860         if [ "$stripe_count" != "2" ]; then
20861                 error "2:stripe_count is $stripe_count, expect 2"
20862         fi
20863
20864         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
20865         if [ "$stripe_index" != "$mdt_index" ]; then
20866                 error "stripe_index is $stripe_index, expect $mdt_index"
20867         fi
20868
20869         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
20870                 error "nlink error after create striped dir"
20871
20872         mkdir $DIR/$tdir/striped_dir/a
20873         mkdir $DIR/$tdir/striped_dir/b
20874
20875         stat $DIR/$tdir/striped_dir/a ||
20876                 error "create dir under striped dir failed"
20877         stat $DIR/$tdir/striped_dir/b ||
20878                 error "create dir under striped dir failed"
20879
20880         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
20881                 error "nlink error after mkdir"
20882
20883         rmdir $DIR/$tdir/striped_dir/a
20884         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
20885                 error "nlink error after rmdir"
20886
20887         rmdir $DIR/$tdir/striped_dir/b
20888         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
20889                 error "nlink error after rmdir"
20890
20891         chattr +i $DIR/$tdir/striped_dir
20892         createmany -o $DIR/$tdir/striped_dir/f 10 &&
20893                 error "immutable flags not working under striped dir!"
20894         chattr -i $DIR/$tdir/striped_dir
20895
20896         rmdir $DIR/$tdir/striped_dir ||
20897                 error "rmdir striped dir error"
20898
20899         cleanup_test_300
20900
20901         true
20902 }
20903
20904 test_300a() {
20905         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20906                 skip "skipped for lustre < 2.7.0"
20907         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20908         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20909
20910         test_striped_dir 0 || error "failed on striped dir on MDT0"
20911         test_striped_dir 1 || error "failed on striped dir on MDT0"
20912 }
20913 run_test 300a "basic striped dir sanity test"
20914
20915 test_300b() {
20916         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20917                 skip "skipped for lustre < 2.7.0"
20918         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20919         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20920
20921         local i
20922         local mtime1
20923         local mtime2
20924         local mtime3
20925
20926         test_mkdir $DIR/$tdir || error "mkdir fail"
20927         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
20928                 error "set striped dir error"
20929         for i in {0..9}; do
20930                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
20931                 sleep 1
20932                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
20933                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
20934                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
20935                 sleep 1
20936                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
20937                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
20938                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
20939         done
20940         true
20941 }
20942 run_test 300b "check ctime/mtime for striped dir"
20943
20944 test_300c() {
20945         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20946                 skip "skipped for lustre < 2.7.0"
20947         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20948         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20949
20950         local file_count
20951
20952         mkdir -p $DIR/$tdir
20953         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
20954                 error "set striped dir error"
20955
20956         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
20957                 error "chown striped dir failed"
20958
20959         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
20960                 error "create 5k files failed"
20961
20962         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
20963
20964         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
20965
20966         rm -rf $DIR/$tdir
20967 }
20968 run_test 300c "chown && check ls under striped directory"
20969
20970 test_300d() {
20971         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20972                 skip "skipped for lustre < 2.7.0"
20973         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20974         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20975
20976         local stripe_count
20977         local file
20978
20979         mkdir -p $DIR/$tdir
20980         $LFS setstripe -c 2 $DIR/$tdir
20981
20982         #local striped directory
20983         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
20984                 error "set striped dir error"
20985         #look at the directories for debug purposes
20986         ls -l $DIR/$tdir
20987         $LFS getdirstripe $DIR/$tdir
20988         ls -l $DIR/$tdir/striped_dir
20989         $LFS getdirstripe $DIR/$tdir/striped_dir
20990         createmany -o $DIR/$tdir/striped_dir/f 10 ||
20991                 error "create 10 files failed"
20992
20993         #remote striped directory
20994         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
20995                 error "set striped dir error"
20996         #look at the directories for debug purposes
20997         ls -l $DIR/$tdir
20998         $LFS getdirstripe $DIR/$tdir
20999         ls -l $DIR/$tdir/remote_striped_dir
21000         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
21001         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
21002                 error "create 10 files failed"
21003
21004         for file in $(find $DIR/$tdir); do
21005                 stripe_count=$($LFS getstripe -c $file)
21006                 [ $stripe_count -eq 2 ] ||
21007                         error "wrong stripe $stripe_count for $file"
21008         done
21009
21010         rm -rf $DIR/$tdir
21011 }
21012 run_test 300d "check default stripe under striped directory"
21013
21014 test_300e() {
21015         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21016                 skip "Need MDS version at least 2.7.55"
21017         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21018         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21019
21020         local stripe_count
21021         local file
21022
21023         mkdir -p $DIR/$tdir
21024
21025         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21026                 error "set striped dir error"
21027
21028         touch $DIR/$tdir/striped_dir/a
21029         touch $DIR/$tdir/striped_dir/b
21030         touch $DIR/$tdir/striped_dir/c
21031
21032         mkdir $DIR/$tdir/striped_dir/dir_a
21033         mkdir $DIR/$tdir/striped_dir/dir_b
21034         mkdir $DIR/$tdir/striped_dir/dir_c
21035
21036         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
21037                 error "set striped adir under striped dir error"
21038
21039         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
21040                 error "set striped bdir under striped dir error"
21041
21042         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
21043                 error "set striped cdir under striped dir error"
21044
21045         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
21046                 error "rename dir under striped dir fails"
21047
21048         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
21049                 error "rename dir under different stripes fails"
21050
21051         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
21052                 error "rename file under striped dir should succeed"
21053
21054         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
21055                 error "rename dir under striped dir should succeed"
21056
21057         rm -rf $DIR/$tdir
21058 }
21059 run_test 300e "check rename under striped directory"
21060
21061 test_300f() {
21062         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21063         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21064         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21065                 skip "Need MDS version at least 2.7.55"
21066
21067         local stripe_count
21068         local file
21069
21070         rm -rf $DIR/$tdir
21071         mkdir -p $DIR/$tdir
21072
21073         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21074                 error "set striped dir error"
21075
21076         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
21077                 error "set striped dir error"
21078
21079         touch $DIR/$tdir/striped_dir/a
21080         mkdir $DIR/$tdir/striped_dir/dir_a
21081         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
21082                 error "create striped dir under striped dir fails"
21083
21084         touch $DIR/$tdir/striped_dir1/b
21085         mkdir $DIR/$tdir/striped_dir1/dir_b
21086         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
21087                 error "create striped dir under striped dir fails"
21088
21089         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
21090                 error "rename dir under different striped dir should fail"
21091
21092         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
21093                 error "rename striped dir under diff striped dir should fail"
21094
21095         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
21096                 error "rename file under diff striped dirs fails"
21097
21098         rm -rf $DIR/$tdir
21099 }
21100 run_test 300f "check rename cross striped directory"
21101
21102 test_300_check_default_striped_dir()
21103 {
21104         local dirname=$1
21105         local default_count=$2
21106         local default_index=$3
21107         local stripe_count
21108         local stripe_index
21109         local dir_stripe_index
21110         local dir
21111
21112         echo "checking $dirname $default_count $default_index"
21113         $LFS setdirstripe -D -c $default_count -i $default_index \
21114                                 -t all_char $DIR/$tdir/$dirname ||
21115                 error "set default stripe on striped dir error"
21116         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
21117         [ $stripe_count -eq $default_count ] ||
21118                 error "expect $default_count get $stripe_count for $dirname"
21119
21120         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
21121         [ $stripe_index -eq $default_index ] ||
21122                 error "expect $default_index get $stripe_index for $dirname"
21123
21124         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
21125                                                 error "create dirs failed"
21126
21127         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
21128         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
21129         for dir in $(find $DIR/$tdir/$dirname/*); do
21130                 stripe_count=$($LFS getdirstripe -c $dir)
21131                 [ $stripe_count -eq $default_count ] ||
21132                 [ $stripe_count -eq 0 ] || [ $default_count -eq 1 ] ||
21133                 error "stripe count $default_count != $stripe_count for $dir"
21134
21135                 stripe_index=$($LFS getdirstripe -i $dir)
21136                 [ $default_index -eq -1 ] ||
21137                         [ $stripe_index -eq $default_index ] ||
21138                         error "$stripe_index != $default_index for $dir"
21139
21140                 #check default stripe
21141                 stripe_count=$($LFS getdirstripe -D -c $dir)
21142                 [ $stripe_count -eq $default_count ] ||
21143                 error "default count $default_count != $stripe_count for $dir"
21144
21145                 stripe_index=$($LFS getdirstripe -D -i $dir)
21146                 [ $stripe_index -eq $default_index ] ||
21147                 error "default index $default_index != $stripe_index for $dir"
21148         done
21149         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
21150 }
21151
21152 test_300g() {
21153         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21154         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21155                 skip "Need MDS version at least 2.7.55"
21156
21157         local dir
21158         local stripe_count
21159         local stripe_index
21160
21161         mkdir $DIR/$tdir
21162         mkdir $DIR/$tdir/normal_dir
21163
21164         #Checking when client cache stripe index
21165         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
21166         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
21167                 error "create striped_dir failed"
21168
21169         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
21170                 error "create dir0 fails"
21171         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
21172         [ $stripe_index -eq 0 ] ||
21173                 error "dir0 expect index 0 got $stripe_index"
21174
21175         mkdir $DIR/$tdir/striped_dir/dir1 ||
21176                 error "create dir1 fails"
21177         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
21178         [ $stripe_index -eq 1 ] ||
21179                 error "dir1 expect index 1 got $stripe_index"
21180
21181         #check default stripe count/stripe index
21182         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
21183         test_300_check_default_striped_dir normal_dir 1 0
21184         test_300_check_default_striped_dir normal_dir 2 1
21185         test_300_check_default_striped_dir normal_dir 2 -1
21186
21187         #delete default stripe information
21188         echo "delete default stripeEA"
21189         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
21190                 error "set default stripe on striped dir error"
21191
21192         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
21193         for dir in $(find $DIR/$tdir/normal_dir/*); do
21194                 stripe_count=$($LFS getdirstripe -c $dir)
21195                 [ $stripe_count -eq 0 ] ||
21196                         error "expect 1 get $stripe_count for $dir"
21197                 stripe_index=$($LFS getdirstripe -i $dir)
21198                 [ $stripe_index -eq 0 ] ||
21199                         error "expect 0 get $stripe_index for $dir"
21200         done
21201 }
21202 run_test 300g "check default striped directory for normal directory"
21203
21204 test_300h() {
21205         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21206         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21207                 skip "Need MDS version at least 2.7.55"
21208
21209         local dir
21210         local stripe_count
21211
21212         mkdir $DIR/$tdir
21213         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21214                 error "set striped dir error"
21215
21216         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
21217         test_300_check_default_striped_dir striped_dir 1 0
21218         test_300_check_default_striped_dir striped_dir 2 1
21219         test_300_check_default_striped_dir striped_dir 2 -1
21220
21221         #delete default stripe information
21222         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
21223                 error "set default stripe on striped dir error"
21224
21225         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
21226         for dir in $(find $DIR/$tdir/striped_dir/*); do
21227                 stripe_count=$($LFS getdirstripe -c $dir)
21228                 [ $stripe_count -eq 0 ] ||
21229                         error "expect 1 get $stripe_count for $dir"
21230         done
21231 }
21232 run_test 300h "check default striped directory for striped directory"
21233
21234 test_300i() {
21235         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21236         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21237         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21238                 skip "Need MDS version at least 2.7.55"
21239
21240         local stripe_count
21241         local file
21242
21243         mkdir $DIR/$tdir
21244
21245         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21246                 error "set striped dir error"
21247
21248         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
21249                 error "create files under striped dir failed"
21250
21251         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
21252                 error "set striped hashdir error"
21253
21254         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
21255                 error "create dir0 under hash dir failed"
21256         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
21257                 error "create dir1 under hash dir failed"
21258
21259         # unfortunately, we need to umount to clear dir layout cache for now
21260         # once we fully implement dir layout, we can drop this
21261         umount_client $MOUNT || error "umount failed"
21262         mount_client $MOUNT || error "mount failed"
21263
21264         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
21265         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
21266         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
21267
21268         #set the stripe to be unknown hash type
21269         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
21270         $LCTL set_param fail_loc=0x1901
21271         for ((i = 0; i < 10; i++)); do
21272                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
21273                         error "stat f-$i failed"
21274                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
21275         done
21276
21277         touch $DIR/$tdir/striped_dir/f0 &&
21278                 error "create under striped dir with unknown hash should fail"
21279
21280         $LCTL set_param fail_loc=0
21281
21282         umount_client $MOUNT || error "umount failed"
21283         mount_client $MOUNT || error "mount failed"
21284
21285         return 0
21286 }
21287 run_test 300i "client handle unknown hash type striped directory"
21288
21289 test_300j() {
21290         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21291         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21292         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21293                 skip "Need MDS version at least 2.7.55"
21294
21295         local stripe_count
21296         local file
21297
21298         mkdir $DIR/$tdir
21299
21300         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
21301         $LCTL set_param fail_loc=0x1702
21302         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21303                 error "set striped dir error"
21304
21305         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
21306                 error "create files under striped dir failed"
21307
21308         $LCTL set_param fail_loc=0
21309
21310         rm -rf $DIR/$tdir || error "unlink striped dir fails"
21311
21312         return 0
21313 }
21314 run_test 300j "test large update record"
21315
21316 test_300k() {
21317         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21318         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21319         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21320                 skip "Need MDS version at least 2.7.55"
21321
21322         # this test needs a huge transaction
21323         local kb
21324         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21325              osd*.$FSNAME-MDT0000.kbytestotal")
21326         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
21327
21328         local stripe_count
21329         local file
21330
21331         mkdir $DIR/$tdir
21332
21333         #define OBD_FAIL_LARGE_STRIPE   0x1703
21334         $LCTL set_param fail_loc=0x1703
21335         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
21336                 error "set striped dir error"
21337         $LCTL set_param fail_loc=0
21338
21339         $LFS getdirstripe $DIR/$tdir/striped_dir ||
21340                 error "getstripeddir fails"
21341         rm -rf $DIR/$tdir/striped_dir ||
21342                 error "unlink striped dir fails"
21343
21344         return 0
21345 }
21346 run_test 300k "test large striped directory"
21347
21348 test_300l() {
21349         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21350         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21351         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21352                 skip "Need MDS version at least 2.7.55"
21353
21354         local stripe_index
21355
21356         test_mkdir -p $DIR/$tdir/striped_dir
21357         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
21358                         error "chown $RUNAS_ID failed"
21359         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
21360                 error "set default striped dir failed"
21361
21362         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
21363         $LCTL set_param fail_loc=0x80000158
21364         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
21365
21366         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
21367         [ $stripe_index -eq 1 ] ||
21368                 error "expect 1 get $stripe_index for $dir"
21369 }
21370 run_test 300l "non-root user to create dir under striped dir with stale layout"
21371
21372 test_300m() {
21373         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21374         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
21375         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21376                 skip "Need MDS version at least 2.7.55"
21377
21378         mkdir -p $DIR/$tdir/striped_dir
21379         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
21380                 error "set default stripes dir error"
21381
21382         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
21383
21384         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
21385         [ $stripe_count -eq 0 ] ||
21386                         error "expect 0 get $stripe_count for a"
21387
21388         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
21389                 error "set default stripes dir error"
21390
21391         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
21392
21393         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
21394         [ $stripe_count -eq 0 ] ||
21395                         error "expect 0 get $stripe_count for b"
21396
21397         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
21398                 error "set default stripes dir error"
21399
21400         mkdir $DIR/$tdir/striped_dir/c &&
21401                 error "default stripe_index is invalid, mkdir c should fails"
21402
21403         rm -rf $DIR/$tdir || error "rmdir fails"
21404 }
21405 run_test 300m "setstriped directory on single MDT FS"
21406
21407 cleanup_300n() {
21408         local list=$(comma_list $(mdts_nodes))
21409
21410         trap 0
21411         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21412 }
21413
21414 test_300n() {
21415         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21416         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21417         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21418                 skip "Need MDS version at least 2.7.55"
21419         remote_mds_nodsh && skip "remote MDS with nodsh"
21420
21421         local stripe_index
21422         local list=$(comma_list $(mdts_nodes))
21423
21424         trap cleanup_300n RETURN EXIT
21425         mkdir -p $DIR/$tdir
21426         chmod 777 $DIR/$tdir
21427         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
21428                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
21429                 error "create striped dir succeeds with gid=0"
21430
21431         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
21432         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
21433                 error "create striped dir fails with gid=-1"
21434
21435         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21436         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
21437                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
21438                 error "set default striped dir succeeds with gid=0"
21439
21440
21441         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
21442         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
21443                 error "set default striped dir fails with gid=-1"
21444
21445
21446         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21447         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
21448                                         error "create test_dir fails"
21449         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
21450                                         error "create test_dir1 fails"
21451         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
21452                                         error "create test_dir2 fails"
21453         cleanup_300n
21454 }
21455 run_test 300n "non-root user to create dir under striped dir with default EA"
21456
21457 test_300o() {
21458         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21459         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21460         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21461                 skip "Need MDS version at least 2.7.55"
21462
21463         local numfree1
21464         local numfree2
21465
21466         mkdir -p $DIR/$tdir
21467
21468         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
21469         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
21470         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
21471                 skip "not enough free inodes $numfree1 $numfree2"
21472         fi
21473
21474         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
21475         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
21476         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
21477                 skip "not enough free space $numfree1 $numfree2"
21478         fi
21479
21480         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
21481                 error "setdirstripe fails"
21482
21483         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
21484                 error "create dirs fails"
21485
21486         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
21487         ls $DIR/$tdir/striped_dir > /dev/null ||
21488                 error "ls striped dir fails"
21489         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
21490                 error "unlink big striped dir fails"
21491 }
21492 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
21493
21494 test_300p() {
21495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21496         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21497         remote_mds_nodsh && skip "remote MDS with nodsh"
21498
21499         mkdir -p $DIR/$tdir
21500
21501         #define OBD_FAIL_OUT_ENOSPC     0x1704
21502         do_facet mds2 lctl set_param fail_loc=0x80001704
21503         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
21504                  && error "create striped directory should fail"
21505
21506         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
21507
21508         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
21509         true
21510 }
21511 run_test 300p "create striped directory without space"
21512
21513 test_300q() {
21514         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21515         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21516
21517         local fd=$(free_fd)
21518         local cmd="exec $fd<$tdir"
21519         cd $DIR
21520         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
21521         eval $cmd
21522         cmd="exec $fd<&-"
21523         trap "eval $cmd" EXIT
21524         cd $tdir || error "cd $tdir fails"
21525         rmdir  ../$tdir || error "rmdir $tdir fails"
21526         mkdir local_dir && error "create dir succeeds"
21527         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
21528         eval $cmd
21529         return 0
21530 }
21531 run_test 300q "create remote directory under orphan directory"
21532
21533 test_300r() {
21534         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21535                 skip "Need MDS version at least 2.7.55" && return
21536         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
21537
21538         mkdir $DIR/$tdir
21539
21540         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
21541                 error "set striped dir error"
21542
21543         $LFS getdirstripe $DIR/$tdir/striped_dir ||
21544                 error "getstripeddir fails"
21545
21546         local stripe_count
21547         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
21548                       awk '/lmv_stripe_count:/ { print $2 }')
21549
21550         [ $MDSCOUNT -ne $stripe_count ] &&
21551                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
21552
21553         rm -rf $DIR/$tdir/striped_dir ||
21554                 error "unlink striped dir fails"
21555 }
21556 run_test 300r "test -1 striped directory"
21557
21558 prepare_remote_file() {
21559         mkdir $DIR/$tdir/src_dir ||
21560                 error "create remote source failed"
21561
21562         cp /etc/hosts $DIR/$tdir/src_dir/a ||
21563                  error "cp to remote source failed"
21564         touch $DIR/$tdir/src_dir/a
21565
21566         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
21567                 error "create remote target dir failed"
21568
21569         touch $DIR/$tdir/tgt_dir/b
21570
21571         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
21572                 error "rename dir cross MDT failed!"
21573
21574         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
21575                 error "src_child still exists after rename"
21576
21577         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
21578                 error "missing file(a) after rename"
21579
21580         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
21581                 error "diff after rename"
21582 }
21583
21584 test_310a() {
21585         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
21586         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21587
21588         local remote_file=$DIR/$tdir/tgt_dir/b
21589
21590         mkdir -p $DIR/$tdir
21591
21592         prepare_remote_file || error "prepare remote file failed"
21593
21594         #open-unlink file
21595         $OPENUNLINK $remote_file $remote_file ||
21596                 error "openunlink $remote_file failed"
21597         $CHECKSTAT -a $remote_file || error "$remote_file exists"
21598 }
21599 run_test 310a "open unlink remote file"
21600
21601 test_310b() {
21602         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
21603         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21604
21605         local remote_file=$DIR/$tdir/tgt_dir/b
21606
21607         mkdir -p $DIR/$tdir
21608
21609         prepare_remote_file || error "prepare remote file failed"
21610
21611         ln $remote_file $DIR/$tfile || error "link failed for remote file"
21612         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
21613         $CHECKSTAT -t file $remote_file || error "check file failed"
21614 }
21615 run_test 310b "unlink remote file with multiple links while open"
21616
21617 test_310c() {
21618         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21619         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
21620
21621         local remote_file=$DIR/$tdir/tgt_dir/b
21622
21623         mkdir -p $DIR/$tdir
21624
21625         prepare_remote_file || error "prepare remote file failed"
21626
21627         ln $remote_file $DIR/$tfile || error "link failed for remote file"
21628         multiop_bg_pause $remote_file O_uc ||
21629                         error "mulitop failed for remote file"
21630         MULTIPID=$!
21631         $MULTIOP $DIR/$tfile Ouc
21632         kill -USR1 $MULTIPID
21633         wait $MULTIPID
21634 }
21635 run_test 310c "open-unlink remote file with multiple links"
21636
21637 #LU-4825
21638 test_311() {
21639         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21640         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
21641         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
21642                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
21643         remote_mds_nodsh && skip "remote MDS with nodsh"
21644
21645         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
21646         local mdts=$(comma_list $(mdts_nodes))
21647
21648         mkdir -p $DIR/$tdir
21649         $LFS setstripe -i 0 -c 1 $DIR/$tdir
21650         createmany -o $DIR/$tdir/$tfile. 1000
21651
21652         # statfs data is not real time, let's just calculate it
21653         old_iused=$((old_iused + 1000))
21654
21655         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21656                         osp.*OST0000*MDT0000.create_count")
21657         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21658                                 osp.*OST0000*MDT0000.max_create_count")
21659         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
21660
21661         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
21662         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
21663         [ $index -ne 0 ] || error "$tfile stripe index is 0"
21664
21665         unlinkmany $DIR/$tdir/$tfile. 1000
21666
21667         do_nodes $mdts "$LCTL set_param -n \
21668                         osp.*OST0000*.max_create_count=$max_count"
21669         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
21670                 do_nodes $mdts "$LCTL set_param -n \
21671                                 osp.*OST0000*.create_count=$count"
21672         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
21673                         grep "=0" && error "create_count is zero"
21674
21675         local new_iused
21676         for i in $(seq 120); do
21677                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
21678                 # system may be too busy to destroy all objs in time, use
21679                 # a somewhat small value to not fail autotest
21680                 [ $((old_iused - new_iused)) -gt 400 ] && break
21681                 sleep 1
21682         done
21683
21684         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
21685         [ $((old_iused - new_iused)) -gt 400 ] ||
21686                 error "objs not destroyed after unlink"
21687 }
21688 run_test 311 "disable OSP precreate, and unlink should destroy objs"
21689
21690 zfs_oid_to_objid()
21691 {
21692         local ost=$1
21693         local objid=$2
21694
21695         local vdevdir=$(dirname $(facet_vdevice $ost))
21696         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
21697         local zfs_zapid=$(do_facet $ost $cmd |
21698                           grep -w "/O/0/d$((objid%32))" -C 5 |
21699                           awk '/Object/{getline; print $1}')
21700         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
21701                           awk "/$objid = /"'{printf $3}')
21702
21703         echo $zfs_objid
21704 }
21705
21706 zfs_object_blksz() {
21707         local ost=$1
21708         local objid=$2
21709
21710         local vdevdir=$(dirname $(facet_vdevice $ost))
21711         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
21712         local blksz=$(do_facet $ost $cmd $objid |
21713                       awk '/dblk/{getline; printf $4}')
21714
21715         case "${blksz: -1}" in
21716                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
21717                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
21718                 *) ;;
21719         esac
21720
21721         echo $blksz
21722 }
21723
21724 test_312() { # LU-4856
21725         remote_ost_nodsh && skip "remote OST with nodsh"
21726         [ "$ost1_FSTYPE" = "zfs" ] ||
21727                 skip_env "the test only applies to zfs"
21728
21729         local max_blksz=$(do_facet ost1 \
21730                           $ZFS get -p recordsize $(facet_device ost1) |
21731                           awk '!/VALUE/{print $3}')
21732
21733         # to make life a little bit easier
21734         $LFS mkdir -c 1 -i 0 $DIR/$tdir
21735         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21736
21737         local tf=$DIR/$tdir/$tfile
21738         touch $tf
21739         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
21740
21741         # Get ZFS object id
21742         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
21743         # block size change by sequential overwrite
21744         local bs
21745
21746         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
21747                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
21748
21749                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
21750                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
21751         done
21752         rm -f $tf
21753
21754         # block size change by sequential append write
21755         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
21756         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
21757         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
21758         local count
21759
21760         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
21761                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
21762                         oflag=sync conv=notrunc
21763
21764                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
21765                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
21766                         error "blksz error, actual $blksz, " \
21767                                 "expected: 2 * $count * $PAGE_SIZE"
21768         done
21769         rm -f $tf
21770
21771         # random write
21772         touch $tf
21773         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
21774         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
21775
21776         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
21777         blksz=$(zfs_object_blksz ost1 $zfs_objid)
21778         [ $blksz -eq $PAGE_SIZE ] ||
21779                 error "blksz error: $blksz, expected: $PAGE_SIZE"
21780
21781         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
21782         blksz=$(zfs_object_blksz ost1 $zfs_objid)
21783         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
21784
21785         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
21786         blksz=$(zfs_object_blksz ost1 $zfs_objid)
21787         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
21788 }
21789 run_test 312 "make sure ZFS adjusts its block size by write pattern"
21790
21791 test_313() {
21792         remote_ost_nodsh && skip "remote OST with nodsh"
21793
21794         local file=$DIR/$tfile
21795
21796         rm -f $file
21797         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
21798
21799         # define OBD_FAIL_TGT_RCVD_EIO           0x720
21800         do_facet ost1 "$LCTL set_param fail_loc=0x720"
21801         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
21802                 error "write should failed"
21803         do_facet ost1 "$LCTL set_param fail_loc=0"
21804         rm -f $file
21805 }
21806 run_test 313 "io should fail after last_rcvd update fail"
21807
21808 test_314() {
21809         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
21810
21811         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
21812         do_facet ost1 "$LCTL set_param fail_loc=0x720"
21813         rm -f $DIR/$tfile
21814         wait_delete_completed
21815         do_facet ost1 "$LCTL set_param fail_loc=0"
21816 }
21817 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
21818
21819 test_315() { # LU-618
21820         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
21821
21822         local file=$DIR/$tfile
21823         rm -f $file
21824
21825         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
21826                 error "multiop file write failed"
21827         $MULTIOP $file oO_RDONLY:r4063232_c &
21828         PID=$!
21829
21830         sleep 2
21831
21832         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
21833         kill -USR1 $PID
21834
21835         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
21836         rm -f $file
21837 }
21838 run_test 315 "read should be accounted"
21839
21840 test_316() {
21841         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21842         large_xattr_enabled || skip_env "ea_inode feature disabled"
21843
21844         rm -rf $DIR/$tdir/d
21845         mkdir -p $DIR/$tdir/d
21846         chown nobody $DIR/$tdir/d
21847         touch $DIR/$tdir/d/file
21848
21849         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
21850 }
21851 run_test 316 "lfs mv"
21852
21853 test_317() {
21854         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
21855                 skip "Need MDS version at least 2.11.53"
21856         if [ "$ost1_FSTYPE" == "zfs" ]; then
21857                 skip "LU-10370: no implementation for ZFS"
21858         fi
21859
21860         local trunc_sz
21861         local grant_blk_size
21862
21863         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
21864                         awk '/grant_block_size:/ { print $2; exit; }')
21865         #
21866         # Create File of size 5M. Truncate it to below size's and verify
21867         # blocks count.
21868         #
21869         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
21870                 error "Create file $DIR/$tfile failed"
21871         stack_trap "rm -f $DIR/$tfile" EXIT
21872
21873         for trunc_sz in 2097152 4097 4000 509 0; do
21874                 $TRUNCATE $DIR/$tfile $trunc_sz ||
21875                         error "truncate $tfile to $trunc_sz failed"
21876                 local sz=$(stat --format=%s $DIR/$tfile)
21877                 local blk=$(stat --format=%b $DIR/$tfile)
21878                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
21879                                      grant_blk_size) * 8))
21880
21881                 if [[ $blk -ne $trunc_blk ]]; then
21882                         $(which stat) $DIR/$tfile
21883                         error "Expected Block $trunc_blk got $blk for $tfile"
21884                 fi
21885
21886                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
21887                         error "Expected Size $trunc_sz got $sz for $tfile"
21888         done
21889
21890         #
21891         # sparse file test
21892         # Create file with a hole and write actual two blocks. Block count
21893         # must be 16.
21894         #
21895         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
21896                 conv=fsync || error "Create file : $DIR/$tfile"
21897
21898         # Calculate the final truncate size.
21899         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
21900
21901         #
21902         # truncate to size $trunc_sz bytes. Strip the last block
21903         # The block count must drop to 8
21904         #
21905         $TRUNCATE $DIR/$tfile $trunc_sz ||
21906                 error "truncate $tfile to $trunc_sz failed"
21907
21908         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
21909         sz=$(stat --format=%s $DIR/$tfile)
21910         blk=$(stat --format=%b $DIR/$tfile)
21911
21912         if [[ $blk -ne $trunc_bsz ]]; then
21913                 $(which stat) $DIR/$tfile
21914                 error "Expected Block $trunc_bsz got $blk for $tfile"
21915         fi
21916
21917         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
21918                 error "Expected Size $trunc_sz got $sz for $tfile"
21919 }
21920 run_test 317 "Verify blocks get correctly update after truncate"
21921
21922 test_318() {
21923         local old_max_active=$($LCTL get_param -n \
21924                             llite.*.max_read_ahead_async_active 2>/dev/null)
21925
21926         $LCTL set_param llite.*.max_read_ahead_async_active=256
21927         local max_active=$($LCTL get_param -n \
21928                            llite.*.max_read_ahead_async_active 2>/dev/null)
21929         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
21930
21931         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
21932                 error "set max_read_ahead_async_active should succeed"
21933
21934         $LCTL set_param llite.*.max_read_ahead_async_active=512
21935         max_active=$($LCTL get_param -n \
21936                      llite.*.max_read_ahead_async_active 2>/dev/null)
21937         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
21938
21939         # restore @max_active
21940         [ $old_max_active -ne 0 ] && $LCTL set_param \
21941                 llite.*.max_read_ahead_async_active=$old_max_active
21942
21943         local old_threshold=$($LCTL get_param -n \
21944                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
21945         local max_per_file_mb=$($LCTL get_param -n \
21946                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
21947
21948         local invalid=$(($max_per_file_mb + 1))
21949         $LCTL set_param \
21950                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
21951                         && error "set $invalid should fail"
21952
21953         local valid=$(($invalid - 1))
21954         $LCTL set_param \
21955                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
21956                         error "set $valid should succeed"
21957         local threshold=$($LCTL get_param -n \
21958                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
21959         [ $threshold -eq $valid ] || error \
21960                 "expect threshold $valid got $threshold"
21961         $LCTL set_param \
21962                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
21963 }
21964 run_test 318 "Verify async readahead tunables"
21965
21966 test_319() {
21967         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
21968
21969         local before=$(date +%s)
21970         local evict
21971         local mdir=$DIR/$tdir
21972         local file=$mdir/xxx
21973
21974         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
21975         touch $file
21976
21977 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
21978         $LCTL set_param fail_val=5 fail_loc=0x8000032c
21979         $LFS mv -m1 $file &
21980
21981         sleep 1
21982         dd if=$file of=/dev/null
21983         wait
21984         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
21985           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
21986
21987         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
21988 }
21989 run_test 319 "lost lease lock on migrate error"
21990
21991 test_398a() { # LU-4198
21992         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21993         $LCTL set_param ldlm.namespaces.*.lru_size=clear
21994
21995         # request a new lock on client
21996         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
21997
21998         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
21999         local lock_count=$($LCTL get_param -n \
22000                            ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
22001         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
22002
22003         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
22004
22005         # no lock cached, should use lockless IO and not enqueue new lock
22006         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
22007         lock_count=$($LCTL get_param -n \
22008                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
22009         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
22010 }
22011 run_test 398a "direct IO should cancel lock otherwise lockless"
22012
22013 test_398b() { # LU-4198
22014         which fio || skip_env "no fio installed"
22015         $LFS setstripe -c -1 $DIR/$tfile
22016
22017         local size=12
22018         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
22019
22020         local njobs=4
22021         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
22022         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
22023                 --numjobs=$njobs --fallocate=none \
22024                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22025                 --filename=$DIR/$tfile &
22026         bg_pid=$!
22027
22028         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
22029         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
22030                 --numjobs=$njobs --fallocate=none \
22031                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22032                 --filename=$DIR/$tfile || true
22033         wait $bg_pid
22034
22035         rm -rf $DIR/$tfile
22036 }
22037 run_test 398b "DIO and buffer IO race"
22038
22039 test_398c() { # LU-4198
22040         which fio || skip_env "no fio installed"
22041
22042         saved_debug=$($LCTL get_param -n debug)
22043         $LCTL set_param debug=0
22044
22045         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
22046         ((size /= 1024)) # by megabytes
22047         ((size /= 2)) # write half of the OST at most
22048         [ $size -gt 40 ] && size=40 #reduce test time anyway
22049
22050         $LFS setstripe -c 1 $DIR/$tfile
22051
22052         # it seems like ldiskfs reserves more space than necessary if the
22053         # writing blocks are not mapped, so it extends the file firstly
22054         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
22055         cancel_lru_locks osc
22056
22057         # clear and verify rpc_stats later
22058         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
22059
22060         local njobs=4
22061         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
22062         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
22063                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
22064                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22065                 --filename=$DIR/$tfile
22066         [ $? -eq 0 ] || error "fio write error"
22067
22068         [ $($LCTL get_param -n \
22069          ldlm.namespaces.${FSNAME}-OST0000-osc-ffff*.lock_count) -eq 0 ] ||
22070                 error "Locks were requested while doing AIO"
22071
22072         # get the percentage of 1-page I/O
22073         pct=$($LCTL get_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats |
22074                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
22075                 awk '{print $7}')
22076         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
22077
22078         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
22079         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
22080                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
22081                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22082                 --filename=$DIR/$tfile
22083         [ $? -eq 0 ] || error "fio mixed read write error"
22084
22085         echo "AIO with large block size ${size}M"
22086         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
22087                 --numjobs=1 --fallocate=none --ioengine=libaio \
22088                 --iodepth=16 --allow_file_create=0 --size=${size}M \
22089                 --filename=$DIR/$tfile
22090         [ $? -eq 0 ] || error "fio large block size failed"
22091
22092         rm -rf $DIR/$tfile
22093         $LCTL set_param debug="$saved_debug"
22094 }
22095 run_test 398c "run fio to test AIO"
22096
22097 test_398d() { #  LU-13846
22098         test -f aiocp || skip_env "no aiocp installed"
22099         local aio_file=$DIR/aio_file
22100
22101         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
22102
22103         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
22104         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
22105
22106         diff $DIR/$tfile $aio_file || "file diff after aiocp"
22107
22108         # make sure we don't crash and fail properly
22109         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
22110                 error "aio not aligned with PAGE SIZE should fail"
22111
22112         rm -rf $DIR/$tfile $aio_file
22113 }
22114 run_test 398d "run aiocp to verify block size > stripe size"
22115
22116 test_fake_rw() {
22117         local read_write=$1
22118         if [ "$read_write" = "write" ]; then
22119                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
22120         elif [ "$read_write" = "read" ]; then
22121                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
22122         else
22123                 error "argument error"
22124         fi
22125
22126         # turn off debug for performance testing
22127         local saved_debug=$($LCTL get_param -n debug)
22128         $LCTL set_param debug=0
22129
22130         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22131
22132         # get ost1 size - $FSNAME-OST0000
22133         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
22134         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
22135         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
22136
22137         if [ "$read_write" = "read" ]; then
22138                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
22139         fi
22140
22141         local start_time=$(date +%s.%N)
22142         $dd_cmd bs=1M count=$blocks oflag=sync ||
22143                 error "real dd $read_write error"
22144         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
22145
22146         if [ "$read_write" = "write" ]; then
22147                 rm -f $DIR/$tfile
22148         fi
22149
22150         # define OBD_FAIL_OST_FAKE_RW           0x238
22151         do_facet ost1 $LCTL set_param fail_loc=0x238
22152
22153         local start_time=$(date +%s.%N)
22154         $dd_cmd bs=1M count=$blocks oflag=sync ||
22155                 error "fake dd $read_write error"
22156         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
22157
22158         if [ "$read_write" = "write" ]; then
22159                 # verify file size
22160                 cancel_lru_locks osc
22161                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
22162                         error "$tfile size not $blocks MB"
22163         fi
22164         do_facet ost1 $LCTL set_param fail_loc=0
22165
22166         echo "fake $read_write $duration_fake vs. normal $read_write" \
22167                 "$duration in seconds"
22168         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
22169                 error_not_in_vm "fake write is slower"
22170
22171         $LCTL set_param -n debug="$saved_debug"
22172         rm -f $DIR/$tfile
22173 }
22174 test_399a() { # LU-7655 for OST fake write
22175         remote_ost_nodsh && skip "remote OST with nodsh"
22176
22177         test_fake_rw write
22178 }
22179 run_test 399a "fake write should not be slower than normal write"
22180
22181 test_399b() { # LU-8726 for OST fake read
22182         remote_ost_nodsh && skip "remote OST with nodsh"
22183         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
22184                 skip_env "ldiskfs only test"
22185         fi
22186
22187         test_fake_rw read
22188 }
22189 run_test 399b "fake read should not be slower than normal read"
22190
22191 test_400a() { # LU-1606, was conf-sanity test_74
22192         if ! which $CC > /dev/null 2>&1; then
22193                 skip_env "$CC is not installed"
22194         fi
22195
22196         local extra_flags=''
22197         local out=$TMP/$tfile
22198         local prefix=/usr/include/lustre
22199         local prog
22200
22201         # Oleg removes c files in his test rig so test if any c files exist
22202         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
22203                 skip_env "Needed c test files are missing"
22204
22205         if ! [[ -d $prefix ]]; then
22206                 # Assume we're running in tree and fixup the include path.
22207                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
22208                 extra_flags+=" -L$LUSTRE/utils/.lib"
22209         fi
22210
22211         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
22212                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
22213                         error "client api broken"
22214         done
22215         rm -f $out
22216 }
22217 run_test 400a "Lustre client api program can compile and link"
22218
22219 test_400b() { # LU-1606, LU-5011
22220         local header
22221         local out=$TMP/$tfile
22222         local prefix=/usr/include/linux/lustre
22223
22224         # We use a hard coded prefix so that this test will not fail
22225         # when run in tree. There are headers in lustre/include/lustre/
22226         # that are not packaged (like lustre_idl.h) and have more
22227         # complicated include dependencies (like config.h and lnet/types.h).
22228         # Since this test about correct packaging we just skip them when
22229         # they don't exist (see below) rather than try to fixup cppflags.
22230
22231         if ! which $CC > /dev/null 2>&1; then
22232                 skip_env "$CC is not installed"
22233         fi
22234
22235         for header in $prefix/*.h; do
22236                 if ! [[ -f "$header" ]]; then
22237                         continue
22238                 fi
22239
22240                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
22241                         continue # lustre_ioctl.h is internal header
22242                 fi
22243
22244                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
22245                         error "cannot compile '$header'"
22246         done
22247         rm -f $out
22248 }
22249 run_test 400b "packaged headers can be compiled"
22250
22251 test_401a() { #LU-7437
22252         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
22253         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
22254
22255         #count the number of parameters by "list_param -R"
22256         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
22257         #count the number of parameters by listing proc files
22258         local proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
22259         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
22260         echo "proc_dirs='$proc_dirs'"
22261         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
22262         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
22263                       sort -u | wc -l)
22264
22265         [ $params -eq $procs ] ||
22266                 error "found $params parameters vs. $procs proc files"
22267
22268         # test the list_param -D option only returns directories
22269         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
22270         #count the number of parameters by listing proc directories
22271         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
22272                 sort -u | wc -l)
22273
22274         [ $params -eq $procs ] ||
22275                 error "found $params parameters vs. $procs proc files"
22276 }
22277 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
22278
22279 test_401b() {
22280         # jobid_var may not allow arbitrary values, so use jobid_name
22281         # if available
22282         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22283                 local testname=jobid_name tmp='testing%p'
22284         else
22285                 local testname=jobid_var tmp=testing
22286         fi
22287
22288         local save=$($LCTL get_param -n $testname)
22289
22290         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
22291                 error "no error returned when setting bad parameters"
22292
22293         local jobid_new=$($LCTL get_param -n foe $testname baz)
22294         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
22295
22296         $LCTL set_param -n fog=bam $testname=$save bat=fog
22297         local jobid_old=$($LCTL get_param -n foe $testname bag)
22298         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
22299 }
22300 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
22301
22302 test_401c() {
22303         # jobid_var may not allow arbitrary values, so use jobid_name
22304         # if available
22305         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22306                 local testname=jobid_name
22307         else
22308                 local testname=jobid_var
22309         fi
22310
22311         local jobid_var_old=$($LCTL get_param -n $testname)
22312         local jobid_var_new
22313
22314         $LCTL set_param $testname= &&
22315                 error "no error returned for 'set_param a='"
22316
22317         jobid_var_new=$($LCTL get_param -n $testname)
22318         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
22319                 error "$testname was changed by setting without value"
22320
22321         $LCTL set_param $testname &&
22322                 error "no error returned for 'set_param a'"
22323
22324         jobid_var_new=$($LCTL get_param -n $testname)
22325         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
22326                 error "$testname was changed by setting without value"
22327 }
22328 run_test 401c "Verify 'lctl set_param' without value fails in either format."
22329
22330 test_401d() {
22331         # jobid_var may not allow arbitrary values, so use jobid_name
22332         # if available
22333         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22334                 local testname=jobid_name new_value='foo=bar%p'
22335         else
22336                 local testname=jobid_var new_valuie=foo=bar
22337         fi
22338
22339         local jobid_var_old=$($LCTL get_param -n $testname)
22340         local jobid_var_new
22341
22342         $LCTL set_param $testname=$new_value ||
22343                 error "'set_param a=b' did not accept a value containing '='"
22344
22345         jobid_var_new=$($LCTL get_param -n $testname)
22346         [[ "$jobid_var_new" == "$new_value" ]] ||
22347                 error "'set_param a=b' failed on a value containing '='"
22348
22349         # Reset the $testname to test the other format
22350         $LCTL set_param $testname=$jobid_var_old
22351         jobid_var_new=$($LCTL get_param -n $testname)
22352         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
22353                 error "failed to reset $testname"
22354
22355         $LCTL set_param $testname $new_value ||
22356                 error "'set_param a b' did not accept a value containing '='"
22357
22358         jobid_var_new=$($LCTL get_param -n $testname)
22359         [[ "$jobid_var_new" == "$new_value" ]] ||
22360                 error "'set_param a b' failed on a value containing '='"
22361
22362         $LCTL set_param $testname $jobid_var_old
22363         jobid_var_new=$($LCTL get_param -n $testname)
22364         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
22365                 error "failed to reset $testname"
22366 }
22367 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
22368
22369 test_402() {
22370         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
22371         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
22372                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
22373         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
22374                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
22375                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
22376         remote_mds_nodsh && skip "remote MDS with nodsh"
22377
22378         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
22379 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
22380         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
22381         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
22382                 echo "Touch failed - OK"
22383 }
22384 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
22385
22386 test_403() {
22387         local file1=$DIR/$tfile.1
22388         local file2=$DIR/$tfile.2
22389         local tfile=$TMP/$tfile
22390
22391         rm -f $file1 $file2 $tfile
22392
22393         touch $file1
22394         ln $file1 $file2
22395
22396         # 30 sec OBD_TIMEOUT in ll_getattr()
22397         # right before populating st_nlink
22398         $LCTL set_param fail_loc=0x80001409
22399         stat -c %h $file1 > $tfile &
22400
22401         # create an alias, drop all locks and reclaim the dentry
22402         < $file2
22403         cancel_lru_locks mdc
22404         cancel_lru_locks osc
22405         sysctl -w vm.drop_caches=2
22406
22407         wait
22408
22409         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
22410
22411         rm -f $tfile $file1 $file2
22412 }
22413 run_test 403 "i_nlink should not drop to zero due to aliasing"
22414
22415 test_404() { # LU-6601
22416         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
22417                 skip "Need server version newer than 2.8.52"
22418         remote_mds_nodsh && skip "remote MDS with nodsh"
22419
22420         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
22421                 awk '/osp .*-osc-MDT/ { print $4}')
22422
22423         local osp
22424         for osp in $mosps; do
22425                 echo "Deactivate: " $osp
22426                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
22427                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
22428                         awk -vp=$osp '$4 == p { print $2 }')
22429                 [ $stat = IN ] || {
22430                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
22431                         error "deactivate error"
22432                 }
22433                 echo "Activate: " $osp
22434                 do_facet $SINGLEMDS $LCTL --device %$osp activate
22435                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
22436                         awk -vp=$osp '$4 == p { print $2 }')
22437                 [ $stat = UP ] || {
22438                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
22439                         error "activate error"
22440                 }
22441         done
22442 }
22443 run_test 404 "validate manual {de}activated works properly for OSPs"
22444
22445 test_405() {
22446         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
22447         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
22448                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
22449                         skip "Layout swap lock is not supported"
22450
22451         check_swap_layouts_support
22452         check_swap_layout_no_dom $DIR
22453
22454         test_mkdir $DIR/$tdir
22455         swap_lock_test -d $DIR/$tdir ||
22456                 error "One layout swap locked test failed"
22457 }
22458 run_test 405 "Various layout swap lock tests"
22459
22460 test_406() {
22461         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22462         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
22463         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
22464         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22465         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
22466                 skip "Need MDS version at least 2.8.50"
22467
22468         local def_stripe_size=$($LFS getstripe -S $MOUNT)
22469         local test_pool=$TESTNAME
22470
22471         pool_add $test_pool || error "pool_add failed"
22472         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
22473                 error "pool_add_targets failed"
22474
22475         save_layout_restore_at_exit $MOUNT
22476
22477         # parent set default stripe count only, child will stripe from both
22478         # parent and fs default
22479         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
22480                 error "setstripe $MOUNT failed"
22481         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
22482         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
22483         for i in $(seq 10); do
22484                 local f=$DIR/$tdir/$tfile.$i
22485                 touch $f || error "touch failed"
22486                 local count=$($LFS getstripe -c $f)
22487                 [ $count -eq $OSTCOUNT ] ||
22488                         error "$f stripe count $count != $OSTCOUNT"
22489                 local offset=$($LFS getstripe -i $f)
22490                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
22491                 local size=$($LFS getstripe -S $f)
22492                 [ $size -eq $((def_stripe_size * 2)) ] ||
22493                         error "$f stripe size $size != $((def_stripe_size * 2))"
22494                 local pool=$($LFS getstripe -p $f)
22495                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
22496         done
22497
22498         # change fs default striping, delete parent default striping, now child
22499         # will stripe from new fs default striping only
22500         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
22501                 error "change $MOUNT default stripe failed"
22502         $LFS setstripe -c 0 $DIR/$tdir ||
22503                 error "delete $tdir default stripe failed"
22504         for i in $(seq 11 20); do
22505                 local f=$DIR/$tdir/$tfile.$i
22506                 touch $f || error "touch $f failed"
22507                 local count=$($LFS getstripe -c $f)
22508                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
22509                 local offset=$($LFS getstripe -i $f)
22510                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
22511                 local size=$($LFS getstripe -S $f)
22512                 [ $size -eq $def_stripe_size ] ||
22513                         error "$f stripe size $size != $def_stripe_size"
22514                 local pool=$($LFS getstripe -p $f)
22515                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
22516         done
22517
22518         unlinkmany $DIR/$tdir/$tfile. 1 20
22519
22520         local f=$DIR/$tdir/$tfile
22521         pool_remove_all_targets $test_pool $f
22522         pool_remove $test_pool $f
22523 }
22524 run_test 406 "DNE support fs default striping"
22525
22526 test_407() {
22527         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22528         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
22529                 skip "Need MDS version at least 2.8.55"
22530         remote_mds_nodsh && skip "remote MDS with nodsh"
22531
22532         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
22533                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
22534         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
22535                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
22536         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
22537
22538         #define OBD_FAIL_DT_TXN_STOP    0x2019
22539         for idx in $(seq $MDSCOUNT); do
22540                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
22541         done
22542         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
22543         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
22544                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
22545         true
22546 }
22547 run_test 407 "transaction fail should cause operation fail"
22548
22549 test_408() {
22550         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
22551
22552         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
22553         lctl set_param fail_loc=0x8000040a
22554         # let ll_prepare_partial_page() fail
22555         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
22556
22557         rm -f $DIR/$tfile
22558
22559         # create at least 100 unused inodes so that
22560         # shrink_icache_memory(0) should not return 0
22561         touch $DIR/$tfile-{0..100}
22562         rm -f $DIR/$tfile-{0..100}
22563         sync
22564
22565         echo 2 > /proc/sys/vm/drop_caches
22566 }
22567 run_test 408 "drop_caches should not hang due to page leaks"
22568
22569 test_409()
22570 {
22571         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22572
22573         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
22574         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
22575         touch $DIR/$tdir/guard || error "(2) Fail to create"
22576
22577         local PREFIX=$(str_repeat 'A' 128)
22578         echo "Create 1K hard links start at $(date)"
22579         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
22580                 error "(3) Fail to hard link"
22581
22582         echo "Links count should be right although linkEA overflow"
22583         stat $DIR/$tdir/guard || error "(4) Fail to stat"
22584         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
22585         [ $linkcount -eq 1001 ] ||
22586                 error "(5) Unexpected hard links count: $linkcount"
22587
22588         echo "List all links start at $(date)"
22589         ls -l $DIR/$tdir/foo > /dev/null ||
22590                 error "(6) Fail to list $DIR/$tdir/foo"
22591
22592         echo "Unlink hard links start at $(date)"
22593         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
22594                 error "(7) Fail to unlink"
22595         echo "Unlink hard links finished at $(date)"
22596 }
22597 run_test 409 "Large amount of cross-MDTs hard links on the same file"
22598
22599 test_410()
22600 {
22601         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
22602                 skip "Need client version at least 2.9.59"
22603         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
22604                 skip "Need MODULES build"
22605
22606         # Create a file, and stat it from the kernel
22607         local testfile=$DIR/$tfile
22608         touch $testfile
22609
22610         local run_id=$RANDOM
22611         local my_ino=$(stat --format "%i" $testfile)
22612
22613         # Try to insert the module. This will always fail as the
22614         # module is designed to not be inserted.
22615         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
22616             &> /dev/null
22617
22618         # Anything but success is a test failure
22619         dmesg | grep -q \
22620             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
22621             error "no inode match"
22622 }
22623 run_test 410 "Test inode number returned from kernel thread"
22624
22625 cleanup_test411_cgroup() {
22626         trap 0
22627         rmdir "$1"
22628 }
22629
22630 test_411() {
22631         local cg_basedir=/sys/fs/cgroup/memory
22632         # LU-9966
22633         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
22634                 skip "no setup for cgroup"
22635
22636         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
22637                 error "test file creation failed"
22638         cancel_lru_locks osc
22639
22640         # Create a very small memory cgroup to force a slab allocation error
22641         local cgdir=$cg_basedir/osc_slab_alloc
22642         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
22643         trap "cleanup_test411_cgroup $cgdir" EXIT
22644         echo 2M > $cgdir/memory.kmem.limit_in_bytes
22645         echo 1M > $cgdir/memory.limit_in_bytes
22646
22647         # Should not LBUG, just be killed by oom-killer
22648         # dd will return 0 even allocation failure in some environment.
22649         # So don't check return value
22650         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
22651         cleanup_test411_cgroup $cgdir
22652
22653         return 0
22654 }
22655 run_test 411 "Slab allocation error with cgroup does not LBUG"
22656
22657 test_412() {
22658         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22659         if [ $MDS1_VERSION -lt $(version_code 2.10.55) ]; then
22660                 skip "Need server version at least 2.10.55"
22661         fi
22662
22663         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
22664                 error "mkdir failed"
22665         $LFS getdirstripe $DIR/$tdir
22666         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
22667         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
22668                 error "expect $((MDSCOUT - 1)) get $stripe_index"
22669         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
22670         [ $stripe_count -eq 2 ] ||
22671                 error "expect 2 get $stripe_count"
22672 }
22673 run_test 412 "mkdir on specific MDTs"
22674
22675 test_qos_mkdir() {
22676         local mkdir_cmd=$1
22677         local stripe_count=$2
22678         local mdts=$(comma_list $(mdts_nodes))
22679
22680         local testdir
22681         local lmv_qos_prio_free
22682         local lmv_qos_threshold_rr
22683         local lmv_qos_maxage
22684         local lod_qos_prio_free
22685         local lod_qos_threshold_rr
22686         local lod_qos_maxage
22687         local count
22688         local i
22689
22690         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
22691         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
22692         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
22693                 head -n1)
22694         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
22695         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
22696         stack_trap "$LCTL set_param \
22697                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null" EXIT
22698         stack_trap "$LCTL set_param \
22699                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
22700         stack_trap "$LCTL set_param \
22701                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" EXIT
22702
22703         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
22704                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
22705         lod_qos_prio_free=${lod_qos_prio_free%%%}
22706         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
22707                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
22708         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
22709         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
22710                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
22711         stack_trap "do_nodes $mdts $LCTL set_param \
22712                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null" EXIT
22713         stack_trap "do_nodes $mdts $LCTL set_param \
22714                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null" \
22715                 EXIT
22716         stack_trap "do_nodes $mdts $LCTL set_param \
22717                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" EXIT
22718
22719         echo
22720         echo "Mkdir (stripe_count $stripe_count) roundrobin:"
22721
22722         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
22723         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
22724
22725         testdir=$DIR/$tdir-s$stripe_count/rr
22726
22727         for i in $(seq $((100 * MDSCOUNT))); do
22728                 eval $mkdir_cmd $testdir/subdir$i ||
22729                         error "$mkdir_cmd subdir$i failed"
22730         done
22731
22732         for i in $(seq $MDSCOUNT); do
22733                 count=$($LFS getdirstripe -i $testdir/* |
22734                                 grep ^$((i - 1))$ | wc -l)
22735                 echo "$count directories created on MDT$((i - 1))"
22736                 [ $count -eq 100 ] || error "subdirs are not evenly distributed"
22737
22738                 if [ $stripe_count -gt 1 ]; then
22739                         count=$($LFS getdirstripe $testdir/* |
22740                                 grep -P "^\s+$((i - 1))\t" | wc -l)
22741                         echo "$count stripes created on MDT$((i - 1))"
22742                         # deviation should < 5% of average
22743                         [ $count -lt $((95 * stripe_count)) ] ||
22744                         [ $count -gt $((105 * stripe_count)) ] &&
22745                                 error "stripes are not evenly distributed"
22746                 fi
22747         done
22748
22749         $LCTL set_param lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null
22750         do_nodes $mdts $LCTL set_param \
22751                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null
22752
22753         echo
22754         echo "Check for uneven MDTs: "
22755
22756         local ffree
22757         local bavail
22758         local max
22759         local min
22760         local max_index
22761         local min_index
22762         local tmp
22763
22764         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
22765         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
22766         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
22767
22768         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
22769         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
22770         max_index=0
22771         min_index=0
22772         for ((i = 1; i < ${#ffree[@]}; i++)); do
22773                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
22774                 if [ $tmp -gt $max ]; then
22775                         max=$tmp
22776                         max_index=$i
22777                 fi
22778                 if [ $tmp -lt $min ]; then
22779                         min=$tmp
22780                         min_index=$i
22781                 fi
22782         done
22783
22784         [ ${ffree[min_index]} -eq 0 ] &&
22785                 skip "no free files in MDT$min_index"
22786         [ ${ffree[min_index]} -gt 100000000 ] &&
22787                 skip "too much free files in MDT$min_index"
22788
22789         # Check if we need to generate uneven MDTs
22790         local threshold=50
22791         local diff=$(((max - min) * 100 / min))
22792         local value="$(generate_string 1024)"
22793
22794         while [ $diff -lt $threshold ]; do
22795                 # generate uneven MDTs, create till $threshold% diff
22796                 echo -n "weight diff=$diff% must be > $threshold% ..."
22797                 count=$((${ffree[min_index]} / 10))
22798                 # 50 sec per 10000 files in vm
22799                 [ $count -gt 40000 ] && [ "$SLOW" = "no" ] &&
22800                         skip "$count files to create"
22801                 echo "Fill MDT$min_index with $count files"
22802                 [ -d $DIR/$tdir-MDT$min_index ] ||
22803                         $LFS mkdir -i $min_index $DIR/$tdir-MDT$min_index ||
22804                         error "mkdir $tdir-MDT$min_index failed"
22805                 for i in $(seq $count); do
22806                         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE \
22807                                 $DIR/$tdir-MDT$min_index/f$j_$i > /dev/null ||
22808                                 error "create f$j_$i failed"
22809                         setfattr -n user.413b -v $value \
22810                                 $DIR/$tdir-MDT$min_index/f$j_$i ||
22811                                 error "setfattr f$j_$i failed"
22812                 done
22813
22814                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
22815                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
22816                 max=$(((${ffree[max_index]} >> 8) * \
22817                         (${bavail[max_index]} * bsize >> 16)))
22818                 min=$(((${ffree[min_index]} >> 8) * \
22819                         (${bavail[min_index]} * bsize >> 16)))
22820                 diff=$(((max - min) * 100 / min))
22821         done
22822
22823         echo "MDT filesfree available: ${ffree[@]}"
22824         echo "MDT blocks available: ${bavail[@]}"
22825         echo "weight diff=$diff%"
22826
22827         echo
22828         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
22829
22830         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
22831         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
22832         # decrease statfs age, so that it can be updated in time
22833         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
22834         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
22835
22836         sleep 1
22837
22838         testdir=$DIR/$tdir-s$stripe_count/qos
22839
22840         for i in $(seq $((100 * MDSCOUNT))); do
22841                 eval $mkdir_cmd $testdir/subdir$i ||
22842                         error "$mkdir_cmd subdir$i failed"
22843         done
22844
22845         for i in $(seq $MDSCOUNT); do
22846                 count=$($LFS getdirstripe -i $testdir/* | grep ^$((i - 1))$ |
22847                         wc -l)
22848                 echo "$count directories created on MDT$((i - 1))"
22849
22850                 if [ $stripe_count -gt 1 ]; then
22851                         count=$($LFS getdirstripe $testdir/* |
22852                                 grep -P "^\s+$((i - 1))\t" | wc -l)
22853                         echo "$count stripes created on MDT$((i - 1))"
22854                 fi
22855         done
22856
22857         max=$($LFS getdirstripe -i $testdir/* | grep ^$max_index$ | wc -l)
22858         min=$($LFS getdirstripe -i $testdir/* | grep ^$min_index$ | wc -l)
22859
22860         # D-value should > 10% of averge
22861         [ $((max - min)) -lt 10 ] &&
22862                 error "subdirs shouldn't be evenly distributed"
22863
22864         # ditto
22865         if [ $stripe_count -gt 1 ]; then
22866                 max=$($LFS getdirstripe $testdir/* |
22867                         grep -P "^\s+$max_index\t" | wc -l)
22868                 min=$($LFS getdirstripe $testdir/* |
22869                         grep -P "^\s+$min_index\t" | wc -l)
22870                 [ $((max - min)) -le $((10 * stripe_count)) ] &&
22871                         error "stripes shouldn't be evenly distributed"|| true
22872         fi
22873 }
22874
22875 test_413a() {
22876         [ $MDSCOUNT -lt 2 ] &&
22877                 skip "We need at least 2 MDTs for this test"
22878
22879         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
22880                 skip "Need server version at least 2.12.52"
22881
22882         local stripe_count
22883
22884         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
22885                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
22886                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
22887                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
22888                 test_qos_mkdir "$LFS mkdir -c $stripe_count" $stripe_count
22889         done
22890 }
22891 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
22892
22893 test_413b() {
22894         [ $MDSCOUNT -lt 2 ] &&
22895                 skip "We need at least 2 MDTs for this test"
22896
22897         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
22898                 skip "Need server version at least 2.12.52"
22899
22900         local stripe_count
22901
22902         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
22903                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
22904                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
22905                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
22906                 $LFS setdirstripe -D -c $stripe_count \
22907                         $DIR/$tdir-s$stripe_count/rr ||
22908                         error "setdirstripe failed"
22909                 $LFS setdirstripe -D -c $stripe_count \
22910                         $DIR/$tdir-s$stripe_count/qos ||
22911                         error "setdirstripe failed"
22912                 test_qos_mkdir "mkdir" $stripe_count
22913         done
22914 }
22915 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
22916
22917 test_414() {
22918 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
22919         $LCTL set_param fail_loc=0x80000521
22920         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
22921         rm -f $DIR/$tfile
22922 }
22923 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
22924
22925 test_415() {
22926         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22927         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22928                 skip "Need server version at least 2.11.52"
22929
22930         # LU-11102
22931         local total
22932         local setattr_pid
22933         local start_time
22934         local end_time
22935         local duration
22936
22937         total=500
22938         # this test may be slow on ZFS
22939         [ "$mds1_FSTYPE" == "zfs" ] && total=100
22940
22941         # though this test is designed for striped directory, let's test normal
22942         # directory too since lock is always saved as CoS lock.
22943         test_mkdir $DIR/$tdir || error "mkdir $tdir"
22944         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
22945
22946         (
22947                 while true; do
22948                         touch $DIR/$tdir
22949                 done
22950         ) &
22951         setattr_pid=$!
22952
22953         start_time=$(date +%s)
22954         for i in $(seq $total); do
22955                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
22956                         > /dev/null
22957         done
22958         end_time=$(date +%s)
22959         duration=$((end_time - start_time))
22960
22961         kill -9 $setattr_pid
22962
22963         echo "rename $total files took $duration sec"
22964         [ $duration -lt 100 ] || error "rename took $duration sec"
22965 }
22966 run_test 415 "lock revoke is not missing"
22967
22968 test_416() {
22969         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
22970                 skip "Need server version at least 2.11.55"
22971
22972         # define OBD_FAIL_OSD_TXN_START    0x19a
22973         do_facet mds1 lctl set_param fail_loc=0x19a
22974
22975         lfs mkdir -c $MDSCOUNT $DIR/$tdir
22976
22977         true
22978 }
22979 run_test 416 "transaction start failure won't cause system hung"
22980
22981 cleanup_417() {
22982         trap 0
22983         do_nodes $(comma_list $(mdts_nodes)) \
22984                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
22985         do_nodes $(comma_list $(mdts_nodes)) \
22986                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
22987         do_nodes $(comma_list $(mdts_nodes)) \
22988                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
22989 }
22990
22991 test_417() {
22992         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22993         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
22994                 skip "Need MDS version at least 2.11.56"
22995
22996         trap cleanup_417 RETURN EXIT
22997
22998         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
22999         do_nodes $(comma_list $(mdts_nodes)) \
23000                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
23001         $LFS migrate -m 0 $DIR/$tdir.1 &&
23002                 error "migrate dir $tdir.1 should fail"
23003
23004         do_nodes $(comma_list $(mdts_nodes)) \
23005                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
23006         $LFS mkdir -i 1 $DIR/$tdir.2 &&
23007                 error "create remote dir $tdir.2 should fail"
23008
23009         do_nodes $(comma_list $(mdts_nodes)) \
23010                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
23011         $LFS mkdir -c 2 $DIR/$tdir.3 &&
23012                 error "create striped dir $tdir.3 should fail"
23013         true
23014 }
23015 run_test 417 "disable remote dir, striped dir and dir migration"
23016
23017 # Checks that the outputs of df [-i] and lfs df [-i] match
23018 #
23019 # usage: check_lfs_df <blocks | inodes> <mountpoint>
23020 check_lfs_df() {
23021         local dir=$2
23022         local inodes
23023         local df_out
23024         local lfs_df_out
23025         local count
23026         local passed=false
23027
23028         # blocks or inodes
23029         [ "$1" == "blocks" ] && inodes= || inodes="-i"
23030
23031         for count in {1..100}; do
23032                 cancel_lru_locks
23033                 sync; sleep 0.2
23034
23035                 # read the lines of interest
23036                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
23037                         error "df $inodes $dir | tail -n +2 failed"
23038                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
23039                         error "lfs df $inodes $dir | grep summary: failed"
23040
23041                 # skip first substrings of each output as they are different
23042                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
23043                 # compare the two outputs
23044                 passed=true
23045                 for i in {1..5}; do
23046                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
23047                 done
23048                 $passed && break
23049         done
23050
23051         if ! $passed; then
23052                 df -P $inodes $dir
23053                 echo
23054                 lfs df $inodes $dir
23055                 error "df and lfs df $1 output mismatch: "      \
23056                       "df ${inodes}: ${df_out[*]}, "            \
23057                       "lfs df ${inodes}: ${lfs_df_out[*]}"
23058         fi
23059 }
23060
23061 test_418() {
23062         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23063
23064         local dir=$DIR/$tdir
23065         local numfiles=$((RANDOM % 4096 + 2))
23066         local numblocks=$((RANDOM % 256 + 1))
23067
23068         wait_delete_completed
23069         test_mkdir $dir
23070
23071         # check block output
23072         check_lfs_df blocks $dir
23073         # check inode output
23074         check_lfs_df inodes $dir
23075
23076         # create a single file and retest
23077         echo "Creating a single file and testing"
23078         createmany -o $dir/$tfile- 1 &>/dev/null ||
23079                 error "creating 1 file in $dir failed"
23080         check_lfs_df blocks $dir
23081         check_lfs_df inodes $dir
23082
23083         # create a random number of files
23084         echo "Creating $((numfiles - 1)) files and testing"
23085         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
23086                 error "creating $((numfiles - 1)) files in $dir failed"
23087
23088         # write a random number of blocks to the first test file
23089         echo "Writing $numblocks 4K blocks and testing"
23090         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
23091                 count=$numblocks &>/dev/null ||
23092                 error "dd to $dir/${tfile}-0 failed"
23093
23094         # retest
23095         check_lfs_df blocks $dir
23096         check_lfs_df inodes $dir
23097
23098         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
23099                 error "unlinking $numfiles files in $dir failed"
23100 }
23101 run_test 418 "df and lfs df outputs match"
23102
23103 test_419()
23104 {
23105         local dir=$DIR/$tdir
23106
23107         mkdir -p $dir
23108         touch $dir/file
23109
23110         cancel_lru_locks mdc
23111
23112         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
23113         $LCTL set_param fail_loc=0x1410
23114         cat $dir/file
23115         $LCTL set_param fail_loc=0
23116         rm -rf $dir
23117 }
23118 run_test 419 "Verify open file by name doesn't crash kernel"
23119
23120 test_420()
23121 {
23122         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
23123                 skip "Need MDS version at least 2.12.53"
23124
23125         local SAVE_UMASK=$(umask)
23126         local dir=$DIR/$tdir
23127         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
23128
23129         mkdir -p $dir
23130         umask 0000
23131         mkdir -m03777 $dir/testdir
23132         ls -dn $dir/testdir
23133         # Need to remove trailing '.' when SELinux is enabled
23134         local dirperms=$(ls -dn $dir/testdir |
23135                          awk '{ sub(/\.$/, "", $1); print $1}')
23136         [ $dirperms == "drwxrwsrwt" ] ||
23137                 error "incorrect perms on $dir/testdir"
23138
23139         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
23140                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
23141         ls -n $dir/testdir/testfile
23142         local fileperms=$(ls -n $dir/testdir/testfile |
23143                           awk '{ sub(/\.$/, "", $1); print $1}')
23144         [ $fileperms == "-rwxr-xr-x" ] ||
23145                 error "incorrect perms on $dir/testdir/testfile"
23146
23147         umask $SAVE_UMASK
23148 }
23149 run_test 420 "clear SGID bit on non-directories for non-members"
23150
23151 test_421a() {
23152         local cnt
23153         local fid1
23154         local fid2
23155
23156         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23157                 skip "Need MDS version at least 2.12.54"
23158
23159         test_mkdir $DIR/$tdir
23160         createmany -o $DIR/$tdir/f 3
23161         cnt=$(ls -1 $DIR/$tdir | wc -l)
23162         [ $cnt != 3 ] && error "unexpected #files: $cnt"
23163
23164         fid1=$(lfs path2fid $DIR/$tdir/f1)
23165         fid2=$(lfs path2fid $DIR/$tdir/f2)
23166         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
23167
23168         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
23169         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
23170
23171         cnt=$(ls -1 $DIR/$tdir | wc -l)
23172         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
23173
23174         rm -f $DIR/$tdir/f3 || error "can't remove f3"
23175         createmany -o $DIR/$tdir/f 3
23176         cnt=$(ls -1 $DIR/$tdir | wc -l)
23177         [ $cnt != 3 ] && error "unexpected #files: $cnt"
23178
23179         fid1=$(lfs path2fid $DIR/$tdir/f1)
23180         fid2=$(lfs path2fid $DIR/$tdir/f2)
23181         echo "remove using fsname $FSNAME"
23182         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
23183
23184         cnt=$(ls -1 $DIR/$tdir | wc -l)
23185         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
23186 }
23187 run_test 421a "simple rm by fid"
23188
23189 test_421b() {
23190         local cnt
23191         local FID1
23192         local FID2
23193
23194         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23195                 skip "Need MDS version at least 2.12.54"
23196
23197         test_mkdir $DIR/$tdir
23198         createmany -o $DIR/$tdir/f 3
23199         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
23200         MULTIPID=$!
23201
23202         FID1=$(lfs path2fid $DIR/$tdir/f1)
23203         FID2=$(lfs path2fid $DIR/$tdir/f2)
23204         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
23205
23206         kill -USR1 $MULTIPID
23207         wait
23208
23209         cnt=$(ls $DIR/$tdir | wc -l)
23210         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
23211 }
23212 run_test 421b "rm by fid on open file"
23213
23214 test_421c() {
23215         local cnt
23216         local FIDS
23217
23218         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23219                 skip "Need MDS version at least 2.12.54"
23220
23221         test_mkdir $DIR/$tdir
23222         createmany -o $DIR/$tdir/f 3
23223         touch $DIR/$tdir/$tfile
23224         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
23225         cnt=$(ls -1 $DIR/$tdir | wc -l)
23226         [ $cnt != 184 ] && error "unexpected #files: $cnt"
23227
23228         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
23229         $LFS rmfid $DIR $FID1 || error "rmfid failed"
23230
23231         cnt=$(ls $DIR/$tdir | wc -l)
23232         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
23233 }
23234 run_test 421c "rm by fid against hardlinked files"
23235
23236 test_421d() {
23237         local cnt
23238         local FIDS
23239
23240         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23241                 skip "Need MDS version at least 2.12.54"
23242
23243         test_mkdir $DIR/$tdir
23244         createmany -o $DIR/$tdir/f 4097
23245         cnt=$(ls -1 $DIR/$tdir | wc -l)
23246         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
23247
23248         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
23249         $LFS rmfid $DIR $FIDS || error "rmfid failed"
23250
23251         cnt=$(ls $DIR/$tdir | wc -l)
23252         rm -rf $DIR/$tdir
23253         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23254 }
23255 run_test 421d "rmfid en masse"
23256
23257 test_421e() {
23258         local cnt
23259         local FID
23260
23261         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23262         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23263                 skip "Need MDS version at least 2.12.54"
23264
23265         mkdir -p $DIR/$tdir
23266         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23267         createmany -o $DIR/$tdir/striped_dir/f 512
23268         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23269         [ $cnt != 512 ] && error "unexpected #files: $cnt"
23270
23271         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
23272                 sed "s/[/][^:]*://g")
23273         $LFS rmfid $DIR $FIDS || error "rmfid failed"
23274
23275         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
23276         rm -rf $DIR/$tdir
23277         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23278 }
23279 run_test 421e "rmfid in DNE"
23280
23281 test_421f() {
23282         local cnt
23283         local FID
23284
23285         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23286                 skip "Need MDS version at least 2.12.54"
23287
23288         test_mkdir $DIR/$tdir
23289         touch $DIR/$tdir/f
23290         cnt=$(ls -1 $DIR/$tdir | wc -l)
23291         [ $cnt != 1 ] && error "unexpected #files: $cnt"
23292
23293         FID=$(lfs path2fid $DIR/$tdir/f)
23294         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
23295         # rmfid should fail
23296         cnt=$(ls -1 $DIR/$tdir | wc -l)
23297         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
23298
23299         chmod a+rw $DIR/$tdir
23300         ls -la $DIR/$tdir
23301         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
23302         # rmfid should fail
23303         cnt=$(ls -1 $DIR/$tdir | wc -l)
23304         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
23305
23306         rm -f $DIR/$tdir/f
23307         $RUNAS touch $DIR/$tdir/f
23308         FID=$(lfs path2fid $DIR/$tdir/f)
23309         echo "rmfid as root"
23310         $LFS rmfid $DIR $FID || error "rmfid as root failed"
23311         cnt=$(ls -1 $DIR/$tdir | wc -l)
23312         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
23313
23314         rm -f $DIR/$tdir/f
23315         $RUNAS touch $DIR/$tdir/f
23316         cnt=$(ls -1 $DIR/$tdir | wc -l)
23317         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
23318         FID=$(lfs path2fid $DIR/$tdir/f)
23319         # rmfid w/o user_fid2path mount option should fail
23320         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
23321         cnt=$(ls -1 $DIR/$tdir | wc -l)
23322         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
23323
23324         umount_client $MOUNT || error "failed to umount client"
23325         mount_client $MOUNT "$MOUNT_OPTS,user_fid2path" ||
23326                 error "failed to mount client'"
23327
23328         $RUNAS $LFS rmfid $DIR $FID || error "rmfid failed"
23329         # rmfid should succeed
23330         cnt=$(ls -1 $DIR/$tdir | wc -l)
23331         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
23332
23333         # rmfid shouldn't allow to remove files due to dir's permission
23334         chmod a+rwx $DIR/$tdir
23335         touch $DIR/$tdir/f
23336         ls -la $DIR/$tdir
23337         FID=$(lfs path2fid $DIR/$tdir/f)
23338         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail"
23339
23340         umount_client $MOUNT || error "failed to umount client"
23341         mount_client $MOUNT "$MOUNT_OPTS" ||
23342                 error "failed to mount client'"
23343
23344 }
23345 run_test 421f "rmfid checks permissions"
23346
23347 test_421g() {
23348         local cnt
23349         local FIDS
23350
23351         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23352         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23353                 skip "Need MDS version at least 2.12.54"
23354
23355         mkdir -p $DIR/$tdir
23356         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23357         createmany -o $DIR/$tdir/striped_dir/f 512
23358         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23359         [ $cnt != 512 ] && error "unexpected #files: $cnt"
23360
23361         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
23362                 sed "s/[/][^:]*://g")
23363
23364         rm -f $DIR/$tdir/striped_dir/f1*
23365         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23366         removed=$((512 - cnt))
23367
23368         # few files have been just removed, so we expect
23369         # rmfid to fail on their fids
23370         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
23371         [ $removed != $errors ] && error "$errors != $removed"
23372
23373         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
23374         rm -rf $DIR/$tdir
23375         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23376 }
23377 run_test 421g "rmfid to return errors properly"
23378
23379 test_422() {
23380         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
23381         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
23382         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
23383         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
23384         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
23385
23386         local amc=$(at_max_get client)
23387         local amo=$(at_max_get mds1)
23388         local timeout=`lctl get_param -n timeout`
23389
23390         at_max_set 0 client
23391         at_max_set 0 mds1
23392
23393 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
23394         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
23395                         fail_val=$(((2*timeout + 10)*1000))
23396         touch $DIR/$tdir/d3/file &
23397         sleep 2
23398 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
23399         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
23400                         fail_val=$((2*timeout + 5))
23401         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
23402         local pid=$!
23403         sleep 1
23404         kill -9 $pid
23405         sleep $((2 * timeout))
23406         echo kill $pid
23407         kill -9 $pid
23408         lctl mark touch
23409         touch $DIR/$tdir/d2/file3
23410         touch $DIR/$tdir/d2/file4
23411         touch $DIR/$tdir/d2/file5
23412
23413         wait
23414         at_max_set $amc client
23415         at_max_set $amo mds1
23416
23417         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
23418         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
23419                 error "Watchdog is always throttled"
23420 }
23421 run_test 422 "kill a process with RPC in progress"
23422
23423 stat_test() {
23424     df -h $MOUNT &
23425     df -h $MOUNT &
23426     df -h $MOUNT &
23427     df -h $MOUNT &
23428     df -h $MOUNT &
23429     df -h $MOUNT &
23430 }
23431
23432 test_423() {
23433     local _stats
23434     # ensure statfs cache is expired
23435     sleep 2;
23436
23437     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
23438     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
23439
23440     return 0
23441 }
23442 run_test 423 "statfs should return a right data"
23443
23444 test_424() {
23445 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
23446         $LCTL set_param fail_loc=0x80000522
23447         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
23448         rm -f $DIR/$tfile
23449 }
23450 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
23451
23452 test_425() {
23453         test_mkdir -c -1 $DIR/$tdir
23454         $LFS setstripe -c -1 $DIR/$tdir
23455
23456         lru_resize_disable "" 100
23457         stack_trap "lru_resize_enable" EXIT
23458
23459         sleep 5
23460
23461         for i in $(seq $((MDSCOUNT * 125))); do
23462                 local t=$DIR/$tdir/$tfile_$i
23463
23464                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
23465                         error_noexit "Create file $t"
23466         done
23467         stack_trap "rm -rf $DIR/$tdir" EXIT
23468
23469         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
23470                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
23471                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
23472
23473                 [ $lock_count -le $lru_size ] ||
23474                         error "osc lock count $lock_count > lru size $lru_size"
23475         done
23476
23477         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
23478                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
23479                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
23480
23481                 [ $lock_count -le $lru_size ] ||
23482                         error "mdc lock count $lock_count > lru size $lru_size"
23483         done
23484 }
23485 run_test 425 "lock count should not exceed lru size"
23486
23487 test_426() {
23488         splice-test -r $DIR/$tfile
23489         splice-test -rd $DIR/$tfile
23490         splice-test $DIR/$tfile
23491         splice-test -d $DIR/$tfile
23492 }
23493 run_test 426 "splice test on Lustre"
23494
23495 prep_801() {
23496         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
23497         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
23498                 skip "Need server version at least 2.9.55"
23499
23500         start_full_debug_logging
23501 }
23502
23503 post_801() {
23504         stop_full_debug_logging
23505 }
23506
23507 barrier_stat() {
23508         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
23509                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
23510                            awk '/The barrier for/ { print $7 }')
23511                 echo $st
23512         else
23513                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
23514                 echo \'$st\'
23515         fi
23516 }
23517
23518 barrier_expired() {
23519         local expired
23520
23521         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
23522                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
23523                           awk '/will be expired/ { print $7 }')
23524         else
23525                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
23526         fi
23527
23528         echo $expired
23529 }
23530
23531 test_801a() {
23532         prep_801
23533
23534         echo "Start barrier_freeze at: $(date)"
23535         #define OBD_FAIL_BARRIER_DELAY          0x2202
23536         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
23537         # Do not reduce barrier time - See LU-11873
23538         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
23539
23540         sleep 2
23541         local b_status=$(barrier_stat)
23542         echo "Got barrier status at: $(date)"
23543         [ "$b_status" = "'freezing_p1'" ] ||
23544                 error "(1) unexpected barrier status $b_status"
23545
23546         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
23547         wait
23548         b_status=$(barrier_stat)
23549         [ "$b_status" = "'frozen'" ] ||
23550                 error "(2) unexpected barrier status $b_status"
23551
23552         local expired=$(barrier_expired)
23553         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
23554         sleep $((expired + 3))
23555
23556         b_status=$(barrier_stat)
23557         [ "$b_status" = "'expired'" ] ||
23558                 error "(3) unexpected barrier status $b_status"
23559
23560         # Do not reduce barrier time - See LU-11873
23561         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
23562                 error "(4) fail to freeze barrier"
23563
23564         b_status=$(barrier_stat)
23565         [ "$b_status" = "'frozen'" ] ||
23566                 error "(5) unexpected barrier status $b_status"
23567
23568         echo "Start barrier_thaw at: $(date)"
23569         #define OBD_FAIL_BARRIER_DELAY          0x2202
23570         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
23571         do_facet mgs $LCTL barrier_thaw $FSNAME &
23572
23573         sleep 2
23574         b_status=$(barrier_stat)
23575         echo "Got barrier status at: $(date)"
23576         [ "$b_status" = "'thawing'" ] ||
23577                 error "(6) unexpected barrier status $b_status"
23578
23579         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
23580         wait
23581         b_status=$(barrier_stat)
23582         [ "$b_status" = "'thawed'" ] ||
23583                 error "(7) unexpected barrier status $b_status"
23584
23585         #define OBD_FAIL_BARRIER_FAILURE        0x2203
23586         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
23587         do_facet mgs $LCTL barrier_freeze $FSNAME
23588
23589         b_status=$(barrier_stat)
23590         [ "$b_status" = "'failed'" ] ||
23591                 error "(8) unexpected barrier status $b_status"
23592
23593         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
23594         do_facet mgs $LCTL barrier_thaw $FSNAME
23595
23596         post_801
23597 }
23598 run_test 801a "write barrier user interfaces and stat machine"
23599
23600 test_801b() {
23601         prep_801
23602
23603         mkdir $DIR/$tdir || error "(1) fail to mkdir"
23604         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
23605         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
23606         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
23607         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
23608
23609         cancel_lru_locks mdc
23610
23611         # 180 seconds should be long enough
23612         do_facet mgs $LCTL barrier_freeze $FSNAME 180
23613
23614         local b_status=$(barrier_stat)
23615         [ "$b_status" = "'frozen'" ] ||
23616                 error "(6) unexpected barrier status $b_status"
23617
23618         mkdir $DIR/$tdir/d0/d10 &
23619         mkdir_pid=$!
23620
23621         touch $DIR/$tdir/d1/f13 &
23622         touch_pid=$!
23623
23624         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
23625         ln_pid=$!
23626
23627         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
23628         mv_pid=$!
23629
23630         rm -f $DIR/$tdir/d4/f12 &
23631         rm_pid=$!
23632
23633         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
23634
23635         # To guarantee taht the 'stat' is not blocked
23636         b_status=$(barrier_stat)
23637         [ "$b_status" = "'frozen'" ] ||
23638                 error "(8) unexpected barrier status $b_status"
23639
23640         # let above commands to run at background
23641         sleep 5
23642
23643         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
23644         ps -p $touch_pid || error "(10) touch should be blocked"
23645         ps -p $ln_pid || error "(11) link should be blocked"
23646         ps -p $mv_pid || error "(12) rename should be blocked"
23647         ps -p $rm_pid || error "(13) unlink should be blocked"
23648
23649         b_status=$(barrier_stat)
23650         [ "$b_status" = "'frozen'" ] ||
23651                 error "(14) unexpected barrier status $b_status"
23652
23653         do_facet mgs $LCTL barrier_thaw $FSNAME
23654         b_status=$(barrier_stat)
23655         [ "$b_status" = "'thawed'" ] ||
23656                 error "(15) unexpected barrier status $b_status"
23657
23658         wait $mkdir_pid || error "(16) mkdir should succeed"
23659         wait $touch_pid || error "(17) touch should succeed"
23660         wait $ln_pid || error "(18) link should succeed"
23661         wait $mv_pid || error "(19) rename should succeed"
23662         wait $rm_pid || error "(20) unlink should succeed"
23663
23664         post_801
23665 }
23666 run_test 801b "modification will be blocked by write barrier"
23667
23668 test_801c() {
23669         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
23670
23671         prep_801
23672
23673         stop mds2 || error "(1) Fail to stop mds2"
23674
23675         do_facet mgs $LCTL barrier_freeze $FSNAME 30
23676
23677         local b_status=$(barrier_stat)
23678         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
23679                 do_facet mgs $LCTL barrier_thaw $FSNAME
23680                 error "(2) unexpected barrier status $b_status"
23681         }
23682
23683         do_facet mgs $LCTL barrier_rescan $FSNAME ||
23684                 error "(3) Fail to rescan barrier bitmap"
23685
23686         # Do not reduce barrier time - See LU-11873
23687         do_facet mgs $LCTL barrier_freeze $FSNAME 20
23688
23689         b_status=$(barrier_stat)
23690         [ "$b_status" = "'frozen'" ] ||
23691                 error "(4) unexpected barrier status $b_status"
23692
23693         do_facet mgs $LCTL barrier_thaw $FSNAME
23694         b_status=$(barrier_stat)
23695         [ "$b_status" = "'thawed'" ] ||
23696                 error "(5) unexpected barrier status $b_status"
23697
23698         local devname=$(mdsdevname 2)
23699
23700         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
23701
23702         do_facet mgs $LCTL barrier_rescan $FSNAME ||
23703                 error "(7) Fail to rescan barrier bitmap"
23704
23705         post_801
23706 }
23707 run_test 801c "rescan barrier bitmap"
23708
23709 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
23710 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
23711 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
23712 saved_MOUNT_OPTS=$MOUNT_OPTS
23713
23714 cleanup_802a() {
23715         trap 0
23716
23717         stopall
23718         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
23719         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
23720         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
23721         MOUNT_OPTS=$saved_MOUNT_OPTS
23722         setupall
23723 }
23724
23725 test_802a() {
23726         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
23727         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
23728         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
23729                 skip "Need server version at least 2.9.55"
23730
23731         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
23732
23733         mkdir $DIR/$tdir || error "(1) fail to mkdir"
23734
23735         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
23736                 error "(2) Fail to copy"
23737
23738         trap cleanup_802a EXIT
23739
23740         # sync by force before remount as readonly
23741         sync; sync_all_data; sleep 3; sync_all_data
23742
23743         stopall
23744
23745         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
23746         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
23747         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
23748
23749         echo "Mount the server as read only"
23750         setupall server_only || error "(3) Fail to start servers"
23751
23752         echo "Mount client without ro should fail"
23753         mount_client $MOUNT &&
23754                 error "(4) Mount client without 'ro' should fail"
23755
23756         echo "Mount client with ro should succeed"
23757         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
23758         mount_client $MOUNT ||
23759                 error "(5) Mount client with 'ro' should succeed"
23760
23761         echo "Modify should be refused"
23762         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
23763
23764         echo "Read should be allowed"
23765         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
23766                 error "(7) Read should succeed under ro mode"
23767
23768         cleanup_802a
23769 }
23770 run_test 802a "simulate readonly device"
23771
23772 test_802b() {
23773         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23774         remote_mds_nodsh && skip "remote MDS with nodsh"
23775
23776         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
23777                 skip "readonly option not available"
23778
23779         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
23780
23781         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
23782                 error "(2) Fail to copy"
23783
23784         # write back all cached data before setting MDT to readonly
23785         cancel_lru_locks
23786         sync_all_data
23787
23788         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
23789         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
23790
23791         echo "Modify should be refused"
23792         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
23793
23794         echo "Read should be allowed"
23795         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
23796                 error "(7) Read should succeed under ro mode"
23797
23798         # disable readonly
23799         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
23800 }
23801 run_test 802b "be able to set MDTs to readonly"
23802
23803 test_803() {
23804         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
23805         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
23806                 skip "MDS needs to be newer than 2.10.54"
23807
23808         mkdir -p $DIR/$tdir
23809         # Create some objects on all MDTs to trigger related logs objects
23810         for idx in $(seq $MDSCOUNT); do
23811                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
23812                         $DIR/$tdir/dir${idx} ||
23813                         error "Fail to create $DIR/$tdir/dir${idx}"
23814         done
23815
23816         sync; sleep 3
23817         wait_delete_completed # ensure old test cleanups are finished
23818         echo "before create:"
23819         $LFS df -i $MOUNT
23820         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
23821
23822         for i in {1..10}; do
23823                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
23824                         error "Fail to create $DIR/$tdir/foo$i"
23825         done
23826
23827         sync; sleep 3
23828         echo "after create:"
23829         $LFS df -i $MOUNT
23830         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
23831
23832         # allow for an llog to be cleaned up during the test
23833         [ $after_used -ge $((before_used + 10 - 1)) ] ||
23834                 error "before ($before_used) + 10 > after ($after_used)"
23835
23836         for i in {1..10}; do
23837                 rm -rf $DIR/$tdir/foo$i ||
23838                         error "Fail to remove $DIR/$tdir/foo$i"
23839         done
23840
23841         sleep 3 # avoid MDT return cached statfs
23842         wait_delete_completed
23843         echo "after unlink:"
23844         $LFS df -i $MOUNT
23845         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
23846
23847         # allow for an llog to be created during the test
23848         [ $after_used -le $((before_used + 1)) ] ||
23849                 error "after ($after_used) > before ($before_used) + 1"
23850 }
23851 run_test 803 "verify agent object for remote object"
23852
23853 test_804() {
23854         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
23855         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
23856                 skip "MDS needs to be newer than 2.10.54"
23857         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
23858
23859         mkdir -p $DIR/$tdir
23860         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
23861                 error "Fail to create $DIR/$tdir/dir0"
23862
23863         local fid=$($LFS path2fid $DIR/$tdir/dir0)
23864         local dev=$(mdsdevname 2)
23865
23866         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23867                 grep ${fid} || error "NOT found agent entry for dir0"
23868
23869         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
23870                 error "Fail to create $DIR/$tdir/dir1"
23871
23872         touch $DIR/$tdir/dir1/foo0 ||
23873                 error "Fail to create $DIR/$tdir/dir1/foo0"
23874         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
23875         local rc=0
23876
23877         for idx in $(seq $MDSCOUNT); do
23878                 dev=$(mdsdevname $idx)
23879                 do_facet mds${idx} \
23880                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23881                         grep ${fid} && rc=$idx
23882         done
23883
23884         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
23885                 error "Fail to rename foo0 to foo1"
23886         if [ $rc -eq 0 ]; then
23887                 for idx in $(seq $MDSCOUNT); do
23888                         dev=$(mdsdevname $idx)
23889                         do_facet mds${idx} \
23890                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23891                         grep ${fid} && rc=$idx
23892                 done
23893         fi
23894
23895         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
23896                 error "Fail to rename foo1 to foo2"
23897         if [ $rc -eq 0 ]; then
23898                 for idx in $(seq $MDSCOUNT); do
23899                         dev=$(mdsdevname $idx)
23900                         do_facet mds${idx} \
23901                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23902                         grep ${fid} && rc=$idx
23903                 done
23904         fi
23905
23906         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
23907
23908         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
23909                 error "Fail to link to $DIR/$tdir/dir1/foo2"
23910         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
23911                 error "Fail to rename foo2 to foo0"
23912         unlink $DIR/$tdir/dir1/foo0 ||
23913                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
23914         rm -rf $DIR/$tdir/dir0 ||
23915                 error "Fail to rm $DIR/$tdir/dir0"
23916
23917         for idx in $(seq $MDSCOUNT); do
23918                 dev=$(mdsdevname $idx)
23919                 rc=0
23920
23921                 stop mds${idx}
23922                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
23923                         rc=$?
23924                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
23925                         error "mount mds$idx failed"
23926                 df $MOUNT > /dev/null 2>&1
23927
23928                 # e2fsck should not return error
23929                 [ $rc -eq 0 ] ||
23930                         error "e2fsck detected error on MDT${idx}: rc=$rc"
23931         done
23932 }
23933 run_test 804 "verify agent entry for remote entry"
23934
23935 cleanup_805() {
23936         do_facet $SINGLEMDS zfs set quota=$old $fsset
23937         unlinkmany $DIR/$tdir/f- 1000000
23938         trap 0
23939 }
23940
23941 test_805() {
23942         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
23943         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
23944         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
23945                 skip "netfree not implemented before 0.7"
23946         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
23947                 skip "Need MDS version at least 2.10.57"
23948
23949         local fsset
23950         local freekb
23951         local usedkb
23952         local old
23953         local quota
23954         local pref="osd-zfs.$FSNAME-MDT0000."
23955
23956         # limit available space on MDS dataset to meet nospace issue
23957         # quickly. then ZFS 0.7.2 can use reserved space if asked
23958         # properly (using netfree flag in osd_declare_destroy()
23959         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
23960         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
23961                 gawk '{print $3}')
23962         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
23963         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
23964         let "usedkb=usedkb-freekb"
23965         let "freekb=freekb/2"
23966         if let "freekb > 5000"; then
23967                 let "freekb=5000"
23968         fi
23969         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
23970         trap cleanup_805 EXIT
23971         mkdir $DIR/$tdir
23972         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
23973                 error "Can't set PFL layout"
23974         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
23975         rm -rf $DIR/$tdir || error "not able to remove"
23976         do_facet $SINGLEMDS zfs set quota=$old $fsset
23977         trap 0
23978 }
23979 run_test 805 "ZFS can remove from full fs"
23980
23981 # Size-on-MDS test
23982 check_lsom_data()
23983 {
23984         local file=$1
23985         local size=$($LFS getsom -s $file)
23986         local expect=$(stat -c %s $file)
23987
23988         [[ $size == $expect ]] ||
23989                 error "$file expected size: $expect, got: $size"
23990
23991         local blocks=$($LFS getsom -b $file)
23992         expect=$(stat -c %b $file)
23993         [[ $blocks == $expect ]] ||
23994                 error "$file expected blocks: $expect, got: $blocks"
23995 }
23996
23997 check_lsom_size()
23998 {
23999         local size=$($LFS getsom -s $1)
24000         local expect=$2
24001
24002         [[ $size == $expect ]] ||
24003                 error "$file expected size: $expect, got: $size"
24004 }
24005
24006 test_806() {
24007         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
24008                 skip "Need MDS version at least 2.11.52"
24009
24010         local bs=1048576
24011
24012         touch $DIR/$tfile || error "touch $tfile failed"
24013
24014         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24015         save_lustre_params client "llite.*.xattr_cache" > $save
24016         lctl set_param llite.*.xattr_cache=0
24017         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24018
24019         # single-threaded write
24020         echo "Test SOM for single-threaded write"
24021         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
24022                 error "write $tfile failed"
24023         check_lsom_size $DIR/$tfile $bs
24024
24025         local num=32
24026         local size=$(($num * $bs))
24027         local offset=0
24028         local i
24029
24030         echo "Test SOM for single client multi-threaded($num) write"
24031         $TRUNCATE $DIR/$tfile 0
24032         for ((i = 0; i < $num; i++)); do
24033                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24034                 local pids[$i]=$!
24035                 offset=$((offset + $bs))
24036         done
24037         for (( i=0; i < $num; i++ )); do
24038                 wait ${pids[$i]}
24039         done
24040         check_lsom_size $DIR/$tfile $size
24041
24042         $TRUNCATE $DIR/$tfile 0
24043         for ((i = 0; i < $num; i++)); do
24044                 offset=$((offset - $bs))
24045                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24046                 local pids[$i]=$!
24047         done
24048         for (( i=0; i < $num; i++ )); do
24049                 wait ${pids[$i]}
24050         done
24051         check_lsom_size $DIR/$tfile $size
24052
24053         # multi-client writes
24054         num=$(get_node_count ${CLIENTS//,/ })
24055         size=$(($num * $bs))
24056         offset=0
24057         i=0
24058
24059         echo "Test SOM for multi-client ($num) writes"
24060         $TRUNCATE $DIR/$tfile 0
24061         for client in ${CLIENTS//,/ }; do
24062                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24063                 local pids[$i]=$!
24064                 i=$((i + 1))
24065                 offset=$((offset + $bs))
24066         done
24067         for (( i=0; i < $num; i++ )); do
24068                 wait ${pids[$i]}
24069         done
24070         check_lsom_size $DIR/$tfile $offset
24071
24072         i=0
24073         $TRUNCATE $DIR/$tfile 0
24074         for client in ${CLIENTS//,/ }; do
24075                 offset=$((offset - $bs))
24076                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24077                 local pids[$i]=$!
24078                 i=$((i + 1))
24079         done
24080         for (( i=0; i < $num; i++ )); do
24081                 wait ${pids[$i]}
24082         done
24083         check_lsom_size $DIR/$tfile $size
24084
24085         # verify truncate
24086         echo "Test SOM for truncate"
24087         $TRUNCATE $DIR/$tfile 1048576
24088         check_lsom_size $DIR/$tfile 1048576
24089         $TRUNCATE $DIR/$tfile 1234
24090         check_lsom_size $DIR/$tfile 1234
24091
24092         # verify SOM blocks count
24093         echo "Verify SOM block count"
24094         $TRUNCATE $DIR/$tfile 0
24095         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
24096                 error "failed to write file $tfile"
24097         check_lsom_data $DIR/$tfile
24098 }
24099 run_test 806 "Verify Lazy Size on MDS"
24100
24101 test_807() {
24102         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
24103         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
24104                 skip "Need MDS version at least 2.11.52"
24105
24106         # Registration step
24107         changelog_register || error "changelog_register failed"
24108         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
24109         changelog_users $SINGLEMDS | grep -q $cl_user ||
24110                 error "User $cl_user not found in changelog_users"
24111
24112         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24113         save_lustre_params client "llite.*.xattr_cache" > $save
24114         lctl set_param llite.*.xattr_cache=0
24115         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24116
24117         rm -rf $DIR/$tdir || error "rm $tdir failed"
24118         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
24119         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
24120         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
24121         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
24122                 error "truncate $tdir/trunc failed"
24123
24124         local bs=1048576
24125         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
24126                 error "write $tfile failed"
24127
24128         # multi-client wirtes
24129         local num=$(get_node_count ${CLIENTS//,/ })
24130         local offset=0
24131         local i=0
24132
24133         echo "Test SOM for multi-client ($num) writes"
24134         touch $DIR/$tfile || error "touch $tfile failed"
24135         $TRUNCATE $DIR/$tfile 0
24136         for client in ${CLIENTS//,/ }; do
24137                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24138                 local pids[$i]=$!
24139                 i=$((i + 1))
24140                 offset=$((offset + $bs))
24141         done
24142         for (( i=0; i < $num; i++ )); do
24143                 wait ${pids[$i]}
24144         done
24145
24146         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
24147         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
24148         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
24149         check_lsom_data $DIR/$tdir/trunc
24150         check_lsom_data $DIR/$tdir/single_dd
24151         check_lsom_data $DIR/$tfile
24152
24153         rm -rf $DIR/$tdir
24154         # Deregistration step
24155         changelog_deregister || error "changelog_deregister failed"
24156 }
24157 run_test 807 "verify LSOM syncing tool"
24158
24159 check_som_nologged()
24160 {
24161         local lines=$($LFS changelog $FSNAME-MDT0000 |
24162                 grep 'x=trusted.som' | wc -l)
24163         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
24164 }
24165
24166 test_808() {
24167         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
24168                 skip "Need MDS version at least 2.11.55"
24169
24170         # Registration step
24171         changelog_register || error "changelog_register failed"
24172
24173         touch $DIR/$tfile || error "touch $tfile failed"
24174         check_som_nologged
24175
24176         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
24177                 error "write $tfile failed"
24178         check_som_nologged
24179
24180         $TRUNCATE $DIR/$tfile 1234
24181         check_som_nologged
24182
24183         $TRUNCATE $DIR/$tfile 1048576
24184         check_som_nologged
24185
24186         # Deregistration step
24187         changelog_deregister || error "changelog_deregister failed"
24188 }
24189 run_test 808 "Check trusted.som xattr not logged in Changelogs"
24190
24191 check_som_nodata()
24192 {
24193         $LFS getsom $1
24194         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
24195 }
24196
24197 test_809() {
24198         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
24199                 skip "Need MDS version at least 2.11.56"
24200
24201         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
24202                 error "failed to create DoM-only file $DIR/$tfile"
24203         touch $DIR/$tfile || error "touch $tfile failed"
24204         check_som_nodata $DIR/$tfile
24205
24206         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
24207                 error "write $tfile failed"
24208         check_som_nodata $DIR/$tfile
24209
24210         $TRUNCATE $DIR/$tfile 1234
24211         check_som_nodata $DIR/$tfile
24212
24213         $TRUNCATE $DIR/$tfile 4097
24214         check_som_nodata $DIR/$file
24215 }
24216 run_test 809 "Verify no SOM xattr store for DoM-only files"
24217
24218 test_810() {
24219         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24220         $GSS && skip_env "could not run with gss"
24221         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
24222                 skip "OST < 2.12.58 doesn't align checksum"
24223
24224         set_checksums 1
24225         stack_trap "set_checksums $ORIG_CSUM" EXIT
24226         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
24227
24228         local csum
24229         local before
24230         local after
24231         for csum in $CKSUM_TYPES; do
24232                 #define OBD_FAIL_OSC_NO_GRANT   0x411
24233                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
24234                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
24235                         eval set -- $i
24236                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
24237                         before=$(md5sum $DIR/$tfile)
24238                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
24239                         after=$(md5sum $DIR/$tfile)
24240                         [ "$before" == "$after" ] ||
24241                                 error "$csum: $before != $after bs=$1 seek=$2"
24242                 done
24243         done
24244 }
24245 run_test 810 "partial page writes on ZFS (LU-11663)"
24246
24247 test_812a() {
24248         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
24249                 skip "OST < 2.12.51 doesn't support this fail_loc"
24250         [ "$SHARED_KEY" = true ] &&
24251                 skip "OSC connections never go IDLE with Shared-Keys enabled"
24252
24253         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24254         # ensure ost1 is connected
24255         stat $DIR/$tfile >/dev/null || error "can't stat"
24256         wait_osc_import_state client ost1 FULL
24257         # no locks, no reqs to let the connection idle
24258         cancel_lru_locks osc
24259
24260         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
24261 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
24262         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
24263         wait_osc_import_state client ost1 CONNECTING
24264         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
24265
24266         stat $DIR/$tfile >/dev/null || error "can't stat file"
24267 }
24268 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
24269
24270 test_812b() { # LU-12378
24271         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
24272                 skip "OST < 2.12.51 doesn't support this fail_loc"
24273         [ "$SHARED_KEY" = true ] &&
24274                 skip "OSC connections never go IDLE with Shared-Keys enabled"
24275
24276         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
24277         # ensure ost1 is connected
24278         stat $DIR/$tfile >/dev/null || error "can't stat"
24279         wait_osc_import_state client ost1 FULL
24280         # no locks, no reqs to let the connection idle
24281         cancel_lru_locks osc
24282
24283         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
24284 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
24285         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
24286         wait_osc_import_state client ost1 CONNECTING
24287         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
24288
24289         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
24290         wait_osc_import_state client ost1 IDLE
24291 }
24292 run_test 812b "do not drop no resend request for idle connect"
24293
24294 test_813() {
24295         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
24296         [ -z "$file_heat_sav" ] && skip "no file heat support"
24297
24298         local readsample
24299         local writesample
24300         local readbyte
24301         local writebyte
24302         local readsample1
24303         local writesample1
24304         local readbyte1
24305         local writebyte1
24306
24307         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
24308         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
24309
24310         $LCTL set_param -n llite.*.file_heat=1
24311         echo "Turn on file heat"
24312         echo "Period second: $period_second, Decay percentage: $decay_pct"
24313
24314         echo "QQQQ" > $DIR/$tfile
24315         echo "QQQQ" > $DIR/$tfile
24316         echo "QQQQ" > $DIR/$tfile
24317         cat $DIR/$tfile > /dev/null
24318         cat $DIR/$tfile > /dev/null
24319         cat $DIR/$tfile > /dev/null
24320         cat $DIR/$tfile > /dev/null
24321
24322         local out=$($LFS heat_get $DIR/$tfile)
24323
24324         $LFS heat_get $DIR/$tfile
24325         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24326         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24327         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24328         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24329
24330         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
24331         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
24332         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
24333         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
24334
24335         sleep $((period_second + 3))
24336         echo "Sleep $((period_second + 3)) seconds..."
24337         # The recursion formula to calculate the heat of the file f is as
24338         # follow:
24339         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
24340         # Where Hi is the heat value in the period between time points i*I and
24341         # (i+1)*I; Ci is the access count in the period; the symbol P refers
24342         # to the weight of Ci.
24343         out=$($LFS heat_get $DIR/$tfile)
24344         $LFS heat_get $DIR/$tfile
24345         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24346         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24347         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24348         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24349
24350         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
24351                 error "read sample ($readsample) is wrong"
24352         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
24353                 error "write sample ($writesample) is wrong"
24354         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
24355                 error "read bytes ($readbyte) is wrong"
24356         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
24357                 error "write bytes ($writebyte) is wrong"
24358
24359         echo "QQQQ" > $DIR/$tfile
24360         echo "QQQQ" > $DIR/$tfile
24361         echo "QQQQ" > $DIR/$tfile
24362         cat $DIR/$tfile > /dev/null
24363         cat $DIR/$tfile > /dev/null
24364         cat $DIR/$tfile > /dev/null
24365         cat $DIR/$tfile > /dev/null
24366
24367         sleep $((period_second + 3))
24368         echo "Sleep $((period_second + 3)) seconds..."
24369
24370         out=$($LFS heat_get $DIR/$tfile)
24371         $LFS heat_get $DIR/$tfile
24372         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24373         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24374         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24375         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24376
24377         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
24378                 4 * $decay_pct) / 100") -eq 1 ] ||
24379                 error "read sample ($readsample1) is wrong"
24380         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
24381                 3 * $decay_pct) / 100") -eq 1 ] ||
24382                 error "write sample ($writesample1) is wrong"
24383         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
24384                 20 * $decay_pct) / 100") -eq 1 ] ||
24385                 error "read bytes ($readbyte1) is wrong"
24386         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
24387                 15 * $decay_pct) / 100") -eq 1 ] ||
24388                 error "write bytes ($writebyte1) is wrong"
24389
24390         echo "Turn off file heat for the file $DIR/$tfile"
24391         $LFS heat_set -o $DIR/$tfile
24392
24393         echo "QQQQ" > $DIR/$tfile
24394         echo "QQQQ" > $DIR/$tfile
24395         echo "QQQQ" > $DIR/$tfile
24396         cat $DIR/$tfile > /dev/null
24397         cat $DIR/$tfile > /dev/null
24398         cat $DIR/$tfile > /dev/null
24399         cat $DIR/$tfile > /dev/null
24400
24401         out=$($LFS heat_get $DIR/$tfile)
24402         $LFS heat_get $DIR/$tfile
24403         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24404         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24405         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24406         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24407
24408         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
24409         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
24410         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
24411         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
24412
24413         echo "Trun on file heat for the file $DIR/$tfile"
24414         $LFS heat_set -O $DIR/$tfile
24415
24416         echo "QQQQ" > $DIR/$tfile
24417         echo "QQQQ" > $DIR/$tfile
24418         echo "QQQQ" > $DIR/$tfile
24419         cat $DIR/$tfile > /dev/null
24420         cat $DIR/$tfile > /dev/null
24421         cat $DIR/$tfile > /dev/null
24422         cat $DIR/$tfile > /dev/null
24423
24424         out=$($LFS heat_get $DIR/$tfile)
24425         $LFS heat_get $DIR/$tfile
24426         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24427         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24428         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24429         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24430
24431         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
24432         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
24433         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
24434         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
24435
24436         $LFS heat_set -c $DIR/$tfile
24437         $LCTL set_param -n llite.*.file_heat=0
24438         echo "Turn off file heat support for the Lustre filesystem"
24439
24440         echo "QQQQ" > $DIR/$tfile
24441         echo "QQQQ" > $DIR/$tfile
24442         echo "QQQQ" > $DIR/$tfile
24443         cat $DIR/$tfile > /dev/null
24444         cat $DIR/$tfile > /dev/null
24445         cat $DIR/$tfile > /dev/null
24446         cat $DIR/$tfile > /dev/null
24447
24448         out=$($LFS heat_get $DIR/$tfile)
24449         $LFS heat_get $DIR/$tfile
24450         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24451         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24452         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24453         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24454
24455         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
24456         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
24457         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
24458         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
24459
24460         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
24461         rm -f $DIR/$tfile
24462 }
24463 run_test 813 "File heat verfication"
24464
24465 test_814()
24466 {
24467         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
24468         echo -n y >> $DIR/$tfile
24469         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
24470         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
24471 }
24472 run_test 814 "sparse cp works as expected (LU-12361)"
24473
24474 test_815()
24475 {
24476         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
24477         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
24478 }
24479 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
24480
24481 test_816() {
24482         [ "$SHARED_KEY" = true ] &&
24483                 skip "OSC connections never go IDLE with Shared-Keys enabled"
24484
24485         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24486         # ensure ost1 is connected
24487         stat $DIR/$tfile >/dev/null || error "can't stat"
24488         wait_osc_import_state client ost1 FULL
24489         # no locks, no reqs to let the connection idle
24490         cancel_lru_locks osc
24491         lru_resize_disable osc
24492         local before
24493         local now
24494         before=$($LCTL get_param -n \
24495                  ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
24496
24497         wait_osc_import_state client ost1 IDLE
24498         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
24499         now=$($LCTL get_param -n \
24500               ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
24501         [ $before == $now ] || error "lru_size changed $before != $now"
24502 }
24503 run_test 816 "do not reset lru_resize on idle reconnect"
24504
24505 cleanup_817() {
24506         umount $tmpdir
24507         exportfs -u localhost:$DIR/nfsexp
24508         rm -rf $DIR/nfsexp
24509 }
24510
24511 test_817() {
24512         systemctl restart nfs-server.service || skip "failed to restart nfsd"
24513
24514         mkdir -p $DIR/nfsexp
24515         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
24516                 error "failed to export nfs"
24517
24518         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
24519         stack_trap cleanup_817 EXIT
24520
24521         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
24522                 error "failed to mount nfs to $tmpdir"
24523
24524         cp /bin/true $tmpdir
24525         $DIR/nfsexp/true || error "failed to execute 'true' command"
24526 }
24527 run_test 817 "nfsd won't cache write lock for exec file"
24528
24529 test_818() {
24530         mkdir $DIR/$tdir
24531         $LFS setstripe -c1 -i0 $DIR/$tfile
24532         $LFS setstripe -c1 -i1 $DIR/$tfile
24533         stop $SINGLEMDS
24534         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
24535         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
24536         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
24537                 error "start $SINGLEMDS failed"
24538         rm -rf $DIR/$tdir
24539 }
24540 run_test 818 "unlink with failed llog"
24541
24542 test_819a() {
24543         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24544         cancel_lru_locks osc
24545         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
24546         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
24547         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
24548         rm -f $TDIR/$tfile
24549 }
24550 run_test 819a "too big niobuf in read"
24551
24552 test_819b() {
24553         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
24554         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
24555         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24556         cancel_lru_locks osc
24557         sleep 1
24558         rm -f $TDIR/$tfile
24559 }
24560 run_test 819b "too big niobuf in write"
24561
24562
24563 function test_820_start_ost() {
24564         sleep 5
24565
24566         for num in $(seq $OSTCOUNT); do
24567                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
24568         done
24569 }
24570
24571 test_820() {
24572         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24573
24574         mkdir $DIR/$tdir
24575         umount_client $MOUNT || error "umount failed"
24576         for num in $(seq $OSTCOUNT); do
24577                 stop ost$num
24578         done
24579
24580         # mount client with no active OSTs
24581         # so that the client can't initialize max LOV EA size
24582         # from OSC notifications
24583         mount_client $MOUNT || error "mount failed"
24584         # delay OST starting to keep this 0 max EA size for a while
24585         test_820_start_ost &
24586
24587         # create a directory on MDS2
24588         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
24589                 error "Failed to create directory"
24590         # open intent should update default EA size
24591         # see mdc_update_max_ea_from_body()
24592         # notice this is the very first RPC to MDS2
24593         cp /etc/services $DIR/$tdir/mds2 ||
24594                 error "Failed to copy files to mds$n"
24595 }
24596 run_test 820 "update max EA from open intent"
24597
24598 #
24599 # tests that do cleanup/setup should be run at the end
24600 #
24601
24602 test_900() {
24603         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24604         local ls
24605
24606         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
24607         $LCTL set_param fail_loc=0x903
24608
24609         cancel_lru_locks MGC
24610
24611         FAIL_ON_ERROR=true cleanup
24612         FAIL_ON_ERROR=true setup
24613 }
24614 run_test 900 "umount should not race with any mgc requeue thread"
24615
24616 # LUS-6253/LU-11185
24617 test_901() {
24618         local oldc
24619         local newc
24620         local olds
24621         local news
24622         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24623
24624         # some get_param have a bug to handle dot in param name
24625         cancel_lru_locks MGC
24626         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
24627         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
24628         umount_client $MOUNT || error "umount failed"
24629         mount_client $MOUNT || error "mount failed"
24630         cancel_lru_locks MGC
24631         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
24632         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
24633
24634         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
24635         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
24636
24637         return 0
24638 }
24639 run_test 901 "don't leak a mgc lock on client umount"
24640
24641 # LU-13377
24642 test_902() {
24643         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
24644                 skip "client does not have LU-13377 fix"
24645         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
24646         $LCTL set_param fail_loc=0x1415
24647         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24648         cancel_lru_locks osc
24649         rm -f $DIR/$tfile
24650 }
24651 run_test 902 "test short write doesn't hang lustre"
24652
24653 complete $SECONDS
24654 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
24655 check_and_cleanup_lustre
24656 if [ "$I_MOUNTED" != "yes" ]; then
24657         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
24658 fi
24659 exit_status