Whamcloud - gitweb
LU-13765 osd-ldiskfs: Extend credit correctly for fallocate
[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 test_150e() {
13419         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13420         [ $OST1_VERSION -ge $(version_code 2.13.55) ] ||
13421                 skip "Need OST version at least 2.13.55"
13422
13423         echo "df before:"
13424         $LFS df
13425         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
13426                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
13427
13428         # Find OST with Minimum Size
13429         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
13430                        sort -un | head -1)
13431
13432         # Get 90% of the available space
13433         local space=$(((min_size_ost * 90)/100 * OSTCOUNT))
13434
13435         fallocate -l${space}k $DIR/$tfile ||
13436                 error "fallocate ${space}k $DIR/$tfile failed"
13437         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
13438
13439         # get size immediately after fallocate. This should be correctly
13440         # updated
13441         local size=$(stat -c '%s' $DIR/$tfile)
13442         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
13443
13444         # Sleep for a while for statfs to get updated. And not pull from cache.
13445         sleep 2
13446
13447         echo "df after fallocate:"
13448         $LFS df
13449
13450         (( size / 1024 == space )) || error "size $size != requested $space"
13451         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
13452                 error "used $used < space $space"
13453
13454         rm $DIR/$tfile || error "rm failed"
13455         sync
13456         wait_delete_completed
13457
13458         echo "df after unlink:"
13459         $LFS df
13460 }
13461 run_test 150e "Verify 90% of available OST space consumed by fallocate"
13462
13463 #LU-2902 roc_hit was not able to read all values from lproc
13464 function roc_hit_init() {
13465         local list=$(comma_list $(osts_nodes))
13466         local dir=$DIR/$tdir-check
13467         local file=$dir/$tfile
13468         local BEFORE
13469         local AFTER
13470         local idx
13471
13472         test_mkdir $dir
13473         #use setstripe to do a write to every ost
13474         for i in $(seq 0 $((OSTCOUNT-1))); do
13475                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
13476                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
13477                 idx=$(printf %04x $i)
13478                 BEFORE=$(get_osd_param $list *OST*$idx stats |
13479                         awk '$1 == "cache_access" {sum += $7}
13480                                 END { printf("%0.0f", sum) }')
13481
13482                 cancel_lru_locks osc
13483                 cat $file >/dev/null
13484
13485                 AFTER=$(get_osd_param $list *OST*$idx stats |
13486                         awk '$1 == "cache_access" {sum += $7}
13487                                 END { printf("%0.0f", sum) }')
13488
13489                 echo BEFORE:$BEFORE AFTER:$AFTER
13490                 if ! let "AFTER - BEFORE == 4"; then
13491                         rm -rf $dir
13492                         error "roc_hit is not safe to use"
13493                 fi
13494                 rm $file
13495         done
13496
13497         rm -rf $dir
13498 }
13499
13500 function roc_hit() {
13501         local list=$(comma_list $(osts_nodes))
13502         echo $(get_osd_param $list '' stats |
13503                 awk '$1 == "cache_hit" {sum += $7}
13504                         END { printf("%0.0f", sum) }')
13505 }
13506
13507 function set_cache() {
13508         local on=1
13509
13510         if [ "$2" == "off" ]; then
13511                 on=0;
13512         fi
13513         local list=$(comma_list $(osts_nodes))
13514         set_osd_param $list '' $1_cache_enable $on
13515
13516         cancel_lru_locks osc
13517 }
13518
13519 test_151() {
13520         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13521         remote_ost_nodsh && skip "remote OST with nodsh"
13522
13523         local CPAGES=3
13524         local list=$(comma_list $(osts_nodes))
13525
13526         # check whether obdfilter is cache capable at all
13527         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
13528                 skip "not cache-capable obdfilter"
13529         fi
13530
13531         # check cache is enabled on all obdfilters
13532         if get_osd_param $list '' read_cache_enable | grep 0; then
13533                 skip "oss cache is disabled"
13534         fi
13535
13536         set_osd_param $list '' writethrough_cache_enable 1
13537
13538         # check write cache is enabled on all obdfilters
13539         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
13540                 skip "oss write cache is NOT enabled"
13541         fi
13542
13543         roc_hit_init
13544
13545         #define OBD_FAIL_OBD_NO_LRU  0x609
13546         do_nodes $list $LCTL set_param fail_loc=0x609
13547
13548         # pages should be in the case right after write
13549         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
13550                 error "dd failed"
13551
13552         local BEFORE=$(roc_hit)
13553         cancel_lru_locks osc
13554         cat $DIR/$tfile >/dev/null
13555         local AFTER=$(roc_hit)
13556
13557         do_nodes $list $LCTL set_param fail_loc=0
13558
13559         if ! let "AFTER - BEFORE == CPAGES"; then
13560                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
13561         fi
13562
13563         cancel_lru_locks osc
13564         # invalidates OST cache
13565         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
13566         set_osd_param $list '' read_cache_enable 0
13567         cat $DIR/$tfile >/dev/null
13568
13569         # now data shouldn't be found in the cache
13570         BEFORE=$(roc_hit)
13571         cancel_lru_locks osc
13572         cat $DIR/$tfile >/dev/null
13573         AFTER=$(roc_hit)
13574         if let "AFTER - BEFORE != 0"; then
13575                 error "IN CACHE: before: $BEFORE, after: $AFTER"
13576         fi
13577
13578         set_osd_param $list '' read_cache_enable 1
13579         rm -f $DIR/$tfile
13580 }
13581 run_test 151 "test cache on oss and controls ==============================="
13582
13583 test_152() {
13584         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13585
13586         local TF="$TMP/$tfile"
13587
13588         # simulate ENOMEM during write
13589 #define OBD_FAIL_OST_NOMEM      0x226
13590         lctl set_param fail_loc=0x80000226
13591         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13592         cp $TF $DIR/$tfile
13593         sync || error "sync failed"
13594         lctl set_param fail_loc=0
13595
13596         # discard client's cache
13597         cancel_lru_locks osc
13598
13599         # simulate ENOMEM during read
13600         lctl set_param fail_loc=0x80000226
13601         cmp $TF $DIR/$tfile || error "cmp failed"
13602         lctl set_param fail_loc=0
13603
13604         rm -f $TF
13605 }
13606 run_test 152 "test read/write with enomem ============================"
13607
13608 test_153() {
13609         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
13610 }
13611 run_test 153 "test if fdatasync does not crash ======================="
13612
13613 dot_lustre_fid_permission_check() {
13614         local fid=$1
13615         local ffid=$MOUNT/.lustre/fid/$fid
13616         local test_dir=$2
13617
13618         echo "stat fid $fid"
13619         stat $ffid > /dev/null || error "stat $ffid failed."
13620         echo "touch fid $fid"
13621         touch $ffid || error "touch $ffid failed."
13622         echo "write to fid $fid"
13623         cat /etc/hosts > $ffid || error "write $ffid failed."
13624         echo "read fid $fid"
13625         diff /etc/hosts $ffid || error "read $ffid failed."
13626         echo "append write to fid $fid"
13627         cat /etc/hosts >> $ffid || error "append write $ffid failed."
13628         echo "rename fid $fid"
13629         mv $ffid $test_dir/$tfile.1 &&
13630                 error "rename $ffid to $tfile.1 should fail."
13631         touch $test_dir/$tfile.1
13632         mv $test_dir/$tfile.1 $ffid &&
13633                 error "rename $tfile.1 to $ffid should fail."
13634         rm -f $test_dir/$tfile.1
13635         echo "truncate fid $fid"
13636         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
13637         echo "link fid $fid"
13638         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
13639         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
13640                 echo "setfacl fid $fid"
13641                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
13642                 echo "getfacl fid $fid"
13643                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
13644         fi
13645         echo "unlink fid $fid"
13646         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
13647         echo "mknod fid $fid"
13648         mknod $ffid c 1 3 && error "mknod $ffid should fail."
13649
13650         fid=[0xf00000400:0x1:0x0]
13651         ffid=$MOUNT/.lustre/fid/$fid
13652
13653         echo "stat non-exist fid $fid"
13654         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
13655         echo "write to non-exist fid $fid"
13656         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
13657         echo "link new fid $fid"
13658         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
13659
13660         mkdir -p $test_dir/$tdir
13661         touch $test_dir/$tdir/$tfile
13662         fid=$($LFS path2fid $test_dir/$tdir)
13663         rc=$?
13664         [ $rc -ne 0 ] &&
13665                 error "error: could not get fid for $test_dir/$dir/$tfile."
13666
13667         ffid=$MOUNT/.lustre/fid/$fid
13668
13669         echo "ls $fid"
13670         ls $ffid > /dev/null || error "ls $ffid failed."
13671         echo "touch $fid/$tfile.1"
13672         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
13673
13674         echo "touch $MOUNT/.lustre/fid/$tfile"
13675         touch $MOUNT/.lustre/fid/$tfile && \
13676                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
13677
13678         echo "setxattr to $MOUNT/.lustre/fid"
13679         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
13680
13681         echo "listxattr for $MOUNT/.lustre/fid"
13682         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
13683
13684         echo "delxattr from $MOUNT/.lustre/fid"
13685         setfattr -x trusted.name1 $MOUNT/.lustre/fid
13686
13687         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
13688         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
13689                 error "touch invalid fid should fail."
13690
13691         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
13692         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
13693                 error "touch non-normal fid should fail."
13694
13695         echo "rename $tdir to $MOUNT/.lustre/fid"
13696         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
13697                 error "rename to $MOUNT/.lustre/fid should fail."
13698
13699         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
13700         then            # LU-3547
13701                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
13702                 local new_obf_mode=777
13703
13704                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
13705                 chmod $new_obf_mode $DIR/.lustre/fid ||
13706                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
13707
13708                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
13709                 [ $obf_mode -eq $new_obf_mode ] ||
13710                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
13711
13712                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
13713                 chmod $old_obf_mode $DIR/.lustre/fid ||
13714                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
13715         fi
13716
13717         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
13718         fid=$($LFS path2fid $test_dir/$tfile-2)
13719
13720         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
13721         then # LU-5424
13722                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
13723                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
13724                         error "create lov data thru .lustre failed"
13725         fi
13726         echo "cp /etc/passwd $test_dir/$tfile-2"
13727         cp /etc/passwd $test_dir/$tfile-2 ||
13728                 error "copy to $test_dir/$tfile-2 failed."
13729         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
13730         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
13731                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
13732
13733         rm -rf $test_dir/tfile.lnk
13734         rm -rf $test_dir/$tfile-2
13735 }
13736
13737 test_154A() {
13738         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13739                 skip "Need MDS version at least 2.4.1"
13740
13741         local tf=$DIR/$tfile
13742         touch $tf
13743
13744         local fid=$($LFS path2fid $tf)
13745         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
13746
13747         # check that we get the same pathname back
13748         local rootpath
13749         local found
13750         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
13751                 echo "$rootpath $fid"
13752                 found=$($LFS fid2path $rootpath "$fid")
13753                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
13754                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
13755         done
13756
13757         # check wrong root path format
13758         rootpath=$MOUNT"_wrong"
13759         found=$($LFS fid2path $rootpath "$fid")
13760         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
13761 }
13762 run_test 154A "lfs path2fid and fid2path basic checks"
13763
13764 test_154B() {
13765         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13766                 skip "Need MDS version at least 2.4.1"
13767
13768         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
13769         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
13770         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
13771         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
13772
13773         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
13774         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
13775
13776         # check that we get the same pathname
13777         echo "PFID: $PFID, name: $name"
13778         local FOUND=$($LFS fid2path $MOUNT "$PFID")
13779         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
13780         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
13781                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
13782
13783         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
13784 }
13785 run_test 154B "verify the ll_decode_linkea tool"
13786
13787 test_154a() {
13788         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13789         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13790         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
13791                 skip "Need MDS version at least 2.2.51"
13792         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13793
13794         cp /etc/hosts $DIR/$tfile
13795
13796         fid=$($LFS path2fid $DIR/$tfile)
13797         rc=$?
13798         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
13799
13800         dot_lustre_fid_permission_check "$fid" $DIR ||
13801                 error "dot lustre permission check $fid failed"
13802
13803         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
13804
13805         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
13806
13807         touch $MOUNT/.lustre/file &&
13808                 error "creation is not allowed under .lustre"
13809
13810         mkdir $MOUNT/.lustre/dir &&
13811                 error "mkdir is not allowed under .lustre"
13812
13813         rm -rf $DIR/$tfile
13814 }
13815 run_test 154a "Open-by-FID"
13816
13817 test_154b() {
13818         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13819         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13820         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13821         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
13822                 skip "Need MDS version at least 2.2.51"
13823
13824         local remote_dir=$DIR/$tdir/remote_dir
13825         local MDTIDX=1
13826         local rc=0
13827
13828         mkdir -p $DIR/$tdir
13829         $LFS mkdir -i $MDTIDX $remote_dir ||
13830                 error "create remote directory failed"
13831
13832         cp /etc/hosts $remote_dir/$tfile
13833
13834         fid=$($LFS path2fid $remote_dir/$tfile)
13835         rc=$?
13836         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
13837
13838         dot_lustre_fid_permission_check "$fid" $remote_dir ||
13839                 error "dot lustre permission check $fid failed"
13840         rm -rf $DIR/$tdir
13841 }
13842 run_test 154b "Open-by-FID for remote directory"
13843
13844 test_154c() {
13845         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13846                 skip "Need MDS version at least 2.4.1"
13847
13848         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
13849         local FID1=$($LFS path2fid $DIR/$tfile.1)
13850         local FID2=$($LFS path2fid $DIR/$tfile.2)
13851         local FID3=$($LFS path2fid $DIR/$tfile.3)
13852
13853         local N=1
13854         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
13855                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
13856                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
13857                 local want=FID$N
13858                 [ "$FID" = "${!want}" ] ||
13859                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
13860                 N=$((N + 1))
13861         done
13862
13863         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
13864         do
13865                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
13866                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
13867                 N=$((N + 1))
13868         done
13869 }
13870 run_test 154c "lfs path2fid and fid2path multiple arguments"
13871
13872 test_154d() {
13873         remote_mds_nodsh && skip "remote MDS with nodsh"
13874         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
13875                 skip "Need MDS version at least 2.5.53"
13876
13877         if remote_mds; then
13878                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
13879         else
13880                 nid="0@lo"
13881         fi
13882         local proc_ofile="mdt.*.exports.'$nid'.open_files"
13883         local fd
13884         local cmd
13885
13886         rm -f $DIR/$tfile
13887         touch $DIR/$tfile
13888
13889         local fid=$($LFS path2fid $DIR/$tfile)
13890         # Open the file
13891         fd=$(free_fd)
13892         cmd="exec $fd<$DIR/$tfile"
13893         eval $cmd
13894         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
13895         echo "$fid_list" | grep "$fid"
13896         rc=$?
13897
13898         cmd="exec $fd>/dev/null"
13899         eval $cmd
13900         if [ $rc -ne 0 ]; then
13901                 error "FID $fid not found in open files list $fid_list"
13902         fi
13903 }
13904 run_test 154d "Verify open file fid"
13905
13906 test_154e()
13907 {
13908         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
13909                 skip "Need MDS version at least 2.6.50"
13910
13911         if ls -a $MOUNT | grep -q '^\.lustre$'; then
13912                 error ".lustre returned by readdir"
13913         fi
13914 }
13915 run_test 154e ".lustre is not returned by readdir"
13916
13917 test_154f() {
13918         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13919
13920         # create parent directory on a single MDT to avoid cross-MDT hardlinks
13921         test_mkdir -p -c1 $DIR/$tdir/d
13922         # test dirs inherit from its stripe
13923         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
13924         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
13925         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
13926         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
13927         touch $DIR/f
13928
13929         # get fid of parents
13930         local FID0=$($LFS path2fid $DIR/$tdir/d)
13931         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
13932         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
13933         local FID3=$($LFS path2fid $DIR)
13934
13935         # check that path2fid --parents returns expected <parent_fid>/name
13936         # 1) test for a directory (single parent)
13937         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
13938         [ "$parent" == "$FID0/foo1" ] ||
13939                 error "expected parent: $FID0/foo1, got: $parent"
13940
13941         # 2) test for a file with nlink > 1 (multiple parents)
13942         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
13943         echo "$parent" | grep -F "$FID1/$tfile" ||
13944                 error "$FID1/$tfile not returned in parent list"
13945         echo "$parent" | grep -F "$FID2/link" ||
13946                 error "$FID2/link not returned in parent list"
13947
13948         # 3) get parent by fid
13949         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
13950         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13951         echo "$parent" | grep -F "$FID1/$tfile" ||
13952                 error "$FID1/$tfile not returned in parent list (by fid)"
13953         echo "$parent" | grep -F "$FID2/link" ||
13954                 error "$FID2/link not returned in parent list (by fid)"
13955
13956         # 4) test for entry in root directory
13957         parent=$($LFS path2fid --parents $DIR/f)
13958         echo "$parent" | grep -F "$FID3/f" ||
13959                 error "$FID3/f not returned in parent list"
13960
13961         # 5) test it on root directory
13962         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
13963                 error "$MOUNT should not have parents"
13964
13965         # enable xattr caching and check that linkea is correctly updated
13966         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
13967         save_lustre_params client "llite.*.xattr_cache" > $save
13968         lctl set_param llite.*.xattr_cache 1
13969
13970         # 6.1) linkea update on rename
13971         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
13972
13973         # get parents by fid
13974         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13975         # foo1 should no longer be returned in parent list
13976         echo "$parent" | grep -F "$FID1" &&
13977                 error "$FID1 should no longer be in parent list"
13978         # the new path should appear
13979         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
13980                 error "$FID2/$tfile.moved is not in parent list"
13981
13982         # 6.2) linkea update on unlink
13983         rm -f $DIR/$tdir/d/foo2/link
13984         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13985         # foo2/link should no longer be returned in parent list
13986         echo "$parent" | grep -F "$FID2/link" &&
13987                 error "$FID2/link should no longer be in parent list"
13988         true
13989
13990         rm -f $DIR/f
13991         restore_lustre_params < $save
13992         rm -f $save
13993 }
13994 run_test 154f "get parent fids by reading link ea"
13995
13996 test_154g()
13997 {
13998         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13999         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
14000            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
14001                 skip "Need MDS version at least 2.6.92"
14002
14003         mkdir -p $DIR/$tdir
14004         llapi_fid_test -d $DIR/$tdir
14005 }
14006 run_test 154g "various llapi FID tests"
14007
14008 test_155_small_load() {
14009     local temp=$TMP/$tfile
14010     local file=$DIR/$tfile
14011
14012     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
14013         error "dd of=$temp bs=6096 count=1 failed"
14014     cp $temp $file
14015     cancel_lru_locks $OSC
14016     cmp $temp $file || error "$temp $file differ"
14017
14018     $TRUNCATE $temp 6000
14019     $TRUNCATE $file 6000
14020     cmp $temp $file || error "$temp $file differ (truncate1)"
14021
14022     echo "12345" >>$temp
14023     echo "12345" >>$file
14024     cmp $temp $file || error "$temp $file differ (append1)"
14025
14026     echo "12345" >>$temp
14027     echo "12345" >>$file
14028     cmp $temp $file || error "$temp $file differ (append2)"
14029
14030     rm -f $temp $file
14031     true
14032 }
14033
14034 test_155_big_load() {
14035         remote_ost_nodsh && skip "remote OST with nodsh"
14036
14037         local temp=$TMP/$tfile
14038         local file=$DIR/$tfile
14039
14040         free_min_max
14041         local cache_size=$(do_facet ost$((MAXI+1)) \
14042                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
14043         local large_file_size=$((cache_size * 2))
14044
14045         echo "OSS cache size: $cache_size KB"
14046         echo "Large file size: $large_file_size KB"
14047
14048         [ $MAXV -le $large_file_size ] &&
14049                 skip_env "max available OST size needs > $large_file_size KB"
14050
14051         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
14052
14053         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
14054                 error "dd of=$temp bs=$large_file_size count=1k failed"
14055         cp $temp $file
14056         ls -lh $temp $file
14057         cancel_lru_locks osc
14058         cmp $temp $file || error "$temp $file differ"
14059
14060         rm -f $temp $file
14061         true
14062 }
14063
14064 save_writethrough() {
14065         local facets=$(get_facets OST)
14066
14067         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
14068 }
14069
14070 test_155a() {
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 on
14078         set_cache writethrough on
14079         test_155_small_load
14080         restore_lustre_params < $p
14081         rm -f $p
14082 }
14083 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
14084
14085 test_155b() {
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 off
14094         test_155_small_load
14095         restore_lustre_params < $p
14096         rm -f $p
14097 }
14098 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
14099
14100 test_155c() {
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 off
14108         set_cache writethrough on
14109         test_155_small_load
14110         restore_lustre_params < $p
14111         rm -f $p
14112 }
14113 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
14114
14115 test_155d() {
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 off
14124         test_155_small_load
14125         restore_lustre_params < $p
14126         rm -f $p
14127 }
14128 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
14129
14130 test_155e() {
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 on
14138         set_cache writethrough on
14139         test_155_big_load
14140         restore_lustre_params < $p
14141         rm -f $p
14142 }
14143 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
14144
14145 test_155f() {
14146         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14147
14148         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14149
14150         save_writethrough $p
14151
14152         set_cache read on
14153         set_cache writethrough off
14154         test_155_big_load
14155         restore_lustre_params < $p
14156         rm -f $p
14157 }
14158 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
14159
14160 test_155g() {
14161         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14162
14163         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14164
14165         save_writethrough $p
14166
14167         set_cache read off
14168         set_cache writethrough on
14169         test_155_big_load
14170         restore_lustre_params < $p
14171         rm -f $p
14172 }
14173 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
14174
14175 test_155h() {
14176         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14177
14178         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14179
14180         save_writethrough $p
14181
14182         set_cache read off
14183         set_cache writethrough off
14184         test_155_big_load
14185         restore_lustre_params < $p
14186         rm -f $p
14187 }
14188 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
14189
14190 test_156() {
14191         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14192         remote_ost_nodsh && skip "remote OST with nodsh"
14193         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
14194                 skip "stats not implemented on old servers"
14195         [ "$ost1_FSTYPE" = "zfs" ] &&
14196                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
14197
14198         local CPAGES=3
14199         local BEFORE
14200         local AFTER
14201         local file="$DIR/$tfile"
14202         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14203
14204         save_writethrough $p
14205         roc_hit_init
14206
14207         log "Turn on read and write cache"
14208         set_cache read on
14209         set_cache writethrough on
14210
14211         log "Write data and read it back."
14212         log "Read should be satisfied from the cache."
14213         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14214         BEFORE=$(roc_hit)
14215         cancel_lru_locks osc
14216         cat $file >/dev/null
14217         AFTER=$(roc_hit)
14218         if ! let "AFTER - BEFORE == CPAGES"; then
14219                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
14220         else
14221                 log "cache hits: before: $BEFORE, after: $AFTER"
14222         fi
14223
14224         log "Read again; it should be satisfied from the cache."
14225         BEFORE=$AFTER
14226         cancel_lru_locks osc
14227         cat $file >/dev/null
14228         AFTER=$(roc_hit)
14229         if ! let "AFTER - BEFORE == CPAGES"; then
14230                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
14231         else
14232                 log "cache hits:: before: $BEFORE, after: $AFTER"
14233         fi
14234
14235         log "Turn off the read cache and turn on the write cache"
14236         set_cache read off
14237         set_cache writethrough on
14238
14239         log "Read again; it should be satisfied from the cache."
14240         BEFORE=$(roc_hit)
14241         cancel_lru_locks osc
14242         cat $file >/dev/null
14243         AFTER=$(roc_hit)
14244         if ! let "AFTER - BEFORE == CPAGES"; then
14245                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
14246         else
14247                 log "cache hits:: before: $BEFORE, after: $AFTER"
14248         fi
14249
14250         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14251                 # > 2.12.56 uses pagecache if cached
14252                 log "Read again; it should not be satisfied from the cache."
14253                 BEFORE=$AFTER
14254                 cancel_lru_locks osc
14255                 cat $file >/dev/null
14256                 AFTER=$(roc_hit)
14257                 if ! let "AFTER - BEFORE == 0"; then
14258                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
14259                 else
14260                         log "cache hits:: before: $BEFORE, after: $AFTER"
14261                 fi
14262         fi
14263
14264         log "Write data and read it back."
14265         log "Read should be satisfied from the cache."
14266         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14267         BEFORE=$(roc_hit)
14268         cancel_lru_locks osc
14269         cat $file >/dev/null
14270         AFTER=$(roc_hit)
14271         if ! let "AFTER - BEFORE == CPAGES"; then
14272                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
14273         else
14274                 log "cache hits:: before: $BEFORE, after: $AFTER"
14275         fi
14276
14277         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14278                 # > 2.12.56 uses pagecache if cached
14279                 log "Read again; it should not be satisfied from the cache."
14280                 BEFORE=$AFTER
14281                 cancel_lru_locks osc
14282                 cat $file >/dev/null
14283                 AFTER=$(roc_hit)
14284                 if ! let "AFTER - BEFORE == 0"; then
14285                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
14286                 else
14287                         log "cache hits:: before: $BEFORE, after: $AFTER"
14288                 fi
14289         fi
14290
14291         log "Turn off read and write cache"
14292         set_cache read off
14293         set_cache writethrough off
14294
14295         log "Write data and read it back"
14296         log "It should not be satisfied from the cache."
14297         rm -f $file
14298         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14299         cancel_lru_locks osc
14300         BEFORE=$(roc_hit)
14301         cat $file >/dev/null
14302         AFTER=$(roc_hit)
14303         if ! let "AFTER - BEFORE == 0"; then
14304                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
14305         else
14306                 log "cache hits:: before: $BEFORE, after: $AFTER"
14307         fi
14308
14309         log "Turn on the read cache and turn off the write cache"
14310         set_cache read on
14311         set_cache writethrough off
14312
14313         log "Write data and read it back"
14314         log "It should not be satisfied from the cache."
14315         rm -f $file
14316         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14317         BEFORE=$(roc_hit)
14318         cancel_lru_locks osc
14319         cat $file >/dev/null
14320         AFTER=$(roc_hit)
14321         if ! let "AFTER - BEFORE == 0"; then
14322                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
14323         else
14324                 log "cache hits:: before: $BEFORE, after: $AFTER"
14325         fi
14326
14327         log "Read again; it should be satisfied from the cache."
14328         BEFORE=$(roc_hit)
14329         cancel_lru_locks osc
14330         cat $file >/dev/null
14331         AFTER=$(roc_hit)
14332         if ! let "AFTER - BEFORE == CPAGES"; then
14333                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
14334         else
14335                 log "cache hits:: before: $BEFORE, after: $AFTER"
14336         fi
14337
14338         restore_lustre_params < $p
14339         rm -f $p $file
14340 }
14341 run_test 156 "Verification of tunables"
14342
14343 test_160a() {
14344         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14345         remote_mds_nodsh && skip "remote MDS with nodsh"
14346         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14347                 skip "Need MDS version at least 2.2.0"
14348
14349         changelog_register || error "changelog_register failed"
14350         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14351         changelog_users $SINGLEMDS | grep -q $cl_user ||
14352                 error "User $cl_user not found in changelog_users"
14353
14354         # change something
14355         test_mkdir -p $DIR/$tdir/pics/2008/zachy
14356         changelog_clear 0 || error "changelog_clear failed"
14357         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
14358         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
14359         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
14360         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
14361         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
14362         rm $DIR/$tdir/pics/desktop.jpg
14363
14364         changelog_dump | tail -10
14365
14366         echo "verifying changelog mask"
14367         changelog_chmask "-MKDIR"
14368         changelog_chmask "-CLOSE"
14369
14370         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
14371         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
14372
14373         changelog_chmask "+MKDIR"
14374         changelog_chmask "+CLOSE"
14375
14376         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
14377         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
14378
14379         changelog_dump | tail -10
14380         MKDIRS=$(changelog_dump | grep -c "MKDIR")
14381         CLOSES=$(changelog_dump | grep -c "CLOSE")
14382         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
14383         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
14384
14385         # verify contents
14386         echo "verifying target fid"
14387         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
14388         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
14389         [ "$fidc" == "$fidf" ] ||
14390                 error "changelog '$tfile' fid $fidc != file fid $fidf"
14391         echo "verifying parent fid"
14392         # The FID returned from the Changelog may be the directory shard on
14393         # a different MDT, and not the FID returned by path2fid on the parent.
14394         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
14395         # since this is what will matter when recreating this file in the tree.
14396         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
14397         local pathp=$($LFS fid2path $MOUNT "$fidp")
14398         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
14399                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
14400
14401         echo "getting records for $cl_user"
14402         changelog_users $SINGLEMDS
14403         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
14404         local nclr=3
14405         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
14406                 error "changelog_clear failed"
14407         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
14408         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
14409         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
14410                 error "user index expect $user_rec1 + $nclr != $user_rec2"
14411
14412         local min0_rec=$(changelog_users $SINGLEMDS |
14413                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
14414         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
14415                           awk '{ print $1; exit; }')
14416
14417         changelog_dump | tail -n 5
14418         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
14419         [ $first_rec == $((min0_rec + 1)) ] ||
14420                 error "first index should be $min0_rec + 1 not $first_rec"
14421
14422         # LU-3446 changelog index reset on MDT restart
14423         local cur_rec1=$(changelog_users $SINGLEMDS |
14424                          awk '/^current.index:/ { print $NF }')
14425         changelog_clear 0 ||
14426                 error "clear all changelog records for $cl_user failed"
14427         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
14428         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
14429                 error "Fail to start $SINGLEMDS"
14430         local cur_rec2=$(changelog_users $SINGLEMDS |
14431                          awk '/^current.index:/ { print $NF }')
14432         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
14433         [ $cur_rec1 == $cur_rec2 ] ||
14434                 error "current index should be $cur_rec1 not $cur_rec2"
14435
14436         echo "verifying users from this test are deregistered"
14437         changelog_deregister || error "changelog_deregister failed"
14438         changelog_users $SINGLEMDS | grep -q $cl_user &&
14439                 error "User '$cl_user' still in changelog_users"
14440
14441         # lctl get_param -n mdd.*.changelog_users
14442         # current index: 144
14443         # ID    index (idle seconds)
14444         # cl3   144 (2)
14445         if ! changelog_users $SINGLEMDS | grep "^cl"; then
14446                 # this is the normal case where all users were deregistered
14447                 # make sure no new records are added when no users are present
14448                 local last_rec1=$(changelog_users $SINGLEMDS |
14449                                   awk '/^current.index:/ { print $NF }')
14450                 touch $DIR/$tdir/chloe
14451                 local last_rec2=$(changelog_users $SINGLEMDS |
14452                                   awk '/^current.index:/ { print $NF }')
14453                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
14454                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
14455         else
14456                 # any changelog users must be leftovers from a previous test
14457                 changelog_users $SINGLEMDS
14458                 echo "other changelog users; can't verify off"
14459         fi
14460 }
14461 run_test 160a "changelog sanity"
14462
14463 test_160b() { # LU-3587
14464         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14465         remote_mds_nodsh && skip "remote MDS with nodsh"
14466         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14467                 skip "Need MDS version at least 2.2.0"
14468
14469         changelog_register || error "changelog_register failed"
14470         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14471         changelog_users $SINGLEMDS | grep -q $cl_user ||
14472                 error "User '$cl_user' not found in changelog_users"
14473
14474         local longname1=$(str_repeat a 255)
14475         local longname2=$(str_repeat b 255)
14476
14477         cd $DIR
14478         echo "creating very long named file"
14479         touch $longname1 || error "create of '$longname1' failed"
14480         echo "renaming very long named file"
14481         mv $longname1 $longname2
14482
14483         changelog_dump | grep RENME | tail -n 5
14484         rm -f $longname2
14485 }
14486 run_test 160b "Verify that very long rename doesn't crash in changelog"
14487
14488 test_160c() {
14489         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14490         remote_mds_nodsh && skip "remote MDS with nodsh"
14491
14492         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
14493                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
14494                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
14495                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
14496
14497         local rc=0
14498
14499         # Registration step
14500         changelog_register || error "changelog_register failed"
14501
14502         rm -rf $DIR/$tdir
14503         mkdir -p $DIR/$tdir
14504         $MCREATE $DIR/$tdir/foo_160c
14505         changelog_chmask "-TRUNC"
14506         $TRUNCATE $DIR/$tdir/foo_160c 200
14507         changelog_chmask "+TRUNC"
14508         $TRUNCATE $DIR/$tdir/foo_160c 199
14509         changelog_dump | tail -n 5
14510         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
14511         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
14512 }
14513 run_test 160c "verify that changelog log catch the truncate event"
14514
14515 test_160d() {
14516         remote_mds_nodsh && skip "remote MDS with nodsh"
14517         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14518         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14519         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
14520                 skip "Need MDS version at least 2.7.60"
14521
14522         # Registration step
14523         changelog_register || error "changelog_register failed"
14524
14525         mkdir -p $DIR/$tdir/migrate_dir
14526         changelog_clear 0 || error "changelog_clear failed"
14527
14528         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
14529         changelog_dump | tail -n 5
14530         local migrates=$(changelog_dump | grep -c "MIGRT")
14531         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
14532 }
14533 run_test 160d "verify that changelog log catch the migrate event"
14534
14535 test_160e() {
14536         remote_mds_nodsh && skip "remote MDS with nodsh"
14537
14538         # Create a user
14539         changelog_register || error "changelog_register failed"
14540
14541         # Delete a future user (expect fail)
14542         local MDT0=$(facet_svc $SINGLEMDS)
14543         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
14544         local rc=$?
14545
14546         if [ $rc -eq 0 ]; then
14547                 error "Deleted non-existant user cl77"
14548         elif [ $rc -ne 2 ]; then
14549                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
14550         fi
14551
14552         # Clear to a bad index (1 billion should be safe)
14553         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
14554         rc=$?
14555
14556         if [ $rc -eq 0 ]; then
14557                 error "Successfully cleared to invalid CL index"
14558         elif [ $rc -ne 22 ]; then
14559                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
14560         fi
14561 }
14562 run_test 160e "changelog negative testing (should return errors)"
14563
14564 test_160f() {
14565         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14566         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14567                 skip "Need MDS version at least 2.10.56"
14568
14569         local mdts=$(comma_list $(mdts_nodes))
14570
14571         # Create a user
14572         changelog_register || error "first changelog_register failed"
14573         changelog_register || error "second changelog_register failed"
14574         local cl_users
14575         declare -A cl_user1
14576         declare -A cl_user2
14577         local user_rec1
14578         local user_rec2
14579         local i
14580
14581         # generate some changelog records to accumulate on each MDT
14582         # use fnv1a because created files should be evenly distributed
14583         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14584                 error "test_mkdir $tdir failed"
14585         log "$(date +%s): creating first files"
14586         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14587                 error "create $DIR/$tdir/$tfile failed"
14588
14589         # check changelogs have been generated
14590         local start=$SECONDS
14591         local idle_time=$((MDSCOUNT * 5 + 5))
14592         local nbcl=$(changelog_dump | wc -l)
14593         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14594
14595         for param in "changelog_max_idle_time=$idle_time" \
14596                      "changelog_gc=1" \
14597                      "changelog_min_gc_interval=2" \
14598                      "changelog_min_free_cat_entries=3"; do
14599                 local MDT0=$(facet_svc $SINGLEMDS)
14600                 local var="${param%=*}"
14601                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14602
14603                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14604                 do_nodes $mdts $LCTL set_param mdd.*.$param
14605         done
14606
14607         # force cl_user2 to be idle (1st part), but also cancel the
14608         # cl_user1 records so that it is not evicted later in the test.
14609         local sleep1=$((idle_time / 2))
14610         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
14611         sleep $sleep1
14612
14613         # simulate changelog catalog almost full
14614         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
14615         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
14616
14617         for i in $(seq $MDSCOUNT); do
14618                 cl_users=(${CL_USERS[mds$i]})
14619                 cl_user1[mds$i]="${cl_users[0]}"
14620                 cl_user2[mds$i]="${cl_users[1]}"
14621
14622                 [ -n "${cl_user1[mds$i]}" ] ||
14623                         error "mds$i: no user registered"
14624                 [ -n "${cl_user2[mds$i]}" ] ||
14625                         error "mds$i: only ${cl_user2[mds$i]} is registered"
14626
14627                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14628                 [ -n "$user_rec1" ] ||
14629                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14630                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14631                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14632                 [ -n "$user_rec2" ] ||
14633                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14634                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14635                      "$user_rec1 + 2 == $user_rec2"
14636                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14637                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14638                               "$user_rec1 + 2, but is $user_rec2"
14639                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14640                 [ -n "$user_rec2" ] ||
14641                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14642                 [ $user_rec1 == $user_rec2 ] ||
14643                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14644                               "$user_rec1, but is $user_rec2"
14645         done
14646
14647         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
14648         local sleep2=$((idle_time - (SECONDS - start) + 1))
14649         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
14650         sleep $sleep2
14651
14652         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
14653         # cl_user1 should be OK because it recently processed records.
14654         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
14655         createmany -m $DIR/$tdir/${tfile}b $((MDSCOUNT * 2)) ||
14656                 error "create $DIR/$tdir/${tfile}b failed"
14657
14658         # ensure gc thread is done
14659         for i in $(mdts_nodes); do
14660                 wait_update $i \
14661                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
14662                         error "$i: GC-thread not done"
14663         done
14664
14665         local first_rec
14666         for i in $(seq $MDSCOUNT); do
14667                 # check cl_user1 still registered
14668                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14669                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14670                 # check cl_user2 unregistered
14671                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14672                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14673
14674                 # check changelogs are present and starting at $user_rec1 + 1
14675                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14676                 [ -n "$user_rec1" ] ||
14677                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14678                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14679                             awk '{ print $1; exit; }')
14680
14681                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14682                 [ $((user_rec1 + 1)) == $first_rec ] ||
14683                         error "mds$i: first index should be $user_rec1 + 1, " \
14684                               "but is $first_rec"
14685         done
14686 }
14687 run_test 160f "changelog garbage collect (timestamped users)"
14688
14689 test_160g() {
14690         remote_mds_nodsh && skip "remote MDS with nodsh"
14691         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14692                 skip "Need MDS version at least 2.10.56"
14693
14694         local mdts=$(comma_list $(mdts_nodes))
14695
14696         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
14697         do_nodes $mdts $LCTL set_param fail_loc=0x1314
14698
14699         # Create a user
14700         changelog_register || error "first changelog_register failed"
14701         changelog_register || error "second changelog_register failed"
14702         local cl_users
14703         declare -A cl_user1
14704         declare -A cl_user2
14705         local user_rec1
14706         local user_rec2
14707         local i
14708
14709         # generate some changelog records to accumulate on each MDT
14710         # use fnv1a because created files should be evenly distributed
14711         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14712                 error "mkdir $tdir failed"
14713         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14714                 error "create $DIR/$tdir/$tfile failed"
14715
14716         # check changelogs have been generated
14717         local nbcl=$(changelog_dump | wc -l)
14718         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14719
14720         # reduce the max_idle_indexes value to make sure we exceed it
14721         max_ndx=$((nbcl / 2 - 1))
14722
14723         for param in "changelog_max_idle_indexes=$max_ndx" \
14724                      "changelog_gc=1" \
14725                      "changelog_min_gc_interval=2" \
14726                      "changelog_min_free_cat_entries=3"; do
14727                 local MDT0=$(facet_svc $SINGLEMDS)
14728                 local var="${param%=*}"
14729                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14730
14731                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14732                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
14733                         error "unable to set mdd.*.$param"
14734         done
14735
14736         # simulate changelog catalog almost full
14737         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
14738         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
14739
14740         for i in $(seq $MDSCOUNT); do
14741                 cl_users=(${CL_USERS[mds$i]})
14742                 cl_user1[mds$i]="${cl_users[0]}"
14743                 cl_user2[mds$i]="${cl_users[1]}"
14744
14745                 [ -n "${cl_user1[mds$i]}" ] ||
14746                         error "mds$i: no user registered"
14747                 [ -n "${cl_user2[mds$i]}" ] ||
14748                         error "mds$i: only ${cl_user1[mds$i]} is registered"
14749
14750                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14751                 [ -n "$user_rec1" ] ||
14752                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14753                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14754                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14755                 [ -n "$user_rec2" ] ||
14756                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14757                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14758                      "$user_rec1 + 2 == $user_rec2"
14759                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14760                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14761                               "$user_rec1 + 2, but is $user_rec2"
14762                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14763                 [ -n "$user_rec2" ] ||
14764                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14765                 [ $user_rec1 == $user_rec2 ] ||
14766                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14767                               "$user_rec1, but is $user_rec2"
14768         done
14769
14770         # ensure we are past the previous changelog_min_gc_interval set above
14771         sleep 2
14772
14773         # generate one more changelog to trigger fail_loc
14774         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14775                 error "create $DIR/$tdir/${tfile}bis failed"
14776
14777         # ensure gc thread is done
14778         for i in $(mdts_nodes); do
14779                 wait_update $i \
14780                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
14781                         error "$i: GC-thread not done"
14782         done
14783
14784         local first_rec
14785         for i in $(seq $MDSCOUNT); do
14786                 # check cl_user1 still registered
14787                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14788                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14789                 # check cl_user2 unregistered
14790                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14791                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14792
14793                 # check changelogs are present and starting at $user_rec1 + 1
14794                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14795                 [ -n "$user_rec1" ] ||
14796                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14797                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14798                             awk '{ print $1; exit; }')
14799
14800                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14801                 [ $((user_rec1 + 1)) == $first_rec ] ||
14802                         error "mds$i: first index should be $user_rec1 + 1, " \
14803                               "but is $first_rec"
14804         done
14805 }
14806 run_test 160g "changelog garbage collect (old users)"
14807
14808 test_160h() {
14809         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14810         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14811                 skip "Need MDS version at least 2.10.56"
14812
14813         local mdts=$(comma_list $(mdts_nodes))
14814
14815         # Create a user
14816         changelog_register || error "first changelog_register failed"
14817         changelog_register || error "second changelog_register failed"
14818         local cl_users
14819         declare -A cl_user1
14820         declare -A cl_user2
14821         local user_rec1
14822         local user_rec2
14823         local i
14824
14825         # generate some changelog records to accumulate on each MDT
14826         # use fnv1a because created files should be evenly distributed
14827         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14828                 error "test_mkdir $tdir failed"
14829         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14830                 error "create $DIR/$tdir/$tfile failed"
14831
14832         # check changelogs have been generated
14833         local nbcl=$(changelog_dump | wc -l)
14834         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14835
14836         for param in "changelog_max_idle_time=10" \
14837                      "changelog_gc=1" \
14838                      "changelog_min_gc_interval=2"; do
14839                 local MDT0=$(facet_svc $SINGLEMDS)
14840                 local var="${param%=*}"
14841                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14842
14843                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14844                 do_nodes $mdts $LCTL set_param mdd.*.$param
14845         done
14846
14847         # force cl_user2 to be idle (1st part)
14848         sleep 9
14849
14850         for i in $(seq $MDSCOUNT); do
14851                 cl_users=(${CL_USERS[mds$i]})
14852                 cl_user1[mds$i]="${cl_users[0]}"
14853                 cl_user2[mds$i]="${cl_users[1]}"
14854
14855                 [ -n "${cl_user1[mds$i]}" ] ||
14856                         error "mds$i: no user registered"
14857                 [ -n "${cl_user2[mds$i]}" ] ||
14858                         error "mds$i: only ${cl_user2[mds$i]} is registered"
14859
14860                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14861                 [ -n "$user_rec1" ] ||
14862                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14863                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14864                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14865                 [ -n "$user_rec2" ] ||
14866                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14867                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14868                      "$user_rec1 + 2 == $user_rec2"
14869                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14870                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14871                               "$user_rec1 + 2, but is $user_rec2"
14872                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14873                 [ -n "$user_rec2" ] ||
14874                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14875                 [ $user_rec1 == $user_rec2 ] ||
14876                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14877                               "$user_rec1, but is $user_rec2"
14878         done
14879
14880         # force cl_user2 to be idle (2nd part) and to reach
14881         # changelog_max_idle_time
14882         sleep 2
14883
14884         # force each GC-thread start and block then
14885         # one per MDT/MDD, set fail_val accordingly
14886         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
14887         do_nodes $mdts $LCTL set_param fail_loc=0x1316
14888
14889         # generate more changelogs to trigger fail_loc
14890         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14891                 error "create $DIR/$tdir/${tfile}bis failed"
14892
14893         # stop MDT to stop GC-thread, should be done in back-ground as it will
14894         # block waiting for the thread to be released and exit
14895         declare -A stop_pids
14896         for i in $(seq $MDSCOUNT); do
14897                 stop mds$i &
14898                 stop_pids[mds$i]=$!
14899         done
14900
14901         for i in $(mdts_nodes); do
14902                 local facet
14903                 local nb=0
14904                 local facets=$(facets_up_on_host $i)
14905
14906                 for facet in ${facets//,/ }; do
14907                         if [[ $facet == mds* ]]; then
14908                                 nb=$((nb + 1))
14909                         fi
14910                 done
14911                 # ensure each MDS's gc threads are still present and all in "R"
14912                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
14913                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
14914                         error "$i: expected $nb GC-thread"
14915                 wait_update $i \
14916                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
14917                         "R" 20 ||
14918                         error "$i: GC-thread not found in R-state"
14919                 # check umounts of each MDT on MDS have reached kthread_stop()
14920                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
14921                         error "$i: expected $nb umount"
14922                 wait_update $i \
14923                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
14924                         error "$i: umount not found in D-state"
14925         done
14926
14927         # release all GC-threads
14928         do_nodes $mdts $LCTL set_param fail_loc=0
14929
14930         # wait for MDT stop to complete
14931         for i in $(seq $MDSCOUNT); do
14932                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
14933         done
14934
14935         # XXX
14936         # may try to check if any orphan changelog records are present
14937         # via ldiskfs/zfs and llog_reader...
14938
14939         # re-start/mount MDTs
14940         for i in $(seq $MDSCOUNT); do
14941                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
14942                         error "Fail to start mds$i"
14943         done
14944
14945         local first_rec
14946         for i in $(seq $MDSCOUNT); do
14947                 # check cl_user1 still registered
14948                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14949                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14950                 # check cl_user2 unregistered
14951                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14952                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14953
14954                 # check changelogs are present and starting at $user_rec1 + 1
14955                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14956                 [ -n "$user_rec1" ] ||
14957                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14958                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14959                             awk '{ print $1; exit; }')
14960
14961                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14962                 [ $((user_rec1 + 1)) == $first_rec ] ||
14963                         error "mds$i: first index should be $user_rec1 + 1, " \
14964                               "but is $first_rec"
14965         done
14966 }
14967 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
14968               "during mount"
14969
14970 test_160i() {
14971
14972         local mdts=$(comma_list $(mdts_nodes))
14973
14974         changelog_register || error "first changelog_register failed"
14975
14976         # generate some changelog records to accumulate on each MDT
14977         # use fnv1a because created files should be evenly distributed
14978         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14979                 error "mkdir $tdir failed"
14980         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14981                 error "create $DIR/$tdir/$tfile failed"
14982
14983         # check changelogs have been generated
14984         local nbcl=$(changelog_dump | wc -l)
14985         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14986
14987         # simulate race between register and unregister
14988         # XXX as fail_loc is set per-MDS, with DNE configs the race
14989         # simulation will only occur for one MDT per MDS and for the
14990         # others the normal race scenario will take place
14991         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
14992         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
14993         do_nodes $mdts $LCTL set_param fail_val=1
14994
14995         # unregister 1st user
14996         changelog_deregister &
14997         local pid1=$!
14998         # wait some time for deregister work to reach race rdv
14999         sleep 2
15000         # register 2nd user
15001         changelog_register || error "2nd user register failed"
15002
15003         wait $pid1 || error "1st user deregister failed"
15004
15005         local i
15006         local last_rec
15007         declare -A LAST_REC
15008         for i in $(seq $MDSCOUNT); do
15009                 if changelog_users mds$i | grep "^cl"; then
15010                         # make sure new records are added with one user present
15011                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
15012                                           awk '/^current.index:/ { print $NF }')
15013                 else
15014                         error "mds$i has no user registered"
15015                 fi
15016         done
15017
15018         # generate more changelog records to accumulate on each MDT
15019         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15020                 error "create $DIR/$tdir/${tfile}bis failed"
15021
15022         for i in $(seq $MDSCOUNT); do
15023                 last_rec=$(changelog_users $SINGLEMDS |
15024                            awk '/^current.index:/ { print $NF }')
15025                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
15026                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
15027                         error "changelogs are off on mds$i"
15028         done
15029 }
15030 run_test 160i "changelog user register/unregister race"
15031
15032 test_160j() {
15033         remote_mds_nodsh && skip "remote MDS with nodsh"
15034         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
15035                 skip "Need MDS version at least 2.12.56"
15036
15037         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
15038         stack_trap "umount $MOUNT2" EXIT
15039
15040         changelog_register || error "first changelog_register failed"
15041         stack_trap "changelog_deregister" EXIT
15042
15043         # generate some changelog
15044         # use fnv1a because created files should be evenly distributed
15045         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
15046                 error "mkdir $tdir failed"
15047         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15048                 error "create $DIR/$tdir/${tfile}bis failed"
15049
15050         # open the changelog device
15051         exec 3>/dev/changelog-$FSNAME-MDT0000
15052         stack_trap "exec 3>&-" EXIT
15053         exec 4</dev/changelog-$FSNAME-MDT0000
15054         stack_trap "exec 4<&-" EXIT
15055
15056         # umount the first lustre mount
15057         umount $MOUNT
15058         stack_trap "mount_client $MOUNT" EXIT
15059
15060         # read changelog
15061         cat <&4 >/dev/null || error "read changelog failed"
15062
15063         # clear changelog
15064         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15065         changelog_users $SINGLEMDS | grep -q $cl_user ||
15066                 error "User $cl_user not found in changelog_users"
15067
15068         printf 'clear:'$cl_user':0' >&3
15069 }
15070 run_test 160j "client can be umounted  while its chanangelog is being used"
15071
15072 test_160k() {
15073         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15074         remote_mds_nodsh && skip "remote MDS with nodsh"
15075
15076         mkdir -p $DIR/$tdir/1/1
15077
15078         changelog_register || error "changelog_register failed"
15079         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15080
15081         changelog_users $SINGLEMDS | grep -q $cl_user ||
15082                 error "User '$cl_user' not found in changelog_users"
15083 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
15084         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
15085         rmdir $DIR/$tdir/1/1 & sleep 1
15086         mkdir $DIR/$tdir/2
15087         touch $DIR/$tdir/2/2
15088         rm -rf $DIR/$tdir/2
15089
15090         wait
15091         sleep 4
15092
15093         changelog_dump | grep rmdir || error "rmdir not recorded"
15094
15095         rm -rf $DIR/$tdir
15096         changelog_deregister
15097 }
15098 run_test 160k "Verify that changelog records are not lost"
15099
15100 # Verifies that a file passed as a parameter has recently had an operation
15101 # performed on it that has generated an MTIME changelog which contains the
15102 # correct parent FID. As files might reside on a different MDT from the
15103 # parent directory in DNE configurations, the FIDs are translated to paths
15104 # before being compared, which should be identical
15105 compare_mtime_changelog() {
15106         local file="${1}"
15107         local mdtidx
15108         local mtime
15109         local cl_fid
15110         local pdir
15111         local dir
15112
15113         mdtidx=$($LFS getstripe --mdt-index $file)
15114         mdtidx=$(printf "%04x" $mdtidx)
15115
15116         # Obtain the parent FID from the MTIME changelog
15117         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
15118         [ -z "$mtime" ] && error "MTIME changelog not recorded"
15119
15120         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
15121         [ -z "$cl_fid" ] && error "parent FID not present"
15122
15123         # Verify that the path for the parent FID is the same as the path for
15124         # the test directory
15125         pdir=$($LFS fid2path $MOUNT "$cl_fid")
15126
15127         dir=$(dirname $1)
15128
15129         [[ "${pdir%/}" == "$dir" ]] ||
15130                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
15131 }
15132
15133 test_160l() {
15134         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15135
15136         remote_mds_nodsh && skip "remote MDS with nodsh"
15137         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
15138                 skip "Need MDS version at least 2.13.55"
15139
15140         local cl_user
15141
15142         changelog_register || error "changelog_register failed"
15143         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15144
15145         changelog_users $SINGLEMDS | grep -q $cl_user ||
15146                 error "User '$cl_user' not found in changelog_users"
15147
15148         # Clear some types so that MTIME changelogs are generated
15149         changelog_chmask "-CREAT"
15150         changelog_chmask "-CLOSE"
15151
15152         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
15153
15154         # Test CL_MTIME during setattr
15155         touch $DIR/$tdir/$tfile
15156         compare_mtime_changelog $DIR/$tdir/$tfile
15157
15158         # Test CL_MTIME during close
15159         dd if=/dev/urandom of=$DIR/$tdir/${tfile}_2 bs=1M count=64 ||
15160                 error "cannot create file $DIR/$tdir/${tfile}_2"
15161         compare_mtime_changelog $DIR/$tdir/${tfile}_2
15162 }
15163 run_test 160l "Verify that MTIME changelog records contain the parent FID"
15164
15165 test_161a() {
15166         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15167
15168         test_mkdir -c1 $DIR/$tdir
15169         cp /etc/hosts $DIR/$tdir/$tfile
15170         test_mkdir -c1 $DIR/$tdir/foo1
15171         test_mkdir -c1 $DIR/$tdir/foo2
15172         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
15173         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
15174         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
15175         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
15176         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
15177         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15178                 $LFS fid2path $DIR $FID
15179                 error "bad link ea"
15180         fi
15181         # middle
15182         rm $DIR/$tdir/foo2/zachary
15183         # last
15184         rm $DIR/$tdir/foo2/thor
15185         # first
15186         rm $DIR/$tdir/$tfile
15187         # rename
15188         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
15189         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
15190                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
15191         rm $DIR/$tdir/foo2/maggie
15192
15193         # overflow the EA
15194         local longname=$tfile.avg_len_is_thirty_two_
15195         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
15196                 error_noexit 'failed to unlink many hardlinks'" EXIT
15197         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
15198                 error "failed to hardlink many files"
15199         links=$($LFS fid2path $DIR $FID | wc -l)
15200         echo -n "${links}/1000 links in link EA"
15201         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
15202 }
15203 run_test 161a "link ea sanity"
15204
15205 test_161b() {
15206         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15207         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
15208
15209         local MDTIDX=1
15210         local remote_dir=$DIR/$tdir/remote_dir
15211
15212         mkdir -p $DIR/$tdir
15213         $LFS mkdir -i $MDTIDX $remote_dir ||
15214                 error "create remote directory failed"
15215
15216         cp /etc/hosts $remote_dir/$tfile
15217         mkdir -p $remote_dir/foo1
15218         mkdir -p $remote_dir/foo2
15219         ln $remote_dir/$tfile $remote_dir/foo1/sofia
15220         ln $remote_dir/$tfile $remote_dir/foo2/zachary
15221         ln $remote_dir/$tfile $remote_dir/foo1/luna
15222         ln $remote_dir/$tfile $remote_dir/foo2/thor
15223
15224         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
15225                      tr -d ']')
15226         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15227                 $LFS fid2path $DIR $FID
15228                 error "bad link ea"
15229         fi
15230         # middle
15231         rm $remote_dir/foo2/zachary
15232         # last
15233         rm $remote_dir/foo2/thor
15234         # first
15235         rm $remote_dir/$tfile
15236         # rename
15237         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
15238         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
15239         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
15240                 $LFS fid2path $DIR $FID
15241                 error "bad link rename"
15242         fi
15243         rm $remote_dir/foo2/maggie
15244
15245         # overflow the EA
15246         local longname=filename_avg_len_is_thirty_two_
15247         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
15248                 error "failed to hardlink many files"
15249         links=$($LFS fid2path $DIR $FID | wc -l)
15250         echo -n "${links}/1000 links in link EA"
15251         [[ ${links} -gt 60 ]] ||
15252                 error "expected at least 60 links in link EA"
15253         unlinkmany $remote_dir/foo2/$longname 1000 ||
15254         error "failed to unlink many hardlinks"
15255 }
15256 run_test 161b "link ea sanity under remote directory"
15257
15258 test_161c() {
15259         remote_mds_nodsh && skip "remote MDS with nodsh"
15260         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15261         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
15262                 skip "Need MDS version at least 2.1.5"
15263
15264         # define CLF_RENAME_LAST 0x0001
15265         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
15266         changelog_register || error "changelog_register failed"
15267
15268         rm -rf $DIR/$tdir
15269         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
15270         touch $DIR/$tdir/foo_161c
15271         touch $DIR/$tdir/bar_161c
15272         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15273         changelog_dump | grep RENME | tail -n 5
15274         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15275         changelog_clear 0 || error "changelog_clear failed"
15276         if [ x$flags != "x0x1" ]; then
15277                 error "flag $flags is not 0x1"
15278         fi
15279
15280         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
15281         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
15282         touch $DIR/$tdir/foo_161c
15283         touch $DIR/$tdir/bar_161c
15284         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15285         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15286         changelog_dump | grep RENME | tail -n 5
15287         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15288         changelog_clear 0 || error "changelog_clear failed"
15289         if [ x$flags != "x0x0" ]; then
15290                 error "flag $flags is not 0x0"
15291         fi
15292         echo "rename overwrite a target having nlink > 1," \
15293                 "changelog record has flags of $flags"
15294
15295         # rename doesn't overwrite a target (changelog flag 0x0)
15296         touch $DIR/$tdir/foo_161c
15297         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
15298         changelog_dump | grep RENME | tail -n 5
15299         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
15300         changelog_clear 0 || error "changelog_clear failed"
15301         if [ x$flags != "x0x0" ]; then
15302                 error "flag $flags is not 0x0"
15303         fi
15304         echo "rename doesn't overwrite a target," \
15305                 "changelog record has flags of $flags"
15306
15307         # define CLF_UNLINK_LAST 0x0001
15308         # unlink a file having nlink = 1 (changelog flag 0x1)
15309         rm -f $DIR/$tdir/foo2_161c
15310         changelog_dump | grep UNLNK | tail -n 5
15311         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15312         changelog_clear 0 || error "changelog_clear failed"
15313         if [ x$flags != "x0x1" ]; then
15314                 error "flag $flags is not 0x1"
15315         fi
15316         echo "unlink a file having nlink = 1," \
15317                 "changelog record has flags of $flags"
15318
15319         # unlink a file having nlink > 1 (changelog flag 0x0)
15320         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15321         rm -f $DIR/$tdir/foobar_161c
15322         changelog_dump | grep UNLNK | tail -n 5
15323         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15324         changelog_clear 0 || error "changelog_clear failed"
15325         if [ x$flags != "x0x0" ]; then
15326                 error "flag $flags is not 0x0"
15327         fi
15328         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
15329 }
15330 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
15331
15332 test_161d() {
15333         remote_mds_nodsh && skip "remote MDS with nodsh"
15334         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
15335
15336         local pid
15337         local fid
15338
15339         changelog_register || error "changelog_register failed"
15340
15341         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
15342         # interfer with $MOUNT/.lustre/fid/ access
15343         mkdir $DIR/$tdir
15344         [[ $? -eq 0 ]] || error "mkdir failed"
15345
15346         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
15347         $LCTL set_param fail_loc=0x8000140c
15348         # 5s pause
15349         $LCTL set_param fail_val=5
15350
15351         # create file
15352         echo foofoo > $DIR/$tdir/$tfile &
15353         pid=$!
15354
15355         # wait for create to be delayed
15356         sleep 2
15357
15358         ps -p $pid
15359         [[ $? -eq 0 ]] || error "create should be blocked"
15360
15361         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
15362         stack_trap "rm -f $tempfile"
15363         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
15364         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
15365         # some delay may occur during ChangeLog publishing and file read just
15366         # above, that could allow file write to happen finally
15367         [[ -s $tempfile ]] && echo "file should be empty"
15368
15369         $LCTL set_param fail_loc=0
15370
15371         wait $pid
15372         [[ $? -eq 0 ]] || error "create failed"
15373 }
15374 run_test 161d "create with concurrent .lustre/fid access"
15375
15376 check_path() {
15377         local expected="$1"
15378         shift
15379         local fid="$2"
15380
15381         local path
15382         path=$($LFS fid2path "$@")
15383         local rc=$?
15384
15385         if [ $rc -ne 0 ]; then
15386                 error "path looked up of '$expected' failed: rc=$rc"
15387         elif [ "$path" != "$expected" ]; then
15388                 error "path looked up '$path' instead of '$expected'"
15389         else
15390                 echo "FID '$fid' resolves to path '$path' as expected"
15391         fi
15392 }
15393
15394 test_162a() { # was test_162
15395         test_mkdir -p -c1 $DIR/$tdir/d2
15396         touch $DIR/$tdir/d2/$tfile
15397         touch $DIR/$tdir/d2/x1
15398         touch $DIR/$tdir/d2/x2
15399         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
15400         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
15401         # regular file
15402         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
15403         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
15404
15405         # softlink
15406         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
15407         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
15408         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
15409
15410         # softlink to wrong file
15411         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
15412         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
15413         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
15414
15415         # hardlink
15416         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
15417         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
15418         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
15419         # fid2path dir/fsname should both work
15420         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
15421         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
15422
15423         # hardlink count: check that there are 2 links
15424         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
15425         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
15426
15427         # hardlink indexing: remove the first link
15428         rm $DIR/$tdir/d2/p/q/r/hlink
15429         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
15430 }
15431 run_test 162a "path lookup sanity"
15432
15433 test_162b() {
15434         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15435         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15436
15437         mkdir $DIR/$tdir
15438         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
15439                                 error "create striped dir failed"
15440
15441         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
15442                                         tail -n 1 | awk '{print $2}')
15443         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
15444
15445         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
15446         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
15447
15448         # regular file
15449         for ((i=0;i<5;i++)); do
15450                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
15451                         error "get fid for f$i failed"
15452                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
15453
15454                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
15455                         error "get fid for d$i failed"
15456                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
15457         done
15458
15459         return 0
15460 }
15461 run_test 162b "striped directory path lookup sanity"
15462
15463 # LU-4239: Verify fid2path works with paths 100 or more directories deep
15464 test_162c() {
15465         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
15466                 skip "Need MDS version at least 2.7.51"
15467
15468         local lpath=$tdir.local
15469         local rpath=$tdir.remote
15470
15471         test_mkdir $DIR/$lpath
15472         test_mkdir $DIR/$rpath
15473
15474         for ((i = 0; i <= 101; i++)); do
15475                 lpath="$lpath/$i"
15476                 mkdir $DIR/$lpath
15477                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
15478                         error "get fid for local directory $DIR/$lpath failed"
15479                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
15480
15481                 rpath="$rpath/$i"
15482                 test_mkdir $DIR/$rpath
15483                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
15484                         error "get fid for remote directory $DIR/$rpath failed"
15485                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
15486         done
15487
15488         return 0
15489 }
15490 run_test 162c "fid2path works with paths 100 or more directories deep"
15491
15492 oalr_event_count() {
15493         local event="${1}"
15494         local trace="${2}"
15495
15496         awk -v name="${FSNAME}-OST0000" \
15497             -v event="${event}" \
15498             '$1 == "TRACE" && $2 == event && $3 == name' \
15499             "${trace}" |
15500         wc -l
15501 }
15502
15503 oalr_expect_event_count() {
15504         local event="${1}"
15505         local trace="${2}"
15506         local expect="${3}"
15507         local count
15508
15509         count=$(oalr_event_count "${event}" "${trace}")
15510         if ((count == expect)); then
15511                 return 0
15512         fi
15513
15514         error_noexit "${event} event count was '${count}', expected ${expect}"
15515         cat "${trace}" >&2
15516         exit 1
15517 }
15518
15519 cleanup_165() {
15520         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
15521         stop ost1
15522         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
15523 }
15524
15525 setup_165() {
15526         sync # Flush previous IOs so we can count log entries.
15527         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
15528         stack_trap cleanup_165 EXIT
15529 }
15530
15531 test_165a() {
15532         local trace="/tmp/${tfile}.trace"
15533         local rc
15534         local count
15535
15536         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15537         setup_165
15538         sleep 5
15539
15540         do_facet ost1 ofd_access_log_reader --list
15541         stop ost1
15542
15543         do_facet ost1 killall -TERM ofd_access_log_reader
15544         wait
15545         rc=$?
15546
15547         if ((rc != 0)); then
15548                 error "ofd_access_log_reader exited with rc = '${rc}'"
15549         fi
15550
15551         # Parse trace file for discovery events:
15552         oalr_expect_event_count alr_log_add "${trace}" 1
15553         oalr_expect_event_count alr_log_eof "${trace}" 1
15554         oalr_expect_event_count alr_log_free "${trace}" 1
15555 }
15556 run_test 165a "ofd access log discovery"
15557
15558 test_165b() {
15559         local trace="/tmp/${tfile}.trace"
15560         local file="${DIR}/${tfile}"
15561         local pfid1
15562         local pfid2
15563         local -a entry
15564         local rc
15565         local count
15566         local size
15567         local flags
15568
15569         setup_165
15570
15571         lfs setstripe -c 1 -i 0 "${file}"
15572         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15573         do_facet ost1 ofd_access_log_reader --list
15574
15575         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15576         sleep 5
15577         do_facet ost1 killall -TERM ofd_access_log_reader
15578         wait
15579         rc=$?
15580
15581         if ((rc != 0)); then
15582                 error "ofd_access_log_reader exited with rc = '${rc}'"
15583         fi
15584
15585         oalr_expect_event_count alr_log_entry "${trace}" 1
15586
15587         pfid1=$($LFS path2fid "${file}")
15588
15589         # 1     2             3   4    5     6   7    8    9     10
15590         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
15591         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
15592
15593         echo "entry = '${entry[*]}'" >&2
15594
15595         pfid2=${entry[4]}
15596         if [[ "${pfid1}" != "${pfid2}" ]]; then
15597                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
15598         fi
15599
15600         size=${entry[8]}
15601         if ((size != 1048576)); then
15602                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
15603         fi
15604
15605         flags=${entry[10]}
15606         if [[ "${flags}" != "w" ]]; then
15607                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
15608         fi
15609
15610         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15611         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c || error "cannot read '${file}'"
15612         sleep 5
15613         do_facet ost1 killall -TERM ofd_access_log_reader
15614         wait
15615         rc=$?
15616
15617         if ((rc != 0)); then
15618                 error "ofd_access_log_reader exited with rc = '${rc}'"
15619         fi
15620
15621         oalr_expect_event_count alr_log_entry "${trace}" 1
15622
15623         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
15624         echo "entry = '${entry[*]}'" >&2
15625
15626         pfid2=${entry[4]}
15627         if [[ "${pfid1}" != "${pfid2}" ]]; then
15628                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
15629         fi
15630
15631         size=${entry[8]}
15632         if ((size != 524288)); then
15633                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
15634         fi
15635
15636         flags=${entry[10]}
15637         if [[ "${flags}" != "r" ]]; then
15638                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
15639         fi
15640 }
15641 run_test 165b "ofd access log entries are produced and consumed"
15642
15643 test_165c() {
15644         local file="${DIR}/${tdir}/${tfile}"
15645         test_mkdir "${DIR}/${tdir}"
15646
15647         setup_165
15648
15649         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
15650
15651         # 4096 / 64 = 64. Create twice as many entries.
15652         for ((i = 0; i < 128; i++)); do
15653                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c || error "cannot create file"
15654         done
15655
15656         sync
15657         do_facet ost1 ofd_access_log_reader --list
15658         unlinkmany  "${file}-%d" 128
15659 }
15660 run_test 165c "full ofd access logs do not block IOs"
15661
15662 oal_peek_entry_count() {
15663         do_facet ost1 ofd_access_log_reader --list | awk '$1 == "_entry_count:" { print $2; }'
15664 }
15665
15666 oal_expect_entry_count() {
15667         local entry_count=$(oal_peek_entry_count)
15668         local expect="$1"
15669
15670         if ((entry_count == expect)); then
15671                 return 0
15672         fi
15673
15674         error_noexit "bad entry count, got ${entry_count}, expected ${expect}"
15675         do_facet ost1 ofd_access_log_reader --list >&2
15676         exit 1
15677 }
15678
15679 test_165d() {
15680         local trace="/tmp/${tfile}.trace"
15681         local file="${DIR}/${tdir}/${tfile}"
15682         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
15683         local entry_count
15684         test_mkdir "${DIR}/${tdir}"
15685
15686         setup_165
15687         lfs setstripe -c 1 -i 0 "${file}"
15688
15689         do_facet ost1 lctl set_param "${param}=rw"
15690         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15691         oal_expect_entry_count 1
15692
15693         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15694         oal_expect_entry_count 2
15695
15696         do_facet ost1 lctl set_param "${param}=r"
15697         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15698         oal_expect_entry_count 2
15699
15700         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15701         oal_expect_entry_count 3
15702
15703         do_facet ost1 lctl set_param "${param}=w"
15704         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15705         oal_expect_entry_count 4
15706
15707         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15708         oal_expect_entry_count 4
15709
15710         do_facet ost1 lctl set_param "${param}=0"
15711         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15712         oal_expect_entry_count 4
15713
15714         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15715         oal_expect_entry_count 4
15716 }
15717 run_test 165d "ofd_access_log mask works"
15718
15719 test_169() {
15720         # do directio so as not to populate the page cache
15721         log "creating a 10 Mb file"
15722         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
15723         log "starting reads"
15724         dd if=$DIR/$tfile of=/dev/null bs=4096 &
15725         log "truncating the file"
15726         $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
15727         log "killing dd"
15728         kill %+ || true # reads might have finished
15729         echo "wait until dd is finished"
15730         wait
15731         log "removing the temporary file"
15732         rm -rf $DIR/$tfile || error "tmp file removal failed"
15733 }
15734 run_test 169 "parallel read and truncate should not deadlock"
15735
15736 test_170() {
15737         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15738
15739         $LCTL clear     # bug 18514
15740         $LCTL debug_daemon start $TMP/${tfile}_log_good
15741         touch $DIR/$tfile
15742         $LCTL debug_daemon stop
15743         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
15744                 error "sed failed to read log_good"
15745
15746         $LCTL debug_daemon start $TMP/${tfile}_log_good
15747         rm -rf $DIR/$tfile
15748         $LCTL debug_daemon stop
15749
15750         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
15751                error "lctl df log_bad failed"
15752
15753         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
15754         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
15755
15756         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
15757         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
15758
15759         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
15760                 error "bad_line good_line1 good_line2 are empty"
15761
15762         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
15763         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
15764         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
15765
15766         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
15767         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
15768         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
15769
15770         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
15771                 error "bad_line_new good_line_new are empty"
15772
15773         local expected_good=$((good_line1 + good_line2*2))
15774
15775         rm -f $TMP/${tfile}*
15776         # LU-231, short malformed line may not be counted into bad lines
15777         if [ $bad_line -ne $bad_line_new ] &&
15778                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
15779                 error "expected $bad_line bad lines, but got $bad_line_new"
15780                 return 1
15781         fi
15782
15783         if [ $expected_good -ne $good_line_new ]; then
15784                 error "expected $expected_good good lines, but got $good_line_new"
15785                 return 2
15786         fi
15787         true
15788 }
15789 run_test 170 "test lctl df to handle corrupted log ====================="
15790
15791 test_171() { # bug20592
15792         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15793
15794         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
15795         $LCTL set_param fail_loc=0x50e
15796         $LCTL set_param fail_val=3000
15797         multiop_bg_pause $DIR/$tfile O_s || true
15798         local MULTIPID=$!
15799         kill -USR1 $MULTIPID
15800         # cause log dump
15801         sleep 3
15802         wait $MULTIPID
15803         if dmesg | grep "recursive fault"; then
15804                 error "caught a recursive fault"
15805         fi
15806         $LCTL set_param fail_loc=0
15807         true
15808 }
15809 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
15810
15811 # it would be good to share it with obdfilter-survey/iokit-libecho code
15812 setup_obdecho_osc () {
15813         local rc=0
15814         local ost_nid=$1
15815         local obdfilter_name=$2
15816         echo "Creating new osc for $obdfilter_name on $ost_nid"
15817         # make sure we can find loopback nid
15818         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
15819
15820         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
15821                            ${obdfilter_name}_osc_UUID || rc=2; }
15822         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
15823                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
15824         return $rc
15825 }
15826
15827 cleanup_obdecho_osc () {
15828         local obdfilter_name=$1
15829         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
15830         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
15831         return 0
15832 }
15833
15834 obdecho_test() {
15835         local OBD=$1
15836         local node=$2
15837         local pages=${3:-64}
15838         local rc=0
15839         local id
15840
15841         local count=10
15842         local obd_size=$(get_obd_size $node $OBD)
15843         local page_size=$(get_page_size $node)
15844         if [[ -n "$obd_size" ]]; then
15845                 local new_count=$((obd_size / (pages * page_size / 1024)))
15846                 [[ $new_count -ge $count ]] || count=$new_count
15847         fi
15848
15849         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
15850         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
15851                            rc=2; }
15852         if [ $rc -eq 0 ]; then
15853             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
15854             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
15855         fi
15856         echo "New object id is $id"
15857         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
15858                            rc=4; }
15859         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
15860                            "test_brw $count w v $pages $id" || rc=4; }
15861         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
15862                            rc=4; }
15863         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
15864                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
15865         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
15866                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
15867         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
15868         return $rc
15869 }
15870
15871 test_180a() {
15872         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15873
15874         if ! [ -d /sys/fs/lustre/echo_client ] &&
15875            ! module_loaded obdecho; then
15876                 load_module obdecho/obdecho &&
15877                         stack_trap "rmmod obdecho" EXIT ||
15878                         error "unable to load obdecho on client"
15879         fi
15880
15881         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
15882         local host=$($LCTL get_param -n osc.$osc.import |
15883                      awk '/current_connection:/ { print $2 }' )
15884         local target=$($LCTL get_param -n osc.$osc.import |
15885                        awk '/target:/ { print $2 }' )
15886         target=${target%_UUID}
15887
15888         if [ -n "$target" ]; then
15889                 setup_obdecho_osc $host $target &&
15890                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
15891                         { error "obdecho setup failed with $?"; return; }
15892
15893                 obdecho_test ${target}_osc client ||
15894                         error "obdecho_test failed on ${target}_osc"
15895         else
15896                 $LCTL get_param osc.$osc.import
15897                 error "there is no osc.$osc.import target"
15898         fi
15899 }
15900 run_test 180a "test obdecho on osc"
15901
15902 test_180b() {
15903         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15904         remote_ost_nodsh && skip "remote OST with nodsh"
15905
15906         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
15907                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
15908                 error "failed to load module obdecho"
15909
15910         local target=$(do_facet ost1 $LCTL dl |
15911                        awk '/obdfilter/ { print $4; exit; }')
15912
15913         if [ -n "$target" ]; then
15914                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
15915         else
15916                 do_facet ost1 $LCTL dl
15917                 error "there is no obdfilter target on ost1"
15918         fi
15919 }
15920 run_test 180b "test obdecho directly on obdfilter"
15921
15922 test_180c() { # LU-2598
15923         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15924         remote_ost_nodsh && skip "remote OST with nodsh"
15925         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
15926                 skip "Need MDS version at least 2.4.0"
15927
15928         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
15929                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
15930                 error "failed to load module obdecho"
15931
15932         local target=$(do_facet ost1 $LCTL dl |
15933                        awk '/obdfilter/ { print $4; exit; }')
15934
15935         if [ -n "$target" ]; then
15936                 local pages=16384 # 64MB bulk I/O RPC size
15937
15938                 obdecho_test "$target" ost1 "$pages" ||
15939                         error "obdecho_test with pages=$pages failed with $?"
15940         else
15941                 do_facet ost1 $LCTL dl
15942                 error "there is no obdfilter target on ost1"
15943         fi
15944 }
15945 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
15946
15947 test_181() { # bug 22177
15948         test_mkdir $DIR/$tdir
15949         # create enough files to index the directory
15950         createmany -o $DIR/$tdir/foobar 4000
15951         # print attributes for debug purpose
15952         lsattr -d .
15953         # open dir
15954         multiop_bg_pause $DIR/$tdir D_Sc || return 1
15955         MULTIPID=$!
15956         # remove the files & current working dir
15957         unlinkmany $DIR/$tdir/foobar 4000
15958         rmdir $DIR/$tdir
15959         kill -USR1 $MULTIPID
15960         wait $MULTIPID
15961         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
15962         return 0
15963 }
15964 run_test 181 "Test open-unlinked dir ========================"
15965
15966 test_182() {
15967         local fcount=1000
15968         local tcount=10
15969
15970         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
15971
15972         $LCTL set_param mdc.*.rpc_stats=clear
15973
15974         for (( i = 0; i < $tcount; i++ )) ; do
15975                 mkdir $DIR/$tdir/$i
15976         done
15977
15978         for (( i = 0; i < $tcount; i++ )) ; do
15979                 createmany -o $DIR/$tdir/$i/f- $fcount &
15980         done
15981         wait
15982
15983         for (( i = 0; i < $tcount; i++ )) ; do
15984                 unlinkmany $DIR/$tdir/$i/f- $fcount &
15985         done
15986         wait
15987
15988         $LCTL get_param mdc.*.rpc_stats
15989
15990         rm -rf $DIR/$tdir
15991 }
15992 run_test 182 "Test parallel modify metadata operations ================"
15993
15994 test_183() { # LU-2275
15995         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15996         remote_mds_nodsh && skip "remote MDS with nodsh"
15997         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
15998                 skip "Need MDS version at least 2.3.56"
15999
16000         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16001         echo aaa > $DIR/$tdir/$tfile
16002
16003 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
16004         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
16005
16006         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
16007         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
16008
16009         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
16010
16011         # Flush negative dentry cache
16012         touch $DIR/$tdir/$tfile
16013
16014         # We are not checking for any leaked references here, they'll
16015         # become evident next time we do cleanup with module unload.
16016         rm -rf $DIR/$tdir
16017 }
16018 run_test 183 "No crash or request leak in case of strange dispositions ========"
16019
16020 # test suite 184 is for LU-2016, LU-2017
16021 test_184a() {
16022         check_swap_layouts_support
16023
16024         dir0=$DIR/$tdir/$testnum
16025         test_mkdir -p -c1 $dir0
16026         ref1=/etc/passwd
16027         ref2=/etc/group
16028         file1=$dir0/f1
16029         file2=$dir0/f2
16030         $LFS setstripe -c1 $file1
16031         cp $ref1 $file1
16032         $LFS setstripe -c2 $file2
16033         cp $ref2 $file2
16034         gen1=$($LFS getstripe -g $file1)
16035         gen2=$($LFS getstripe -g $file2)
16036
16037         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
16038         gen=$($LFS getstripe -g $file1)
16039         [[ $gen1 != $gen ]] ||
16040                 "Layout generation on $file1 does not change"
16041         gen=$($LFS getstripe -g $file2)
16042         [[ $gen2 != $gen ]] ||
16043                 "Layout generation on $file2 does not change"
16044
16045         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
16046         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
16047
16048         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
16049 }
16050 run_test 184a "Basic layout swap"
16051
16052 test_184b() {
16053         check_swap_layouts_support
16054
16055         dir0=$DIR/$tdir/$testnum
16056         mkdir -p $dir0 || error "creating dir $dir0"
16057         file1=$dir0/f1
16058         file2=$dir0/f2
16059         file3=$dir0/f3
16060         dir1=$dir0/d1
16061         dir2=$dir0/d2
16062         mkdir $dir1 $dir2
16063         $LFS setstripe -c1 $file1
16064         $LFS setstripe -c2 $file2
16065         $LFS setstripe -c1 $file3
16066         chown $RUNAS_ID $file3
16067         gen1=$($LFS getstripe -g $file1)
16068         gen2=$($LFS getstripe -g $file2)
16069
16070         $LFS swap_layouts $dir1 $dir2 &&
16071                 error "swap of directories layouts should fail"
16072         $LFS swap_layouts $dir1 $file1 &&
16073                 error "swap of directory and file layouts should fail"
16074         $RUNAS $LFS swap_layouts $file1 $file2 &&
16075                 error "swap of file we cannot write should fail"
16076         $LFS swap_layouts $file1 $file3 &&
16077                 error "swap of file with different owner should fail"
16078         /bin/true # to clear error code
16079 }
16080 run_test 184b "Forbidden layout swap (will generate errors)"
16081
16082 test_184c() {
16083         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
16084         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
16085         check_swap_layouts_support
16086         check_swap_layout_no_dom $DIR
16087
16088         local dir0=$DIR/$tdir/$testnum
16089         mkdir -p $dir0 || error "creating dir $dir0"
16090
16091         local ref1=$dir0/ref1
16092         local ref2=$dir0/ref2
16093         local file1=$dir0/file1
16094         local file2=$dir0/file2
16095         # create a file large enough for the concurrent test
16096         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
16097         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
16098         echo "ref file size: ref1($(stat -c %s $ref1))," \
16099              "ref2($(stat -c %s $ref2))"
16100
16101         cp $ref2 $file2
16102         dd if=$ref1 of=$file1 bs=16k &
16103         local DD_PID=$!
16104
16105         # Make sure dd starts to copy file, but wait at most 5 seconds
16106         local loops=0
16107         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
16108
16109         $LFS swap_layouts $file1 $file2
16110         local rc=$?
16111         wait $DD_PID
16112         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
16113         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
16114
16115         # how many bytes copied before swapping layout
16116         local copied=$(stat -c %s $file2)
16117         local remaining=$(stat -c %s $ref1)
16118         remaining=$((remaining - copied))
16119         echo "Copied $copied bytes before swapping layout..."
16120
16121         cmp -n $copied $file1 $ref2 | grep differ &&
16122                 error "Content mismatch [0, $copied) of ref2 and file1"
16123         cmp -n $copied $file2 $ref1 ||
16124                 error "Content mismatch [0, $copied) of ref1 and file2"
16125         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
16126                 error "Content mismatch [$copied, EOF) of ref1 and file1"
16127
16128         # clean up
16129         rm -f $ref1 $ref2 $file1 $file2
16130 }
16131 run_test 184c "Concurrent write and layout swap"
16132
16133 test_184d() {
16134         check_swap_layouts_support
16135         check_swap_layout_no_dom $DIR
16136         [ -z "$(which getfattr 2>/dev/null)" ] &&
16137                 skip_env "no getfattr command"
16138
16139         local file1=$DIR/$tdir/$tfile-1
16140         local file2=$DIR/$tdir/$tfile-2
16141         local file3=$DIR/$tdir/$tfile-3
16142         local lovea1
16143         local lovea2
16144
16145         mkdir -p $DIR/$tdir
16146         touch $file1 || error "create $file1 failed"
16147         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
16148                 error "create $file2 failed"
16149         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
16150                 error "create $file3 failed"
16151         lovea1=$(get_layout_param $file1)
16152
16153         $LFS swap_layouts $file2 $file3 ||
16154                 error "swap $file2 $file3 layouts failed"
16155         $LFS swap_layouts $file1 $file2 ||
16156                 error "swap $file1 $file2 layouts failed"
16157
16158         lovea2=$(get_layout_param $file2)
16159         echo "$lovea1"
16160         echo "$lovea2"
16161         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
16162
16163         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
16164         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
16165 }
16166 run_test 184d "allow stripeless layouts swap"
16167
16168 test_184e() {
16169         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
16170                 skip "Need MDS version at least 2.6.94"
16171         check_swap_layouts_support
16172         check_swap_layout_no_dom $DIR
16173         [ -z "$(which getfattr 2>/dev/null)" ] &&
16174                 skip_env "no getfattr command"
16175
16176         local file1=$DIR/$tdir/$tfile-1
16177         local file2=$DIR/$tdir/$tfile-2
16178         local file3=$DIR/$tdir/$tfile-3
16179         local lovea
16180
16181         mkdir -p $DIR/$tdir
16182         touch $file1 || error "create $file1 failed"
16183         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
16184                 error "create $file2 failed"
16185         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
16186                 error "create $file3 failed"
16187
16188         $LFS swap_layouts $file1 $file2 ||
16189                 error "swap $file1 $file2 layouts failed"
16190
16191         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
16192         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
16193
16194         echo 123 > $file1 || error "Should be able to write into $file1"
16195
16196         $LFS swap_layouts $file1 $file3 ||
16197                 error "swap $file1 $file3 layouts failed"
16198
16199         echo 123 > $file1 || error "Should be able to write into $file1"
16200
16201         rm -rf $file1 $file2 $file3
16202 }
16203 run_test 184e "Recreate layout after stripeless layout swaps"
16204
16205 test_184f() {
16206         # Create a file with name longer than sizeof(struct stat) ==
16207         # 144 to see if we can get chars from the file name to appear
16208         # in the returned striping. Note that 'f' == 0x66.
16209         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
16210
16211         mkdir -p $DIR/$tdir
16212         mcreate $DIR/$tdir/$file
16213         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
16214                 error "IOC_MDC_GETFILEINFO returned garbage striping"
16215         fi
16216 }
16217 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
16218
16219 test_185() { # LU-2441
16220         # LU-3553 - no volatile file support in old servers
16221         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
16222                 skip "Need MDS version at least 2.3.60"
16223
16224         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16225         touch $DIR/$tdir/spoo
16226         local mtime1=$(stat -c "%Y" $DIR/$tdir)
16227         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
16228                 error "cannot create/write a volatile file"
16229         [ "$FILESET" == "" ] &&
16230         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
16231                 error "FID is still valid after close"
16232
16233         multiop_bg_pause $DIR/$tdir vVw4096_c
16234         local multi_pid=$!
16235
16236         local OLD_IFS=$IFS
16237         IFS=":"
16238         local fidv=($fid)
16239         IFS=$OLD_IFS
16240         # assume that the next FID for this client is sequential, since stdout
16241         # is unfortunately eaten by multiop_bg_pause
16242         local n=$((${fidv[1]} + 1))
16243         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
16244         if [ "$FILESET" == "" ]; then
16245                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
16246                         error "FID is missing before close"
16247         fi
16248         kill -USR1 $multi_pid
16249         # 1 second delay, so if mtime change we will see it
16250         sleep 1
16251         local mtime2=$(stat -c "%Y" $DIR/$tdir)
16252         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
16253 }
16254 run_test 185 "Volatile file support"
16255
16256 function create_check_volatile() {
16257         local idx=$1
16258         local tgt
16259
16260         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
16261         local PID=$!
16262         sleep 1
16263         local FID=$(cat /tmp/${tfile}.fid)
16264         [ "$FID" == "" ] && error "can't get FID for volatile"
16265         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
16266         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
16267         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
16268         kill -USR1 $PID
16269         wait
16270         sleep 1
16271         cancel_lru_locks mdc # flush opencache
16272         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
16273         return 0
16274 }
16275
16276 test_185a(){
16277         # LU-12516 - volatile creation via .lustre
16278         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
16279                 skip "Need MDS version at least 2.3.55"
16280
16281         create_check_volatile 0
16282         [ $MDSCOUNT -lt 2 ] && return 0
16283
16284         # DNE case
16285         create_check_volatile 1
16286
16287         return 0
16288 }
16289 run_test 185a "Volatile file creation in .lustre/fid/"
16290
16291 test_187a() {
16292         remote_mds_nodsh && skip "remote MDS with nodsh"
16293         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
16294                 skip "Need MDS version at least 2.3.0"
16295
16296         local dir0=$DIR/$tdir/$testnum
16297         mkdir -p $dir0 || error "creating dir $dir0"
16298
16299         local file=$dir0/file1
16300         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
16301         local dv1=$($LFS data_version $file)
16302         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
16303         local dv2=$($LFS data_version $file)
16304         [[ $dv1 != $dv2 ]] ||
16305                 error "data version did not change on write $dv1 == $dv2"
16306
16307         # clean up
16308         rm -f $file1
16309 }
16310 run_test 187a "Test data version change"
16311
16312 test_187b() {
16313         remote_mds_nodsh && skip "remote MDS with nodsh"
16314         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
16315                 skip "Need MDS version at least 2.3.0"
16316
16317         local dir0=$DIR/$tdir/$testnum
16318         mkdir -p $dir0 || error "creating dir $dir0"
16319
16320         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
16321         [[ ${DV[0]} != ${DV[1]} ]] ||
16322                 error "data version did not change on write"\
16323                       " ${DV[0]} == ${DV[1]}"
16324
16325         # clean up
16326         rm -f $file1
16327 }
16328 run_test 187b "Test data version change on volatile file"
16329
16330 test_200() {
16331         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16332         remote_mgs_nodsh && skip "remote MGS with nodsh"
16333         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16334
16335         local POOL=${POOL:-cea1}
16336         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
16337         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
16338         # Pool OST targets
16339         local first_ost=0
16340         local last_ost=$(($OSTCOUNT - 1))
16341         local ost_step=2
16342         local ost_list=$(seq $first_ost $ost_step $last_ost)
16343         local ost_range="$first_ost $last_ost $ost_step"
16344         local test_path=$POOL_ROOT/$POOL_DIR_NAME
16345         local file_dir=$POOL_ROOT/file_tst
16346         local subdir=$test_path/subdir
16347         local rc=0
16348
16349         while : ; do
16350                 # former test_200a test_200b
16351                 pool_add $POOL                          || { rc=$? ; break; }
16352                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
16353                 # former test_200c test_200d
16354                 mkdir -p $test_path
16355                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
16356                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
16357                 mkdir -p $subdir
16358                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
16359                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
16360                                                         || { rc=$? ; break; }
16361                 # former test_200e test_200f
16362                 local files=$((OSTCOUNT*3))
16363                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
16364                                                         || { rc=$? ; break; }
16365                 pool_create_files $POOL $file_dir $files "$ost_list" \
16366                                                         || { rc=$? ; break; }
16367                 # former test_200g test_200h
16368                 pool_lfs_df $POOL                       || { rc=$? ; break; }
16369                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
16370
16371                 # former test_201a test_201b test_201c
16372                 pool_remove_first_target $POOL          || { rc=$? ; break; }
16373
16374                 local f=$test_path/$tfile
16375                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
16376                 pool_remove $POOL $f                    || { rc=$? ; break; }
16377                 break
16378         done
16379
16380         destroy_test_pools
16381
16382         return $rc
16383 }
16384 run_test 200 "OST pools"
16385
16386 # usage: default_attr <count | size | offset>
16387 default_attr() {
16388         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
16389 }
16390
16391 # usage: check_default_stripe_attr
16392 check_default_stripe_attr() {
16393         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
16394         case $1 in
16395         --stripe-count|-c)
16396                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
16397         --stripe-size|-S)
16398                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
16399         --stripe-index|-i)
16400                 EXPECTED=-1;;
16401         *)
16402                 error "unknown getstripe attr '$1'"
16403         esac
16404
16405         [ $ACTUAL == $EXPECTED ] ||
16406                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
16407 }
16408
16409 test_204a() {
16410         test_mkdir $DIR/$tdir
16411         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
16412
16413         check_default_stripe_attr --stripe-count
16414         check_default_stripe_attr --stripe-size
16415         check_default_stripe_attr --stripe-index
16416 }
16417 run_test 204a "Print default stripe attributes"
16418
16419 test_204b() {
16420         test_mkdir $DIR/$tdir
16421         $LFS setstripe --stripe-count 1 $DIR/$tdir
16422
16423         check_default_stripe_attr --stripe-size
16424         check_default_stripe_attr --stripe-index
16425 }
16426 run_test 204b "Print default stripe size and offset"
16427
16428 test_204c() {
16429         test_mkdir $DIR/$tdir
16430         $LFS setstripe --stripe-size 65536 $DIR/$tdir
16431
16432         check_default_stripe_attr --stripe-count
16433         check_default_stripe_attr --stripe-index
16434 }
16435 run_test 204c "Print default stripe count and offset"
16436
16437 test_204d() {
16438         test_mkdir $DIR/$tdir
16439         $LFS setstripe --stripe-index 0 $DIR/$tdir
16440
16441         check_default_stripe_attr --stripe-count
16442         check_default_stripe_attr --stripe-size
16443 }
16444 run_test 204d "Print default stripe count and size"
16445
16446 test_204e() {
16447         test_mkdir $DIR/$tdir
16448         $LFS setstripe -d $DIR/$tdir
16449
16450         check_default_stripe_attr --stripe-count --raw
16451         check_default_stripe_attr --stripe-size --raw
16452         check_default_stripe_attr --stripe-index --raw
16453 }
16454 run_test 204e "Print raw stripe attributes"
16455
16456 test_204f() {
16457         test_mkdir $DIR/$tdir
16458         $LFS setstripe --stripe-count 1 $DIR/$tdir
16459
16460         check_default_stripe_attr --stripe-size --raw
16461         check_default_stripe_attr --stripe-index --raw
16462 }
16463 run_test 204f "Print raw stripe size and offset"
16464
16465 test_204g() {
16466         test_mkdir $DIR/$tdir
16467         $LFS setstripe --stripe-size 65536 $DIR/$tdir
16468
16469         check_default_stripe_attr --stripe-count --raw
16470         check_default_stripe_attr --stripe-index --raw
16471 }
16472 run_test 204g "Print raw stripe count and offset"
16473
16474 test_204h() {
16475         test_mkdir $DIR/$tdir
16476         $LFS setstripe --stripe-index 0 $DIR/$tdir
16477
16478         check_default_stripe_attr --stripe-count --raw
16479         check_default_stripe_attr --stripe-size --raw
16480 }
16481 run_test 204h "Print raw stripe count and size"
16482
16483 # Figure out which job scheduler is being used, if any,
16484 # or use a fake one
16485 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
16486         JOBENV=SLURM_JOB_ID
16487 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
16488         JOBENV=LSB_JOBID
16489 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
16490         JOBENV=PBS_JOBID
16491 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
16492         JOBENV=LOADL_STEP_ID
16493 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
16494         JOBENV=JOB_ID
16495 else
16496         $LCTL list_param jobid_name > /dev/null 2>&1
16497         if [ $? -eq 0 ]; then
16498                 JOBENV=nodelocal
16499         else
16500                 JOBENV=FAKE_JOBID
16501         fi
16502 fi
16503 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
16504
16505 verify_jobstats() {
16506         local cmd=($1)
16507         shift
16508         local facets="$@"
16509
16510 # we don't really need to clear the stats for this test to work, since each
16511 # command has a unique jobid, but it makes debugging easier if needed.
16512 #       for facet in $facets; do
16513 #               local dev=$(convert_facet2label $facet)
16514 #               # clear old jobstats
16515 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
16516 #       done
16517
16518         # use a new JobID for each test, or we might see an old one
16519         [ "$JOBENV" = "FAKE_JOBID" ] &&
16520                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
16521
16522         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
16523
16524         [ "$JOBENV" = "nodelocal" ] && {
16525                 FAKE_JOBID=id.$testnum.%e.$RANDOM
16526                 $LCTL set_param jobid_name=$FAKE_JOBID
16527                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
16528         }
16529
16530         log "Test: ${cmd[*]}"
16531         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
16532
16533         if [ $JOBENV = "FAKE_JOBID" ]; then
16534                 FAKE_JOBID=$JOBVAL ${cmd[*]}
16535         else
16536                 ${cmd[*]}
16537         fi
16538
16539         # all files are created on OST0000
16540         for facet in $facets; do
16541                 local stats="*.$(convert_facet2label $facet).job_stats"
16542
16543                 # strip out libtool wrappers for in-tree executables
16544                 if [ $(do_facet $facet lctl get_param $stats |
16545                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
16546                         do_facet $facet lctl get_param $stats
16547                         error "No jobstats for $JOBVAL found on $facet::$stats"
16548                 fi
16549         done
16550 }
16551
16552 jobstats_set() {
16553         local new_jobenv=$1
16554
16555         set_persistent_param_and_check client "jobid_var" \
16556                 "$FSNAME.sys.jobid_var" $new_jobenv
16557 }
16558
16559 test_205a() { # Job stats
16560         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16561         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
16562                 skip "Need MDS version with at least 2.7.1"
16563         remote_mgs_nodsh && skip "remote MGS with nodsh"
16564         remote_mds_nodsh && skip "remote MDS with nodsh"
16565         remote_ost_nodsh && skip "remote OST with nodsh"
16566         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
16567                 skip "Server doesn't support jobstats"
16568         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
16569
16570         local old_jobenv=$($LCTL get_param -n jobid_var)
16571         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
16572
16573         if [[ $PERM_CMD == *"set_param -P"* ]]; then
16574                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
16575         else
16576                 stack_trap "do_facet mgs $PERM_CMD \
16577                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
16578         fi
16579         changelog_register
16580
16581         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
16582                                 mdt.*.job_cleanup_interval | head -n 1)
16583         local new_interval=5
16584         do_facet $SINGLEMDS \
16585                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
16586         stack_trap "do_facet $SINGLEMDS \
16587                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
16588         local start=$SECONDS
16589
16590         local cmd
16591         # mkdir
16592         cmd="mkdir $DIR/$tdir"
16593         verify_jobstats "$cmd" "$SINGLEMDS"
16594         # rmdir
16595         cmd="rmdir $DIR/$tdir"
16596         verify_jobstats "$cmd" "$SINGLEMDS"
16597         # mkdir on secondary MDT
16598         if [ $MDSCOUNT -gt 1 ]; then
16599                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
16600                 verify_jobstats "$cmd" "mds2"
16601         fi
16602         # mknod
16603         cmd="mknod $DIR/$tfile c 1 3"
16604         verify_jobstats "$cmd" "$SINGLEMDS"
16605         # unlink
16606         cmd="rm -f $DIR/$tfile"
16607         verify_jobstats "$cmd" "$SINGLEMDS"
16608         # create all files on OST0000 so verify_jobstats can find OST stats
16609         # open & close
16610         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
16611         verify_jobstats "$cmd" "$SINGLEMDS"
16612         # setattr
16613         cmd="touch $DIR/$tfile"
16614         verify_jobstats "$cmd" "$SINGLEMDS ost1"
16615         # write
16616         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
16617         verify_jobstats "$cmd" "ost1"
16618         # read
16619         cancel_lru_locks osc
16620         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
16621         verify_jobstats "$cmd" "ost1"
16622         # truncate
16623         cmd="$TRUNCATE $DIR/$tfile 0"
16624         verify_jobstats "$cmd" "$SINGLEMDS ost1"
16625         # rename
16626         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
16627         verify_jobstats "$cmd" "$SINGLEMDS"
16628         # jobstats expiry - sleep until old stats should be expired
16629         local left=$((new_interval + 5 - (SECONDS - start)))
16630         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
16631                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
16632                         "0" $left
16633         cmd="mkdir $DIR/$tdir.expire"
16634         verify_jobstats "$cmd" "$SINGLEMDS"
16635         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
16636             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
16637
16638         # Ensure that jobid are present in changelog (if supported by MDS)
16639         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
16640                 changelog_dump | tail -10
16641                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
16642                 [ $jobids -eq 9 ] ||
16643                         error "Wrong changelog jobid count $jobids != 9"
16644
16645                 # LU-5862
16646                 JOBENV="disable"
16647                 jobstats_set $JOBENV
16648                 touch $DIR/$tfile
16649                 changelog_dump | grep $tfile
16650                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
16651                 [ $jobids -eq 0 ] ||
16652                         error "Unexpected jobids when jobid_var=$JOBENV"
16653         fi
16654
16655         # test '%j' access to environment variable - if supported
16656         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
16657                 JOBENV="JOBCOMPLEX"
16658                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
16659
16660                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
16661         fi
16662
16663         # test '%j' access to per-session jobid - if supported
16664         if lctl list_param jobid_this_session > /dev/null 2>&1
16665         then
16666                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
16667                 lctl set_param jobid_this_session=$USER
16668
16669                 JOBENV="JOBCOMPLEX"
16670                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
16671
16672                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
16673         fi
16674 }
16675 run_test 205a "Verify job stats"
16676
16677 # LU-13117, LU-13597
16678 test_205b() {
16679         job_stats="mdt.*.job_stats"
16680         $LCTL set_param $job_stats=clear
16681         # Setting jobid_var to USER might not be supported
16682         $LCTL set_param jobid_var=USER || true
16683         $LCTL set_param jobid_name="%e.%u"
16684         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
16685         do_facet $SINGLEMDS $LCTL get_param $job_stats |
16686                 grep "job_id:.*foolish" &&
16687                         error "Unexpected jobid found"
16688         do_facet $SINGLEMDS $LCTL get_param $job_stats |
16689                 grep "open:.*min.*max.*sum" ||
16690                         error "wrong job_stats format found"
16691 }
16692 run_test 205b "Verify job stats jobid and output format"
16693
16694 # LU-13733
16695 test_205c() {
16696         $LCTL set_param llite.*.stats=0
16697         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
16698         $LCTL get_param llite.*.stats
16699         $LCTL get_param llite.*.stats | grep \
16700                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
16701                         error "wrong client stats format found"
16702 }
16703 run_test 205c "Verify client stats format"
16704
16705 # LU-1480, LU-1773 and LU-1657
16706 test_206() {
16707         mkdir -p $DIR/$tdir
16708         $LFS setstripe -c -1 $DIR/$tdir
16709 #define OBD_FAIL_LOV_INIT 0x1403
16710         $LCTL set_param fail_loc=0xa0001403
16711         $LCTL set_param fail_val=1
16712         touch $DIR/$tdir/$tfile || true
16713 }
16714 run_test 206 "fail lov_init_raid0() doesn't lbug"
16715
16716 test_207a() {
16717         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
16718         local fsz=`stat -c %s $DIR/$tfile`
16719         cancel_lru_locks mdc
16720
16721         # do not return layout in getattr intent
16722 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
16723         $LCTL set_param fail_loc=0x170
16724         local sz=`stat -c %s $DIR/$tfile`
16725
16726         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
16727
16728         rm -rf $DIR/$tfile
16729 }
16730 run_test 207a "can refresh layout at glimpse"
16731
16732 test_207b() {
16733         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
16734         local cksum=`md5sum $DIR/$tfile`
16735         local fsz=`stat -c %s $DIR/$tfile`
16736         cancel_lru_locks mdc
16737         cancel_lru_locks osc
16738
16739         # do not return layout in getattr intent
16740 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
16741         $LCTL set_param fail_loc=0x171
16742
16743         # it will refresh layout after the file is opened but before read issues
16744         echo checksum is "$cksum"
16745         echo "$cksum" |md5sum -c --quiet || error "file differs"
16746
16747         rm -rf $DIR/$tfile
16748 }
16749 run_test 207b "can refresh layout at open"
16750
16751 test_208() {
16752         # FIXME: in this test suite, only RD lease is used. This is okay
16753         # for now as only exclusive open is supported. After generic lease
16754         # is done, this test suite should be revised. - Jinshan
16755
16756         remote_mds_nodsh && skip "remote MDS with nodsh"
16757         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
16758                 skip "Need MDS version at least 2.4.52"
16759
16760         echo "==== test 1: verify get lease work"
16761         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
16762
16763         echo "==== test 2: verify lease can be broken by upcoming open"
16764         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
16765         local PID=$!
16766         sleep 1
16767
16768         $MULTIOP $DIR/$tfile oO_RDONLY:c
16769         kill -USR1 $PID && wait $PID || error "break lease error"
16770
16771         echo "==== test 3: verify lease can't be granted if an open already exists"
16772         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
16773         local PID=$!
16774         sleep 1
16775
16776         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
16777         kill -USR1 $PID && wait $PID || error "open file error"
16778
16779         echo "==== test 4: lease can sustain over recovery"
16780         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
16781         PID=$!
16782         sleep 1
16783
16784         fail mds1
16785
16786         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
16787
16788         echo "==== test 5: lease broken can't be regained by replay"
16789         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
16790         PID=$!
16791         sleep 1
16792
16793         # open file to break lease and then recovery
16794         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
16795         fail mds1
16796
16797         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
16798
16799         rm -f $DIR/$tfile
16800 }
16801 run_test 208 "Exclusive open"
16802
16803 test_209() {
16804         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
16805                 skip_env "must have disp_stripe"
16806
16807         touch $DIR/$tfile
16808         sync; sleep 5; sync;
16809
16810         echo 3 > /proc/sys/vm/drop_caches
16811         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
16812                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
16813         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
16814
16815         # open/close 500 times
16816         for i in $(seq 500); do
16817                 cat $DIR/$tfile
16818         done
16819
16820         echo 3 > /proc/sys/vm/drop_caches
16821         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
16822                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
16823         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
16824
16825         echo "before: $req_before, after: $req_after"
16826         [ $((req_after - req_before)) -ge 300 ] &&
16827                 error "open/close requests are not freed"
16828         return 0
16829 }
16830 run_test 209 "read-only open/close requests should be freed promptly"
16831
16832 test_210() {
16833         local pid
16834
16835         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
16836         pid=$!
16837         sleep 1
16838
16839         $LFS getstripe $DIR/$tfile
16840         kill -USR1 $pid
16841         wait $pid || error "multiop failed"
16842
16843         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
16844         pid=$!
16845         sleep 1
16846
16847         $LFS getstripe $DIR/$tfile
16848         kill -USR1 $pid
16849         wait $pid || error "multiop failed"
16850 }
16851 run_test 210 "lfs getstripe does not break leases"
16852
16853 test_212() {
16854         size=`date +%s`
16855         size=$((size % 8192 + 1))
16856         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
16857         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
16858         rm -f $DIR/f212 $DIR/f212.xyz
16859 }
16860 run_test 212 "Sendfile test ============================================"
16861
16862 test_213() {
16863         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
16864         cancel_lru_locks osc
16865         lctl set_param fail_loc=0x8000040f
16866         # generate a read lock
16867         cat $DIR/$tfile > /dev/null
16868         # write to the file, it will try to cancel the above read lock.
16869         cat /etc/hosts >> $DIR/$tfile
16870 }
16871 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
16872
16873 test_214() { # for bug 20133
16874         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
16875         for (( i=0; i < 340; i++ )) ; do
16876                 touch $DIR/$tdir/d214c/a$i
16877         done
16878
16879         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
16880         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
16881         ls $DIR/d214c || error "ls $DIR/d214c failed"
16882         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
16883         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
16884 }
16885 run_test 214 "hash-indexed directory test - bug 20133"
16886
16887 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
16888 create_lnet_proc_files() {
16889         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
16890 }
16891
16892 # counterpart of create_lnet_proc_files
16893 remove_lnet_proc_files() {
16894         rm -f $TMP/lnet_$1.sys
16895 }
16896
16897 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
16898 # 3rd arg as regexp for body
16899 check_lnet_proc_stats() {
16900         local l=$(cat "$TMP/lnet_$1" |wc -l)
16901         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
16902
16903         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
16904 }
16905
16906 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
16907 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
16908 # optional and can be regexp for 2nd line (lnet.routes case)
16909 check_lnet_proc_entry() {
16910         local blp=2          # blp stands for 'position of 1st line of body'
16911         [ -z "$5" ] || blp=3 # lnet.routes case
16912
16913         local l=$(cat "$TMP/lnet_$1" |wc -l)
16914         # subtracting one from $blp because the body can be empty
16915         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
16916
16917         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
16918                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
16919
16920         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
16921                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
16922
16923         # bail out if any unexpected line happened
16924         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
16925         [ "$?" != 0 ] || error "$2 misformatted"
16926 }
16927
16928 test_215() { # for bugs 18102, 21079, 21517
16929         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16930
16931         local N='(0|[1-9][0-9]*)'       # non-negative numeric
16932         local P='[1-9][0-9]*'           # positive numeric
16933         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
16934         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
16935         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
16936         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
16937
16938         local L1 # regexp for 1st line
16939         local L2 # regexp for 2nd line (optional)
16940         local BR # regexp for the rest (body)
16941
16942         # lnet.stats should look as 11 space-separated non-negative numerics
16943         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
16944         create_lnet_proc_files "stats"
16945         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
16946         remove_lnet_proc_files "stats"
16947
16948         # lnet.routes should look like this:
16949         # Routing disabled/enabled
16950         # net hops priority state router
16951         # where net is a string like tcp0, hops > 0, priority >= 0,
16952         # state is up/down,
16953         # router is a string like 192.168.1.1@tcp2
16954         L1="^Routing (disabled|enabled)$"
16955         L2="^net +hops +priority +state +router$"
16956         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
16957         create_lnet_proc_files "routes"
16958         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
16959         remove_lnet_proc_files "routes"
16960
16961         # lnet.routers should look like this:
16962         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
16963         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
16964         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
16965         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
16966         L1="^ref +rtr_ref +alive +router$"
16967         BR="^$P +$P +(up|down) +$NID$"
16968         create_lnet_proc_files "routers"
16969         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
16970         remove_lnet_proc_files "routers"
16971
16972         # lnet.peers should look like this:
16973         # nid refs state last max rtr min tx min queue
16974         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
16975         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
16976         # numeric (0 or >0 or <0), queue >= 0.
16977         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
16978         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
16979         create_lnet_proc_files "peers"
16980         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
16981         remove_lnet_proc_files "peers"
16982
16983         # lnet.buffers  should look like this:
16984         # pages count credits min
16985         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
16986         L1="^pages +count +credits +min$"
16987         BR="^ +$N +$N +$I +$I$"
16988         create_lnet_proc_files "buffers"
16989         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
16990         remove_lnet_proc_files "buffers"
16991
16992         # lnet.nis should look like this:
16993         # nid status alive refs peer rtr max tx min
16994         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
16995         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
16996         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
16997         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
16998         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
16999         create_lnet_proc_files "nis"
17000         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
17001         remove_lnet_proc_files "nis"
17002
17003         # can we successfully write to lnet.stats?
17004         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
17005 }
17006 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
17007
17008 test_216() { # bug 20317
17009         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17010         remote_ost_nodsh && skip "remote OST with nodsh"
17011
17012         local node
17013         local facets=$(get_facets OST)
17014         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17015
17016         save_lustre_params client "osc.*.contention_seconds" > $p
17017         save_lustre_params $facets \
17018                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
17019         save_lustre_params $facets \
17020                 "ldlm.namespaces.filter-*.contended_locks" >> $p
17021         save_lustre_params $facets \
17022                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
17023         clear_stats osc.*.osc_stats
17024
17025         # agressive lockless i/o settings
17026         do_nodes $(comma_list $(osts_nodes)) \
17027                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
17028                         ldlm.namespaces.filter-*.contended_locks=0 \
17029                         ldlm.namespaces.filter-*.contention_seconds=60"
17030         lctl set_param -n osc.*.contention_seconds=60
17031
17032         $DIRECTIO write $DIR/$tfile 0 10 4096
17033         $CHECKSTAT -s 40960 $DIR/$tfile
17034
17035         # disable lockless i/o
17036         do_nodes $(comma_list $(osts_nodes)) \
17037                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
17038                         ldlm.namespaces.filter-*.contended_locks=32 \
17039                         ldlm.namespaces.filter-*.contention_seconds=0"
17040         lctl set_param -n osc.*.contention_seconds=0
17041         clear_stats osc.*.osc_stats
17042
17043         dd if=/dev/zero of=$DIR/$tfile count=0
17044         $CHECKSTAT -s 0 $DIR/$tfile
17045
17046         restore_lustre_params <$p
17047         rm -f $p
17048         rm $DIR/$tfile
17049 }
17050 run_test 216 "check lockless direct write updates file size and kms correctly"
17051
17052 test_217() { # bug 22430
17053         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17054
17055         local node
17056         local nid
17057
17058         for node in $(nodes_list); do
17059                 nid=$(host_nids_address $node $NETTYPE)
17060                 if [[ $nid = *-* ]] ; then
17061                         echo "lctl ping $(h2nettype $nid)"
17062                         lctl ping $(h2nettype $nid)
17063                 else
17064                         echo "skipping $node (no hyphen detected)"
17065                 fi
17066         done
17067 }
17068 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
17069
17070 test_218() {
17071        # do directio so as not to populate the page cache
17072        log "creating a 10 Mb file"
17073        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
17074        log "starting reads"
17075        dd if=$DIR/$tfile of=/dev/null bs=4096 &
17076        log "truncating the file"
17077        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
17078        log "killing dd"
17079        kill %+ || true # reads might have finished
17080        echo "wait until dd is finished"
17081        wait
17082        log "removing the temporary file"
17083        rm -rf $DIR/$tfile || error "tmp file removal failed"
17084 }
17085 run_test 218 "parallel read and truncate should not deadlock"
17086
17087 test_219() {
17088         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17089
17090         # write one partial page
17091         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
17092         # set no grant so vvp_io_commit_write will do sync write
17093         $LCTL set_param fail_loc=0x411
17094         # write a full page at the end of file
17095         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
17096
17097         $LCTL set_param fail_loc=0
17098         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
17099         $LCTL set_param fail_loc=0x411
17100         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
17101
17102         # LU-4201
17103         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
17104         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
17105 }
17106 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
17107
17108 test_220() { #LU-325
17109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17110         remote_ost_nodsh && skip "remote OST with nodsh"
17111         remote_mds_nodsh && skip "remote MDS with nodsh"
17112         remote_mgs_nodsh && skip "remote MGS with nodsh"
17113
17114         local OSTIDX=0
17115
17116         # create on MDT0000 so the last_id and next_id are correct
17117         mkdir $DIR/$tdir
17118         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
17119         OST=${OST%_UUID}
17120
17121         # on the mdt's osc
17122         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
17123         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
17124                         osp.$mdtosc_proc1.prealloc_last_id)
17125         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
17126                         osp.$mdtosc_proc1.prealloc_next_id)
17127
17128         $LFS df -i
17129
17130         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
17131         #define OBD_FAIL_OST_ENOINO              0x229
17132         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
17133         create_pool $FSNAME.$TESTNAME || return 1
17134         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
17135
17136         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
17137
17138         MDSOBJS=$((last_id - next_id))
17139         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
17140
17141         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
17142         echo "OST still has $count kbytes free"
17143
17144         echo "create $MDSOBJS files @next_id..."
17145         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
17146
17147         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
17148                         osp.$mdtosc_proc1.prealloc_last_id)
17149         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
17150                         osp.$mdtosc_proc1.prealloc_next_id)
17151
17152         echo "after creation, last_id=$last_id2, next_id=$next_id2"
17153         $LFS df -i
17154
17155         echo "cleanup..."
17156
17157         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
17158         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
17159
17160         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
17161                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
17162         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
17163                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
17164         echo "unlink $MDSOBJS files @$next_id..."
17165         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
17166 }
17167 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
17168
17169 test_221() {
17170         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17171
17172         dd if=`which date` of=$MOUNT/date oflag=sync
17173         chmod +x $MOUNT/date
17174
17175         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
17176         $LCTL set_param fail_loc=0x80001401
17177
17178         $MOUNT/date > /dev/null
17179         rm -f $MOUNT/date
17180 }
17181 run_test 221 "make sure fault and truncate race to not cause OOM"
17182
17183 test_222a () {
17184         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17185
17186         rm -rf $DIR/$tdir
17187         test_mkdir $DIR/$tdir
17188         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17189         createmany -o $DIR/$tdir/$tfile 10
17190         cancel_lru_locks mdc
17191         cancel_lru_locks osc
17192         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
17193         $LCTL set_param fail_loc=0x31a
17194         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
17195         $LCTL set_param fail_loc=0
17196         rm -r $DIR/$tdir
17197 }
17198 run_test 222a "AGL for ls should not trigger CLIO lock failure"
17199
17200 test_222b () {
17201         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17202
17203         rm -rf $DIR/$tdir
17204         test_mkdir $DIR/$tdir
17205         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17206         createmany -o $DIR/$tdir/$tfile 10
17207         cancel_lru_locks mdc
17208         cancel_lru_locks osc
17209         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
17210         $LCTL set_param fail_loc=0x31a
17211         rm -r $DIR/$tdir || error "AGL for rmdir failed"
17212         $LCTL set_param fail_loc=0
17213 }
17214 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
17215
17216 test_223 () {
17217         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17218
17219         rm -rf $DIR/$tdir
17220         test_mkdir $DIR/$tdir
17221         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17222         createmany -o $DIR/$tdir/$tfile 10
17223         cancel_lru_locks mdc
17224         cancel_lru_locks osc
17225         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
17226         $LCTL set_param fail_loc=0x31b
17227         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
17228         $LCTL set_param fail_loc=0
17229         rm -r $DIR/$tdir
17230 }
17231 run_test 223 "osc reenqueue if without AGL lock granted ======================="
17232
17233 test_224a() { # LU-1039, MRP-303
17234         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17235
17236         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
17237         $LCTL set_param fail_loc=0x508
17238         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
17239         $LCTL set_param fail_loc=0
17240         df $DIR
17241 }
17242 run_test 224a "Don't panic on bulk IO failure"
17243
17244 test_224b() { # LU-1039, MRP-303
17245         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17246
17247         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
17248         cancel_lru_locks osc
17249         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
17250         $LCTL set_param fail_loc=0x515
17251         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
17252         $LCTL set_param fail_loc=0
17253         df $DIR
17254 }
17255 run_test 224b "Don't panic on bulk IO failure"
17256
17257 test_224c() { # LU-6441
17258         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17259         remote_mds_nodsh && skip "remote MDS with nodsh"
17260
17261         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17262         save_writethrough $p
17263         set_cache writethrough on
17264
17265         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
17266         local at_max=$($LCTL get_param -n at_max)
17267         local timeout=$($LCTL get_param -n timeout)
17268         local test_at="at_max"
17269         local param_at="$FSNAME.sys.at_max"
17270         local test_timeout="timeout"
17271         local param_timeout="$FSNAME.sys.timeout"
17272
17273         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
17274
17275         set_persistent_param_and_check client "$test_at" "$param_at" 0
17276         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
17277
17278         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
17279         do_facet ost1 "$LCTL set_param fail_loc=0x520"
17280         $LFS setstripe -c 1 -i 0 $DIR/$tfile
17281         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
17282         sync
17283         do_facet ost1 "$LCTL set_param fail_loc=0"
17284
17285         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
17286         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
17287                 $timeout
17288
17289         $LCTL set_param -n $pages_per_rpc
17290         restore_lustre_params < $p
17291         rm -f $p
17292 }
17293 run_test 224c "Don't hang if one of md lost during large bulk RPC"
17294
17295 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
17296 test_225a () {
17297         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17298         if [ -z ${MDSSURVEY} ]; then
17299                 skip_env "mds-survey not found"
17300         fi
17301         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
17302                 skip "Need MDS version at least 2.2.51"
17303
17304         local mds=$(facet_host $SINGLEMDS)
17305         local target=$(do_nodes $mds 'lctl dl' |
17306                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17307
17308         local cmd1="file_count=1000 thrhi=4"
17309         local cmd2="dir_count=2 layer=mdd stripe_count=0"
17310         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17311         local cmd="$cmd1 $cmd2 $cmd3"
17312
17313         rm -f ${TMP}/mds_survey*
17314         echo + $cmd
17315         eval $cmd || error "mds-survey with zero-stripe failed"
17316         cat ${TMP}/mds_survey*
17317         rm -f ${TMP}/mds_survey*
17318 }
17319 run_test 225a "Metadata survey sanity with zero-stripe"
17320
17321 test_225b () {
17322         if [ -z ${MDSSURVEY} ]; then
17323                 skip_env "mds-survey not found"
17324         fi
17325         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
17326                 skip "Need MDS version at least 2.2.51"
17327         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17328         remote_mds_nodsh && skip "remote MDS with nodsh"
17329         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
17330                 skip_env "Need to mount OST to test"
17331         fi
17332
17333         local mds=$(facet_host $SINGLEMDS)
17334         local target=$(do_nodes $mds 'lctl dl' |
17335                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17336
17337         local cmd1="file_count=1000 thrhi=4"
17338         local cmd2="dir_count=2 layer=mdd stripe_count=1"
17339         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17340         local cmd="$cmd1 $cmd2 $cmd3"
17341
17342         rm -f ${TMP}/mds_survey*
17343         echo + $cmd
17344         eval $cmd || error "mds-survey with stripe_count failed"
17345         cat ${TMP}/mds_survey*
17346         rm -f ${TMP}/mds_survey*
17347 }
17348 run_test 225b "Metadata survey sanity with stripe_count = 1"
17349
17350 mcreate_path2fid () {
17351         local mode=$1
17352         local major=$2
17353         local minor=$3
17354         local name=$4
17355         local desc=$5
17356         local path=$DIR/$tdir/$name
17357         local fid
17358         local rc
17359         local fid_path
17360
17361         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
17362                 error "cannot create $desc"
17363
17364         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
17365         rc=$?
17366         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
17367
17368         fid_path=$($LFS fid2path $MOUNT $fid)
17369         rc=$?
17370         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
17371
17372         [ "$path" == "$fid_path" ] ||
17373                 error "fid2path returned $fid_path, expected $path"
17374
17375         echo "pass with $path and $fid"
17376 }
17377
17378 test_226a () {
17379         rm -rf $DIR/$tdir
17380         mkdir -p $DIR/$tdir
17381
17382         mcreate_path2fid 0010666 0 0 fifo "FIFO"
17383         mcreate_path2fid 0020666 1 3 null "character special file (null)"
17384         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
17385         mcreate_path2fid 0040666 0 0 dir "directory"
17386         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
17387         mcreate_path2fid 0100666 0 0 file "regular file"
17388         mcreate_path2fid 0120666 0 0 link "symbolic link"
17389         mcreate_path2fid 0140666 0 0 sock "socket"
17390 }
17391 run_test 226a "call path2fid and fid2path on files of all type"
17392
17393 test_226b () {
17394         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17395
17396         local MDTIDX=1
17397
17398         rm -rf $DIR/$tdir
17399         mkdir -p $DIR/$tdir
17400         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
17401                 error "create remote directory failed"
17402         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
17403         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
17404                                 "character special file (null)"
17405         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
17406                                 "character special file (no device)"
17407         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
17408         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
17409                                 "block special file (loop)"
17410         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
17411         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
17412         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
17413 }
17414 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
17415
17416 test_226c () {
17417         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17418         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
17419                 skip "Need MDS version at least 2.13.55"
17420
17421         local submnt=/mnt/submnt
17422         local srcfile=/etc/passwd
17423         local dstfile=$submnt/passwd
17424         local path
17425         local fid
17426
17427         rm -rf $DIR/$tdir
17428         rm -rf $submnt
17429         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
17430                 error "create remote directory failed"
17431         mkdir -p $submnt || error "create $submnt failed"
17432         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
17433                 error "mount $submnt failed"
17434         stack_trap "umount $submnt" EXIT
17435
17436         cp $srcfile $dstfile
17437         fid=$($LFS path2fid $dstfile)
17438         path=$($LFS fid2path $submnt "$fid")
17439         [ "$path" = "$dstfile" ] ||
17440                 error "fid2path $submnt $fid failed ($path != $dstfile)"
17441 }
17442 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
17443
17444 # LU-1299 Executing or running ldd on a truncated executable does not
17445 # cause an out-of-memory condition.
17446 test_227() {
17447         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17448         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
17449
17450         dd if=$(which date) of=$MOUNT/date bs=1k count=1
17451         chmod +x $MOUNT/date
17452
17453         $MOUNT/date > /dev/null
17454         ldd $MOUNT/date > /dev/null
17455         rm -f $MOUNT/date
17456 }
17457 run_test 227 "running truncated executable does not cause OOM"
17458
17459 # LU-1512 try to reuse idle OI blocks
17460 test_228a() {
17461         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17462         remote_mds_nodsh && skip "remote MDS with nodsh"
17463         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17464
17465         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17466         local myDIR=$DIR/$tdir
17467
17468         mkdir -p $myDIR
17469         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17470         $LCTL set_param fail_loc=0x80001002
17471         createmany -o $myDIR/t- 10000
17472         $LCTL set_param fail_loc=0
17473         # The guard is current the largest FID holder
17474         touch $myDIR/guard
17475         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17476                     tr -d '[')
17477         local IDX=$(($SEQ % 64))
17478
17479         do_facet $SINGLEMDS sync
17480         # Make sure journal flushed.
17481         sleep 6
17482         local blk1=$(do_facet $SINGLEMDS \
17483                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17484                      grep Blockcount | awk '{print $4}')
17485
17486         # Remove old files, some OI blocks will become idle.
17487         unlinkmany $myDIR/t- 10000
17488         # Create new files, idle OI blocks should be reused.
17489         createmany -o $myDIR/t- 2000
17490         do_facet $SINGLEMDS sync
17491         # Make sure journal flushed.
17492         sleep 6
17493         local blk2=$(do_facet $SINGLEMDS \
17494                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17495                      grep Blockcount | awk '{print $4}')
17496
17497         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17498 }
17499 run_test 228a "try to reuse idle OI blocks"
17500
17501 test_228b() {
17502         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17503         remote_mds_nodsh && skip "remote MDS with nodsh"
17504         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17505
17506         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17507         local myDIR=$DIR/$tdir
17508
17509         mkdir -p $myDIR
17510         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17511         $LCTL set_param fail_loc=0x80001002
17512         createmany -o $myDIR/t- 10000
17513         $LCTL set_param fail_loc=0
17514         # The guard is current the largest FID holder
17515         touch $myDIR/guard
17516         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17517                     tr -d '[')
17518         local IDX=$(($SEQ % 64))
17519
17520         do_facet $SINGLEMDS sync
17521         # Make sure journal flushed.
17522         sleep 6
17523         local blk1=$(do_facet $SINGLEMDS \
17524                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17525                      grep Blockcount | awk '{print $4}')
17526
17527         # Remove old files, some OI blocks will become idle.
17528         unlinkmany $myDIR/t- 10000
17529
17530         # stop the MDT
17531         stop $SINGLEMDS || error "Fail to stop MDT."
17532         # remount the MDT
17533         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
17534
17535         df $MOUNT || error "Fail to df."
17536         # Create new files, idle OI blocks should be reused.
17537         createmany -o $myDIR/t- 2000
17538         do_facet $SINGLEMDS sync
17539         # Make sure journal flushed.
17540         sleep 6
17541         local blk2=$(do_facet $SINGLEMDS \
17542                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17543                      grep Blockcount | awk '{print $4}')
17544
17545         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17546 }
17547 run_test 228b "idle OI blocks can be reused after MDT restart"
17548
17549 #LU-1881
17550 test_228c() {
17551         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17552         remote_mds_nodsh && skip "remote MDS with nodsh"
17553         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17554
17555         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17556         local myDIR=$DIR/$tdir
17557
17558         mkdir -p $myDIR
17559         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17560         $LCTL set_param fail_loc=0x80001002
17561         # 20000 files can guarantee there are index nodes in the OI file
17562         createmany -o $myDIR/t- 20000
17563         $LCTL set_param fail_loc=0
17564         # The guard is current the largest FID holder
17565         touch $myDIR/guard
17566         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17567                     tr -d '[')
17568         local IDX=$(($SEQ % 64))
17569
17570         do_facet $SINGLEMDS sync
17571         # Make sure journal flushed.
17572         sleep 6
17573         local blk1=$(do_facet $SINGLEMDS \
17574                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17575                      grep Blockcount | awk '{print $4}')
17576
17577         # Remove old files, some OI blocks will become idle.
17578         unlinkmany $myDIR/t- 20000
17579         rm -f $myDIR/guard
17580         # The OI file should become empty now
17581
17582         # Create new files, idle OI blocks should be reused.
17583         createmany -o $myDIR/t- 2000
17584         do_facet $SINGLEMDS sync
17585         # Make sure journal flushed.
17586         sleep 6
17587         local blk2=$(do_facet $SINGLEMDS \
17588                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17589                      grep Blockcount | awk '{print $4}')
17590
17591         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17592 }
17593 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
17594
17595 test_229() { # LU-2482, LU-3448
17596         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17597         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
17598         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
17599                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
17600
17601         rm -f $DIR/$tfile
17602
17603         # Create a file with a released layout and stripe count 2.
17604         $MULTIOP $DIR/$tfile H2c ||
17605                 error "failed to create file with released layout"
17606
17607         $LFS getstripe -v $DIR/$tfile
17608
17609         local pattern=$($LFS getstripe -L $DIR/$tfile)
17610         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
17611
17612         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
17613                 error "getstripe"
17614         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
17615         stat $DIR/$tfile || error "failed to stat released file"
17616
17617         chown $RUNAS_ID $DIR/$tfile ||
17618                 error "chown $RUNAS_ID $DIR/$tfile failed"
17619
17620         chgrp $RUNAS_ID $DIR/$tfile ||
17621                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
17622
17623         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
17624         rm $DIR/$tfile || error "failed to remove released file"
17625 }
17626 run_test 229 "getstripe/stat/rm/attr changes work on released files"
17627
17628 test_230a() {
17629         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17630         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17631         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17632                 skip "Need MDS version at least 2.11.52"
17633
17634         local MDTIDX=1
17635
17636         test_mkdir $DIR/$tdir
17637         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
17638         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
17639         [ $mdt_idx -ne 0 ] &&
17640                 error "create local directory on wrong MDT $mdt_idx"
17641
17642         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
17643                         error "create remote directory failed"
17644         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
17645         [ $mdt_idx -ne $MDTIDX ] &&
17646                 error "create remote directory on wrong MDT $mdt_idx"
17647
17648         createmany -o $DIR/$tdir/test_230/t- 10 ||
17649                 error "create files on remote directory failed"
17650         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
17651         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
17652         rm -r $DIR/$tdir || error "unlink remote directory failed"
17653 }
17654 run_test 230a "Create remote directory and files under the remote directory"
17655
17656 test_230b() {
17657         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17658         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17659         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17660                 skip "Need MDS version at least 2.11.52"
17661
17662         local MDTIDX=1
17663         local mdt_index
17664         local i
17665         local file
17666         local pid
17667         local stripe_count
17668         local migrate_dir=$DIR/$tdir/migrate_dir
17669         local other_dir=$DIR/$tdir/other_dir
17670
17671         test_mkdir $DIR/$tdir
17672         test_mkdir -i0 -c1 $migrate_dir
17673         test_mkdir -i0 -c1 $other_dir
17674         for ((i=0; i<10; i++)); do
17675                 mkdir -p $migrate_dir/dir_${i}
17676                 createmany -o $migrate_dir/dir_${i}/f 10 ||
17677                         error "create files under remote dir failed $i"
17678         done
17679
17680         cp /etc/passwd $migrate_dir/$tfile
17681         cp /etc/passwd $other_dir/$tfile
17682         chattr +SAD $migrate_dir
17683         chattr +SAD $migrate_dir/$tfile
17684
17685         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17686         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17687         local old_dir_mode=$(stat -c%f $migrate_dir)
17688         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
17689
17690         mkdir -p $migrate_dir/dir_default_stripe2
17691         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
17692         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
17693
17694         mkdir -p $other_dir
17695         ln $migrate_dir/$tfile $other_dir/luna
17696         ln $migrate_dir/$tfile $migrate_dir/sofia
17697         ln $other_dir/$tfile $migrate_dir/david
17698         ln -s $migrate_dir/$tfile $other_dir/zachary
17699         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
17700         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
17701
17702         local len
17703         local lnktgt
17704
17705         # inline symlink
17706         for len in 58 59 60; do
17707                 lnktgt=$(str_repeat 'l' $len)
17708                 touch $migrate_dir/$lnktgt
17709                 ln -s $lnktgt $migrate_dir/${len}char_ln
17710         done
17711
17712         # PATH_MAX
17713         for len in 4094 4095; do
17714                 lnktgt=$(str_repeat 'l' $len)
17715                 ln -s $lnktgt $migrate_dir/${len}char_ln
17716         done
17717
17718         # NAME_MAX
17719         for len in 254 255; do
17720                 touch $migrate_dir/$(str_repeat 'l' $len)
17721         done
17722
17723         $LFS migrate -m $MDTIDX $migrate_dir ||
17724                 error "fails on migrating remote dir to MDT1"
17725
17726         echo "migratate to MDT1, then checking.."
17727         for ((i = 0; i < 10; i++)); do
17728                 for file in $(find $migrate_dir/dir_${i}); do
17729                         mdt_index=$($LFS getstripe -m $file)
17730                         # broken symlink getstripe will fail
17731                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
17732                                 error "$file is not on MDT${MDTIDX}"
17733                 done
17734         done
17735
17736         # the multiple link file should still in MDT0
17737         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
17738         [ $mdt_index == 0 ] ||
17739                 error "$file is not on MDT${MDTIDX}"
17740
17741         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17742         [ "$old_dir_flag" = "$new_dir_flag" ] ||
17743                 error " expect $old_dir_flag get $new_dir_flag"
17744
17745         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17746         [ "$old_file_flag" = "$new_file_flag" ] ||
17747                 error " expect $old_file_flag get $new_file_flag"
17748
17749         local new_dir_mode=$(stat -c%f $migrate_dir)
17750         [ "$old_dir_mode" = "$new_dir_mode" ] ||
17751                 error "expect mode $old_dir_mode get $new_dir_mode"
17752
17753         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
17754         [ "$old_file_mode" = "$new_file_mode" ] ||
17755                 error "expect mode $old_file_mode get $new_file_mode"
17756
17757         diff /etc/passwd $migrate_dir/$tfile ||
17758                 error "$tfile different after migration"
17759
17760         diff /etc/passwd $other_dir/luna ||
17761                 error "luna different after migration"
17762
17763         diff /etc/passwd $migrate_dir/sofia ||
17764                 error "sofia different after migration"
17765
17766         diff /etc/passwd $migrate_dir/david ||
17767                 error "david different after migration"
17768
17769         diff /etc/passwd $other_dir/zachary ||
17770                 error "zachary different after migration"
17771
17772         diff /etc/passwd $migrate_dir/${tfile}_ln ||
17773                 error "${tfile}_ln different after migration"
17774
17775         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
17776                 error "${tfile}_ln_other different after migration"
17777
17778         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
17779         [ $stripe_count = 2 ] ||
17780                 error "dir strpe_count $d != 2 after migration."
17781
17782         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
17783         [ $stripe_count = 2 ] ||
17784                 error "file strpe_count $d != 2 after migration."
17785
17786         #migrate back to MDT0
17787         MDTIDX=0
17788
17789         $LFS migrate -m $MDTIDX $migrate_dir ||
17790                 error "fails on migrating remote dir to MDT0"
17791
17792         echo "migrate back to MDT0, checking.."
17793         for file in $(find $migrate_dir); do
17794                 mdt_index=$($LFS getstripe -m $file)
17795                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
17796                         error "$file is not on MDT${MDTIDX}"
17797         done
17798
17799         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17800         [ "$old_dir_flag" = "$new_dir_flag" ] ||
17801                 error " expect $old_dir_flag get $new_dir_flag"
17802
17803         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17804         [ "$old_file_flag" = "$new_file_flag" ] ||
17805                 error " expect $old_file_flag get $new_file_flag"
17806
17807         local new_dir_mode=$(stat -c%f $migrate_dir)
17808         [ "$old_dir_mode" = "$new_dir_mode" ] ||
17809                 error "expect mode $old_dir_mode get $new_dir_mode"
17810
17811         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
17812         [ "$old_file_mode" = "$new_file_mode" ] ||
17813                 error "expect mode $old_file_mode get $new_file_mode"
17814
17815         diff /etc/passwd ${migrate_dir}/$tfile ||
17816                 error "$tfile different after migration"
17817
17818         diff /etc/passwd ${other_dir}/luna ||
17819                 error "luna different after migration"
17820
17821         diff /etc/passwd ${migrate_dir}/sofia ||
17822                 error "sofia different after migration"
17823
17824         diff /etc/passwd ${other_dir}/zachary ||
17825                 error "zachary different after migration"
17826
17827         diff /etc/passwd $migrate_dir/${tfile}_ln ||
17828                 error "${tfile}_ln different after migration"
17829
17830         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
17831                 error "${tfile}_ln_other different after migration"
17832
17833         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
17834         [ $stripe_count = 2 ] ||
17835                 error "dir strpe_count $d != 2 after migration."
17836
17837         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
17838         [ $stripe_count = 2 ] ||
17839                 error "file strpe_count $d != 2 after migration."
17840
17841         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17842 }
17843 run_test 230b "migrate directory"
17844
17845 test_230c() {
17846         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17847         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17848         remote_mds_nodsh && skip "remote MDS with nodsh"
17849         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17850                 skip "Need MDS version at least 2.11.52"
17851
17852         local MDTIDX=1
17853         local total=3
17854         local mdt_index
17855         local file
17856         local migrate_dir=$DIR/$tdir/migrate_dir
17857
17858         #If migrating directory fails in the middle, all entries of
17859         #the directory is still accessiable.
17860         test_mkdir $DIR/$tdir
17861         test_mkdir -i0 -c1 $migrate_dir
17862         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
17863         stat $migrate_dir
17864         createmany -o $migrate_dir/f $total ||
17865                 error "create files under ${migrate_dir} failed"
17866
17867         # fail after migrating top dir, and this will fail only once, so the
17868         # first sub file migration will fail (currently f3), others succeed.
17869         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
17870         do_facet mds1 lctl set_param fail_loc=0x1801
17871         local t=$(ls $migrate_dir | wc -l)
17872         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
17873                 error "migrate should fail"
17874         local u=$(ls $migrate_dir | wc -l)
17875         [ "$u" == "$t" ] || error "$u != $t during migration"
17876
17877         # add new dir/file should succeed
17878         mkdir $migrate_dir/dir ||
17879                 error "mkdir failed under migrating directory"
17880         touch $migrate_dir/file ||
17881                 error "create file failed under migrating directory"
17882
17883         # add file with existing name should fail
17884         for file in $migrate_dir/f*; do
17885                 stat $file > /dev/null || error "stat $file failed"
17886                 $OPENFILE -f O_CREAT:O_EXCL $file &&
17887                         error "open(O_CREAT|O_EXCL) $file should fail"
17888                 $MULTIOP $file m && error "create $file should fail"
17889                 touch $DIR/$tdir/remote_dir/$tfile ||
17890                         error "touch $tfile failed"
17891                 ln $DIR/$tdir/remote_dir/$tfile $file &&
17892                         error "link $file should fail"
17893                 mdt_index=$($LFS getstripe -m $file)
17894                 if [ $mdt_index == 0 ]; then
17895                         # file failed to migrate is not allowed to rename to
17896                         mv $DIR/$tdir/remote_dir/$tfile $file &&
17897                                 error "rename to $file should fail"
17898                 else
17899                         mv $DIR/$tdir/remote_dir/$tfile $file ||
17900                                 error "rename to $file failed"
17901                 fi
17902                 echo hello >> $file || error "write $file failed"
17903         done
17904
17905         # resume migration with different options should fail
17906         $LFS migrate -m 0 $migrate_dir &&
17907                 error "migrate -m 0 $migrate_dir should fail"
17908
17909         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
17910                 error "migrate -c 2 $migrate_dir should fail"
17911
17912         # resume migration should succeed
17913         $LFS migrate -m $MDTIDX $migrate_dir ||
17914                 error "migrate $migrate_dir failed"
17915
17916         echo "Finish migration, then checking.."
17917         for file in $(find $migrate_dir); do
17918                 mdt_index=$($LFS getstripe -m $file)
17919                 [ $mdt_index == $MDTIDX ] ||
17920                         error "$file is not on MDT${MDTIDX}"
17921         done
17922
17923         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17924 }
17925 run_test 230c "check directory accessiblity if migration failed"
17926
17927 test_230d() {
17928         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17929         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17930         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17931                 skip "Need MDS version at least 2.11.52"
17932         # LU-11235
17933         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
17934
17935         local migrate_dir=$DIR/$tdir/migrate_dir
17936         local old_index
17937         local new_index
17938         local old_count
17939         local new_count
17940         local new_hash
17941         local mdt_index
17942         local i
17943         local j
17944
17945         old_index=$((RANDOM % MDSCOUNT))
17946         old_count=$((MDSCOUNT - old_index))
17947         new_index=$((RANDOM % MDSCOUNT))
17948         new_count=$((MDSCOUNT - new_index))
17949         new_hash=1 # for all_char
17950
17951         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
17952         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
17953
17954         test_mkdir $DIR/$tdir
17955         test_mkdir -i $old_index -c $old_count $migrate_dir
17956
17957         for ((i=0; i<100; i++)); do
17958                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
17959                 createmany -o $migrate_dir/dir_${i}/f 100 ||
17960                         error "create files under remote dir failed $i"
17961         done
17962
17963         echo -n "Migrate from MDT$old_index "
17964         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
17965         echo -n "to MDT$new_index"
17966         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
17967         echo
17968
17969         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
17970         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
17971                 error "migrate remote dir error"
17972
17973         echo "Finish migration, then checking.."
17974         for file in $(find $migrate_dir); do
17975                 mdt_index=$($LFS getstripe -m $file)
17976                 if [ $mdt_index -lt $new_index ] ||
17977                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
17978                         error "$file is on MDT$mdt_index"
17979                 fi
17980         done
17981
17982         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17983 }
17984 run_test 230d "check migrate big directory"
17985
17986 test_230e() {
17987         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17988         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17989         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17990                 skip "Need MDS version at least 2.11.52"
17991
17992         local i
17993         local j
17994         local a_fid
17995         local b_fid
17996
17997         mkdir -p $DIR/$tdir
17998         mkdir $DIR/$tdir/migrate_dir
17999         mkdir $DIR/$tdir/other_dir
18000         touch $DIR/$tdir/migrate_dir/a
18001         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
18002         ls $DIR/$tdir/other_dir
18003
18004         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18005                 error "migrate dir fails"
18006
18007         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
18008         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
18009
18010         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18011         [ $mdt_index == 0 ] || error "a is not on MDT0"
18012
18013         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
18014                 error "migrate dir fails"
18015
18016         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
18017         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
18018
18019         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18020         [ $mdt_index == 1 ] || error "a is not on MDT1"
18021
18022         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
18023         [ $mdt_index == 1 ] || error "b is not on MDT1"
18024
18025         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
18026         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
18027
18028         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
18029
18030         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18031 }
18032 run_test 230e "migrate mulitple local link files"
18033
18034 test_230f() {
18035         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18036         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18037         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18038                 skip "Need MDS version at least 2.11.52"
18039
18040         local a_fid
18041         local ln_fid
18042
18043         mkdir -p $DIR/$tdir
18044         mkdir $DIR/$tdir/migrate_dir
18045         $LFS mkdir -i1 $DIR/$tdir/other_dir
18046         touch $DIR/$tdir/migrate_dir/a
18047         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
18048         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
18049         ls $DIR/$tdir/other_dir
18050
18051         # a should be migrated to MDT1, since no other links on MDT0
18052         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18053                 error "#1 migrate dir fails"
18054         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
18055         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
18056         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18057         [ $mdt_index == 1 ] || error "a is not on MDT1"
18058
18059         # a should stay on MDT1, because it is a mulitple link file
18060         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
18061                 error "#2 migrate dir fails"
18062         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18063         [ $mdt_index == 1 ] || error "a is not on MDT1"
18064
18065         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18066                 error "#3 migrate dir fails"
18067
18068         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
18069         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
18070         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
18071
18072         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
18073         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
18074
18075         # a should be migrated to MDT0, since no other links on MDT1
18076         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
18077                 error "#4 migrate dir fails"
18078         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18079         [ $mdt_index == 0 ] || error "a is not on MDT0"
18080
18081         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18082 }
18083 run_test 230f "migrate mulitple remote link files"
18084
18085 test_230g() {
18086         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18087         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18088         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18089                 skip "Need MDS version at least 2.11.52"
18090
18091         mkdir -p $DIR/$tdir/migrate_dir
18092
18093         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
18094                 error "migrating dir to non-exist MDT succeeds"
18095         true
18096 }
18097 run_test 230g "migrate dir to non-exist MDT"
18098
18099 test_230h() {
18100         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18101         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18102         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18103                 skip "Need MDS version at least 2.11.52"
18104
18105         local mdt_index
18106
18107         mkdir -p $DIR/$tdir/migrate_dir
18108
18109         $LFS migrate -m1 $DIR &&
18110                 error "migrating mountpoint1 should fail"
18111
18112         $LFS migrate -m1 $DIR/$tdir/.. &&
18113                 error "migrating mountpoint2 should fail"
18114
18115         # same as mv
18116         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
18117                 error "migrating $tdir/migrate_dir/.. should fail"
18118
18119         true
18120 }
18121 run_test 230h "migrate .. and root"
18122
18123 test_230i() {
18124         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18125         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18126         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18127                 skip "Need MDS version at least 2.11.52"
18128
18129         mkdir -p $DIR/$tdir/migrate_dir
18130
18131         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
18132                 error "migration fails with a tailing slash"
18133
18134         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
18135                 error "migration fails with two tailing slashes"
18136 }
18137 run_test 230i "lfs migrate -m tolerates trailing slashes"
18138
18139 test_230j() {
18140         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18141         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
18142                 skip "Need MDS version at least 2.11.52"
18143
18144         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
18145         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
18146                 error "create $tfile failed"
18147         cat /etc/passwd > $DIR/$tdir/$tfile
18148
18149         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
18150
18151         cmp /etc/passwd $DIR/$tdir/$tfile ||
18152                 error "DoM file mismatch after migration"
18153 }
18154 run_test 230j "DoM file data not changed after dir migration"
18155
18156 test_230k() {
18157         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
18158         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18159                 skip "Need MDS version at least 2.11.56"
18160
18161         local total=20
18162         local files_on_starting_mdt=0
18163
18164         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
18165         $LFS getdirstripe $DIR/$tdir
18166         for i in $(seq $total); do
18167                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
18168                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
18169                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18170         done
18171
18172         echo "$files_on_starting_mdt files on MDT0"
18173
18174         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
18175         $LFS getdirstripe $DIR/$tdir
18176
18177         files_on_starting_mdt=0
18178         for i in $(seq $total); do
18179                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
18180                         error "file $tfile.$i mismatch after migration"
18181                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
18182                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18183         done
18184
18185         echo "$files_on_starting_mdt files on MDT1 after migration"
18186         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
18187
18188         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
18189         $LFS getdirstripe $DIR/$tdir
18190
18191         files_on_starting_mdt=0
18192         for i in $(seq $total); do
18193                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
18194                         error "file $tfile.$i mismatch after 2nd migration"
18195                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
18196                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18197         done
18198
18199         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
18200         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
18201
18202         true
18203 }
18204 run_test 230k "file data not changed after dir migration"
18205
18206 test_230l() {
18207         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18208         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18209                 skip "Need MDS version at least 2.11.56"
18210
18211         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
18212         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
18213                 error "create files under remote dir failed $i"
18214         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
18215 }
18216 run_test 230l "readdir between MDTs won't crash"
18217
18218 test_230m() {
18219         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18220         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18221                 skip "Need MDS version at least 2.11.56"
18222
18223         local MDTIDX=1
18224         local mig_dir=$DIR/$tdir/migrate_dir
18225         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
18226         local shortstr="b"
18227         local val
18228
18229         echo "Creating files and dirs with xattrs"
18230         test_mkdir $DIR/$tdir
18231         test_mkdir -i0 -c1 $mig_dir
18232         mkdir $mig_dir/dir
18233         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
18234                 error "cannot set xattr attr1 on dir"
18235         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
18236                 error "cannot set xattr attr2 on dir"
18237         touch $mig_dir/dir/f0
18238         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
18239                 error "cannot set xattr attr1 on file"
18240         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
18241                 error "cannot set xattr attr2 on file"
18242         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18243         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18244         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
18245         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18246         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
18247         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18248         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
18249         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18250         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
18251
18252         echo "Migrating to MDT1"
18253         $LFS migrate -m $MDTIDX $mig_dir ||
18254                 error "fails on migrating dir to MDT1"
18255
18256         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18257         echo "Checking xattrs"
18258         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18259         [ "$val" = $longstr ] ||
18260                 error "expecting xattr1 $longstr on dir, found $val"
18261         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18262         [ "$val" = $shortstr ] ||
18263                 error "expecting xattr2 $shortstr on dir, found $val"
18264         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18265         [ "$val" = $longstr ] ||
18266                 error "expecting xattr1 $longstr on file, found $val"
18267         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18268         [ "$val" = $shortstr ] ||
18269                 error "expecting xattr2 $shortstr on file, found $val"
18270 }
18271 run_test 230m "xattrs not changed after dir migration"
18272
18273 test_230n() {
18274         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18275         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
18276                 skip "Need MDS version at least 2.13.53"
18277
18278         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
18279         cat /etc/hosts > $DIR/$tdir/$tfile
18280         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
18281         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
18282
18283         cmp /etc/hosts $DIR/$tdir/$tfile ||
18284                 error "File data mismatch after migration"
18285 }
18286 run_test 230n "Dir migration with mirrored file"
18287
18288 test_230o() {
18289         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18290         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18291                 skip "Need MDS version at least 2.13.52"
18292
18293         local mdts=$(comma_list $(mdts_nodes))
18294         local timeout=100
18295
18296         local restripe_status
18297         local delta
18298         local i
18299         local j
18300
18301         [[ $(facet_fstype mds1) == zfs ]] && timeout=300
18302
18303         # in case "crush" hash type is not set
18304         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18305
18306         restripe_status=$(do_facet mds1 $LCTL get_param -n \
18307                            mdt.*MDT0000.enable_dir_restripe)
18308         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
18309         stack_trap "do_nodes $mdts $LCTL set_param \
18310                     mdt.*.enable_dir_restripe=$restripe_status"
18311
18312         mkdir $DIR/$tdir
18313         createmany -m $DIR/$tdir/f 100 ||
18314                 error "create files under remote dir failed $i"
18315         createmany -d $DIR/$tdir/d 100 ||
18316                 error "create dirs under remote dir failed $i"
18317
18318         for i in $(seq 2 $MDSCOUNT); do
18319                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
18320                 $LFS setdirstripe -c $i $DIR/$tdir ||
18321                         error "split -c $i $tdir failed"
18322                 wait_update $HOSTNAME \
18323                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
18324                         error "dir split not finished"
18325                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18326                         awk '/migrate/ {sum += $2} END { print sum }')
18327                 echo "$delta files migrated when dir split from $((i - 1)) to $i stripes"
18328                 # delta is around total_files/stripe_count
18329                 [ $delta -lt $((200 /(i - 1))) ] ||
18330                         error "$delta files migrated"
18331         done
18332 }
18333 run_test 230o "dir split"
18334
18335 test_230p() {
18336         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18337         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18338                 skip "Need MDS version at least 2.13.52"
18339
18340         local mdts=$(comma_list $(mdts_nodes))
18341         local timeout=100
18342
18343         local restripe_status
18344         local delta
18345         local i
18346         local j
18347
18348         [[ $(facet_fstype mds1) == zfs ]] && timeout=300
18349
18350         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18351
18352         restripe_status=$(do_facet mds1 $LCTL get_param -n \
18353                            mdt.*MDT0000.enable_dir_restripe)
18354         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
18355         stack_trap "do_nodes $mdts $LCTL set_param \
18356                     mdt.*.enable_dir_restripe=$restripe_status"
18357
18358         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
18359         createmany -m $DIR/$tdir/f 100 ||
18360                 error "create files under remote dir failed $i"
18361         createmany -d $DIR/$tdir/d 100 ||
18362                 error "create dirs under remote dir failed $i"
18363
18364         for i in $(seq $((MDSCOUNT - 1)) -1 1); do
18365                 local mdt_hash="crush"
18366
18367                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
18368                 $LFS setdirstripe -c $i $DIR/$tdir ||
18369                         error "split -c $i $tdir failed"
18370                 [ $i -eq 1 ] && mdt_hash="none"
18371                 wait_update $HOSTNAME \
18372                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
18373                         error "dir merge not finished"
18374                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18375                         awk '/migrate/ {sum += $2} END { print sum }')
18376                 echo "$delta files migrated when dir merge from $((i + 1)) to $i stripes"
18377                 # delta is around total_files/stripe_count
18378                 [ $delta -lt $((200 / i)) ] ||
18379                         error "$delta files migrated"
18380         done
18381 }
18382 run_test 230p "dir merge"
18383
18384 test_230q() {
18385         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18386         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18387                 skip "Need MDS version at least 2.13.52"
18388
18389         local mdts=$(comma_list $(mdts_nodes))
18390         local saved_threshold=$(do_facet mds1 \
18391                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
18392         local saved_delta=$(do_facet mds1 \
18393                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
18394         local threshold=100
18395         local delta=2
18396         local total=0
18397         local stripe_count=0
18398         local stripe_index
18399         local nr_files
18400
18401         stack_trap "do_nodes $mdts $LCTL set_param \
18402                     mdt.*.dir_split_count=$saved_threshold"
18403         stack_trap "do_nodes $mdts $LCTL set_param \
18404                     mdt.*.dir_split_delta=$saved_delta"
18405         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
18406         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
18407         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
18408         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
18409         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
18410         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18411
18412         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
18413         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
18414
18415         while [ $stripe_count -lt $MDSCOUNT ]; do
18416                 createmany -m $DIR/$tdir/f $total $((threshold * 3 / 2)) ||
18417                         error "create sub files failed"
18418                 stat $DIR/$tdir > /dev/null
18419                 total=$((total + threshold * 3 / 2))
18420                 stripe_count=$((stripe_count + delta))
18421                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
18422
18423                 wait_update $HOSTNAME \
18424                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
18425                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
18426
18427                 wait_update $HOSTNAME \
18428                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
18429                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
18430
18431                 nr_files=$($LFS getstripe -m $DIR/$tdir/* |
18432                            grep -w $stripe_index | wc -l)
18433                 echo "$nr_files files on MDT$stripe_index after split"
18434                 [ $nr_files -lt $((total / (stripe_count - 1))) ] ||
18435                         error "$nr_files files on MDT$stripe_index after split"
18436
18437                 nr_files=$(ls $DIR/$tdir | wc -w)
18438                 [ $nr_files -eq $total ] ||
18439                         error "total sub files $nr_files != $total"
18440         done
18441 }
18442 run_test 230q "dir auto split"
18443
18444 test_230r() {
18445         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18446         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
18447         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
18448                 skip "Need MDS version at least 2.13.54"
18449
18450         # maximum amount of local locks:
18451         # parent striped dir - 2 locks
18452         # new stripe in parent to migrate to - 1 lock
18453         # source and target - 2 locks
18454         # Total 5 locks for regular file
18455         mkdir -p $DIR/$tdir
18456         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
18457         touch $DIR/$tdir/dir1/eee
18458
18459         # create 4 hardlink for 4 more locks
18460         # Total: 9 locks > RS_MAX_LOCKS (8)
18461         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
18462         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
18463         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
18464         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
18465         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
18466         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
18467         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
18468         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
18469
18470         cancel_lru_locks mdc
18471
18472         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
18473                 error "migrate dir fails"
18474
18475         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18476 }
18477 run_test 230r "migrate with too many local locks"
18478
18479 test_231a()
18480 {
18481         # For simplicity this test assumes that max_pages_per_rpc
18482         # is the same across all OSCs
18483         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
18484         local bulk_size=$((max_pages * PAGE_SIZE))
18485         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
18486                                        head -n 1)
18487
18488         mkdir -p $DIR/$tdir
18489         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
18490                 error "failed to set stripe with -S ${brw_size}M option"
18491
18492         # clear the OSC stats
18493         $LCTL set_param osc.*.stats=0 &>/dev/null
18494         stop_writeback
18495
18496         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
18497         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
18498                 oflag=direct &>/dev/null || error "dd failed"
18499
18500         sync; sleep 1; sync # just to be safe
18501         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
18502         if [ x$nrpcs != "x1" ]; then
18503                 $LCTL get_param osc.*.stats
18504                 error "found $nrpcs ost_write RPCs, not 1 as expected"
18505         fi
18506
18507         start_writeback
18508         # Drop the OSC cache, otherwise we will read from it
18509         cancel_lru_locks osc
18510
18511         # clear the OSC stats
18512         $LCTL set_param osc.*.stats=0 &>/dev/null
18513
18514         # Client reads $bulk_size.
18515         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
18516                 iflag=direct &>/dev/null || error "dd failed"
18517
18518         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
18519         if [ x$nrpcs != "x1" ]; then
18520                 $LCTL get_param osc.*.stats
18521                 error "found $nrpcs ost_read RPCs, not 1 as expected"
18522         fi
18523 }
18524 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
18525
18526 test_231b() {
18527         mkdir -p $DIR/$tdir
18528         local i
18529         for i in {0..1023}; do
18530                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
18531                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
18532                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
18533         done
18534         sync
18535 }
18536 run_test 231b "must not assert on fully utilized OST request buffer"
18537
18538 test_232a() {
18539         mkdir -p $DIR/$tdir
18540         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
18541
18542         #define OBD_FAIL_LDLM_OST_LVB            0x31c
18543         do_facet ost1 $LCTL set_param fail_loc=0x31c
18544
18545         # ignore dd failure
18546         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
18547
18548         do_facet ost1 $LCTL set_param fail_loc=0
18549         umount_client $MOUNT || error "umount failed"
18550         mount_client $MOUNT || error "mount failed"
18551         stop ost1 || error "cannot stop ost1"
18552         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18553 }
18554 run_test 232a "failed lock should not block umount"
18555
18556 test_232b() {
18557         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
18558                 skip "Need MDS version at least 2.10.58"
18559
18560         mkdir -p $DIR/$tdir
18561         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
18562         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
18563         sync
18564         cancel_lru_locks osc
18565
18566         #define OBD_FAIL_LDLM_OST_LVB            0x31c
18567         do_facet ost1 $LCTL set_param fail_loc=0x31c
18568
18569         # ignore failure
18570         $LFS data_version $DIR/$tdir/$tfile || true
18571
18572         do_facet ost1 $LCTL set_param fail_loc=0
18573         umount_client $MOUNT || error "umount failed"
18574         mount_client $MOUNT || error "mount failed"
18575         stop ost1 || error "cannot stop ost1"
18576         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18577 }
18578 run_test 232b "failed data version lock should not block umount"
18579
18580 test_233a() {
18581         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
18582                 skip "Need MDS version at least 2.3.64"
18583         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
18584
18585         local fid=$($LFS path2fid $MOUNT)
18586
18587         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18588                 error "cannot access $MOUNT using its FID '$fid'"
18589 }
18590 run_test 233a "checking that OBF of the FS root succeeds"
18591
18592 test_233b() {
18593         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
18594                 skip "Need MDS version at least 2.5.90"
18595         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
18596
18597         local fid=$($LFS path2fid $MOUNT/.lustre)
18598
18599         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18600                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
18601
18602         fid=$($LFS path2fid $MOUNT/.lustre/fid)
18603         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18604                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
18605 }
18606 run_test 233b "checking that OBF of the FS .lustre succeeds"
18607
18608 test_234() {
18609         local p="$TMP/sanityN-$TESTNAME.parameters"
18610         save_lustre_params client "llite.*.xattr_cache" > $p
18611         lctl set_param llite.*.xattr_cache 1 ||
18612                 skip_env "xattr cache is not supported"
18613
18614         mkdir -p $DIR/$tdir || error "mkdir failed"
18615         touch $DIR/$tdir/$tfile || error "touch failed"
18616         # OBD_FAIL_LLITE_XATTR_ENOMEM
18617         $LCTL set_param fail_loc=0x1405
18618         getfattr -n user.attr $DIR/$tdir/$tfile &&
18619                 error "getfattr should have failed with ENOMEM"
18620         $LCTL set_param fail_loc=0x0
18621         rm -rf $DIR/$tdir
18622
18623         restore_lustre_params < $p
18624         rm -f $p
18625 }
18626 run_test 234 "xattr cache should not crash on ENOMEM"
18627
18628 test_235() {
18629         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
18630                 skip "Need MDS version at least 2.4.52"
18631
18632         flock_deadlock $DIR/$tfile
18633         local RC=$?
18634         case $RC in
18635                 0)
18636                 ;;
18637                 124) error "process hangs on a deadlock"
18638                 ;;
18639                 *) error "error executing flock_deadlock $DIR/$tfile"
18640                 ;;
18641         esac
18642 }
18643 run_test 235 "LU-1715: flock deadlock detection does not work properly"
18644
18645 #LU-2935
18646 test_236() {
18647         check_swap_layouts_support
18648
18649         local ref1=/etc/passwd
18650         local ref2=/etc/group
18651         local file1=$DIR/$tdir/f1
18652         local file2=$DIR/$tdir/f2
18653
18654         test_mkdir -c1 $DIR/$tdir
18655         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
18656         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
18657         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
18658         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
18659         local fd=$(free_fd)
18660         local cmd="exec $fd<>$file2"
18661         eval $cmd
18662         rm $file2
18663         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
18664                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
18665         cmd="exec $fd>&-"
18666         eval $cmd
18667         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
18668
18669         #cleanup
18670         rm -rf $DIR/$tdir
18671 }
18672 run_test 236 "Layout swap on open unlinked file"
18673
18674 # LU-4659 linkea consistency
18675 test_238() {
18676         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
18677                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
18678                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
18679                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
18680
18681         touch $DIR/$tfile
18682         ln $DIR/$tfile $DIR/$tfile.lnk
18683         touch $DIR/$tfile.new
18684         mv $DIR/$tfile.new $DIR/$tfile
18685         local fid1=$($LFS path2fid $DIR/$tfile)
18686         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
18687         local path1=$($LFS fid2path $FSNAME "$fid1")
18688         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
18689         local path2=$($LFS fid2path $FSNAME "$fid2")
18690         [ $tfile.lnk == $path2 ] ||
18691                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
18692         rm -f $DIR/$tfile*
18693 }
18694 run_test 238 "Verify linkea consistency"
18695
18696 test_239A() { # was test_239
18697         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
18698                 skip "Need MDS version at least 2.5.60"
18699
18700         local list=$(comma_list $(mdts_nodes))
18701
18702         mkdir -p $DIR/$tdir
18703         createmany -o $DIR/$tdir/f- 5000
18704         unlinkmany $DIR/$tdir/f- 5000
18705         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
18706                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
18707         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
18708                         osp.*MDT*.sync_in_flight" | calc_sum)
18709         [ "$changes" -eq 0 ] || error "$changes not synced"
18710 }
18711 run_test 239A "osp_sync test"
18712
18713 test_239a() { #LU-5297
18714         remote_mds_nodsh && skip "remote MDS with nodsh"
18715
18716         touch $DIR/$tfile
18717         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
18718         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
18719         chgrp $RUNAS_GID $DIR/$tfile
18720         wait_delete_completed
18721 }
18722 run_test 239a "process invalid osp sync record correctly"
18723
18724 test_239b() { #LU-5297
18725         remote_mds_nodsh && skip "remote MDS with nodsh"
18726
18727         touch $DIR/$tfile1
18728         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
18729         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
18730         chgrp $RUNAS_GID $DIR/$tfile1
18731         wait_delete_completed
18732         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
18733         touch $DIR/$tfile2
18734         chgrp $RUNAS_GID $DIR/$tfile2
18735         wait_delete_completed
18736 }
18737 run_test 239b "process osp sync record with ENOMEM error correctly"
18738
18739 test_240() {
18740         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18741         remote_mds_nodsh && skip "remote MDS with nodsh"
18742
18743         mkdir -p $DIR/$tdir
18744
18745         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
18746                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
18747         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
18748                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
18749
18750         umount_client $MOUNT || error "umount failed"
18751         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
18752         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
18753         mount_client $MOUNT || error "failed to mount client"
18754
18755         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
18756         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
18757 }
18758 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
18759
18760 test_241_bio() {
18761         local count=$1
18762         local bsize=$2
18763
18764         for LOOP in $(seq $count); do
18765                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
18766                 cancel_lru_locks $OSC || true
18767         done
18768 }
18769
18770 test_241_dio() {
18771         local count=$1
18772         local bsize=$2
18773
18774         for LOOP in $(seq $1); do
18775                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
18776                         2>/dev/null
18777         done
18778 }
18779
18780 test_241a() { # was test_241
18781         local bsize=$PAGE_SIZE
18782
18783         (( bsize < 40960 )) && bsize=40960
18784         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
18785         ls -la $DIR/$tfile
18786         cancel_lru_locks $OSC
18787         test_241_bio 1000 $bsize &
18788         PID=$!
18789         test_241_dio 1000 $bsize
18790         wait $PID
18791 }
18792 run_test 241a "bio vs dio"
18793
18794 test_241b() {
18795         local bsize=$PAGE_SIZE
18796
18797         (( bsize < 40960 )) && bsize=40960
18798         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
18799         ls -la $DIR/$tfile
18800         test_241_dio 1000 $bsize &
18801         PID=$!
18802         test_241_dio 1000 $bsize
18803         wait $PID
18804 }
18805 run_test 241b "dio vs dio"
18806
18807 test_242() {
18808         remote_mds_nodsh && skip "remote MDS with nodsh"
18809
18810         mkdir -p $DIR/$tdir
18811         touch $DIR/$tdir/$tfile
18812
18813         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
18814         do_facet mds1 lctl set_param fail_loc=0x105
18815         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
18816
18817         do_facet mds1 lctl set_param fail_loc=0
18818         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
18819 }
18820 run_test 242 "mdt_readpage failure should not cause directory unreadable"
18821
18822 test_243()
18823 {
18824         test_mkdir $DIR/$tdir
18825         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
18826 }
18827 run_test 243 "various group lock tests"
18828
18829 test_244a()
18830 {
18831         test_mkdir $DIR/$tdir
18832         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
18833         sendfile_grouplock $DIR/$tdir/$tfile || \
18834                 error "sendfile+grouplock failed"
18835         rm -rf $DIR/$tdir
18836 }
18837 run_test 244a "sendfile with group lock tests"
18838
18839 test_244b()
18840 {
18841         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
18842
18843         local threads=50
18844         local size=$((1024*1024))
18845
18846         test_mkdir $DIR/$tdir
18847         for i in $(seq 1 $threads); do
18848                 local file=$DIR/$tdir/file_$((i / 10))
18849                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
18850                 local pids[$i]=$!
18851         done
18852         for i in $(seq 1 $threads); do
18853                 wait ${pids[$i]}
18854         done
18855 }
18856 run_test 244b "multi-threaded write with group lock"
18857
18858 test_245() {
18859         local flagname="multi_mod_rpcs"
18860         local connect_data_name="max_mod_rpcs"
18861         local out
18862
18863         # check if multiple modify RPCs flag is set
18864         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
18865                 grep "connect_flags:")
18866         echo "$out"
18867
18868         echo "$out" | grep -qw $flagname
18869         if [ $? -ne 0 ]; then
18870                 echo "connect flag $flagname is not set"
18871                 return
18872         fi
18873
18874         # check if multiple modify RPCs data is set
18875         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
18876         echo "$out"
18877
18878         echo "$out" | grep -qw $connect_data_name ||
18879                 error "import should have connect data $connect_data_name"
18880 }
18881 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
18882
18883 cleanup_247() {
18884         local submount=$1
18885
18886         trap 0
18887         umount_client $submount
18888         rmdir $submount
18889 }
18890
18891 test_247a() {
18892         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
18893                 grep -q subtree ||
18894                 skip_env "Fileset feature is not supported"
18895
18896         local submount=${MOUNT}_$tdir
18897
18898         mkdir $MOUNT/$tdir
18899         mkdir -p $submount || error "mkdir $submount failed"
18900         FILESET="$FILESET/$tdir" mount_client $submount ||
18901                 error "mount $submount failed"
18902         trap "cleanup_247 $submount" EXIT
18903         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
18904         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
18905                 error "read $MOUNT/$tdir/$tfile failed"
18906         cleanup_247 $submount
18907 }
18908 run_test 247a "mount subdir as fileset"
18909
18910 test_247b() {
18911         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18912                 skip_env "Fileset feature is not supported"
18913
18914         local submount=${MOUNT}_$tdir
18915
18916         rm -rf $MOUNT/$tdir
18917         mkdir -p $submount || error "mkdir $submount failed"
18918         SKIP_FILESET=1
18919         FILESET="$FILESET/$tdir" mount_client $submount &&
18920                 error "mount $submount should fail"
18921         rmdir $submount
18922 }
18923 run_test 247b "mount subdir that dose not exist"
18924
18925 test_247c() {
18926         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18927                 skip_env "Fileset feature is not supported"
18928
18929         local submount=${MOUNT}_$tdir
18930
18931         mkdir -p $MOUNT/$tdir/dir1
18932         mkdir -p $submount || error "mkdir $submount failed"
18933         trap "cleanup_247 $submount" EXIT
18934         FILESET="$FILESET/$tdir" mount_client $submount ||
18935                 error "mount $submount failed"
18936         local fid=$($LFS path2fid $MOUNT/)
18937         $LFS fid2path $submount $fid && error "fid2path should fail"
18938         cleanup_247 $submount
18939 }
18940 run_test 247c "running fid2path outside subdirectory root"
18941
18942 test_247d() {
18943         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18944                 skip "Fileset feature is not supported"
18945
18946         local submount=${MOUNT}_$tdir
18947
18948         mkdir -p $MOUNT/$tdir/dir1
18949         mkdir -p $submount || error "mkdir $submount failed"
18950         FILESET="$FILESET/$tdir" mount_client $submount ||
18951                 error "mount $submount failed"
18952         trap "cleanup_247 $submount" EXIT
18953
18954         local td=$submount/dir1
18955         local fid=$($LFS path2fid $td)
18956         [ -z "$fid" ] && error "path2fid unable to get $td FID"
18957
18958         # check that we get the same pathname back
18959         local rootpath
18960         local found
18961         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
18962                 echo "$rootpath $fid"
18963                 found=$($LFS fid2path $rootpath "$fid")
18964                 [ -n "found" ] || error "fid2path should succeed"
18965                 [ "$found" == "$td" ] || error "fid2path $found != $td"
18966         done
18967         # check wrong root path format
18968         rootpath=$submount"_wrong"
18969         found=$($LFS fid2path $rootpath "$fid")
18970         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
18971
18972         cleanup_247 $submount
18973 }
18974 run_test 247d "running fid2path inside subdirectory root"
18975
18976 # LU-8037
18977 test_247e() {
18978         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
18979                 grep -q subtree ||
18980                 skip "Fileset feature is not supported"
18981
18982         local submount=${MOUNT}_$tdir
18983
18984         mkdir $MOUNT/$tdir
18985         mkdir -p $submount || error "mkdir $submount failed"
18986         FILESET="$FILESET/.." mount_client $submount &&
18987                 error "mount $submount should fail"
18988         rmdir $submount
18989 }
18990 run_test 247e "mount .. as fileset"
18991
18992 test_247f() {
18993         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18994         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
18995                 skip "Need at least version 2.13.52"
18996         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
18997                 grep -q subtree ||
18998                 skip "Fileset feature is not supported"
18999
19000         mkdir $DIR/$tdir || error "mkdir $tdir failed"
19001         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
19002                 error "mkdir remote failed"
19003         mkdir $DIR/$tdir/remote/subdir || error "mkdir remote/subdir failed"
19004         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped ||
19005                 error "mkdir striped failed"
19006         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
19007
19008         local submount=${MOUNT}_$tdir
19009
19010         mkdir -p $submount || error "mkdir $submount failed"
19011
19012         local dir
19013         local fileset=$FILESET
19014
19015         for dir in $tdir/remote $tdir/remote/subdir \
19016                    $tdir/striped $tdir/striped/subdir $tdir/striped/. ; do
19017                 FILESET="$fileset/$dir" mount_client $submount ||
19018                         error "mount $dir failed"
19019                 umount_client $submount
19020         done
19021 }
19022 run_test 247f "mount striped or remote directory as fileset"
19023
19024 test_248a() {
19025         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
19026         [ -z "$fast_read_sav" ] && skip "no fast read support"
19027
19028         # create a large file for fast read verification
19029         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
19030
19031         # make sure the file is created correctly
19032         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
19033                 { rm -f $DIR/$tfile; skip "file creation error"; }
19034
19035         echo "Test 1: verify that fast read is 4 times faster on cache read"
19036
19037         # small read with fast read enabled
19038         $LCTL set_param -n llite.*.fast_read=1
19039         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
19040                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19041                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19042         # small read with fast read disabled
19043         $LCTL set_param -n llite.*.fast_read=0
19044         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
19045                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19046                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19047
19048         # verify that fast read is 4 times faster for cache read
19049         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
19050                 error_not_in_vm "fast read was not 4 times faster: " \
19051                            "$t_fast vs $t_slow"
19052
19053         echo "Test 2: verify the performance between big and small read"
19054         $LCTL set_param -n llite.*.fast_read=1
19055
19056         # 1k non-cache read
19057         cancel_lru_locks osc
19058         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
19059                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19060                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19061
19062         # 1M non-cache read
19063         cancel_lru_locks osc
19064         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
19065                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19066                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19067
19068         # verify that big IO is not 4 times faster than small IO
19069         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
19070                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
19071
19072         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
19073         rm -f $DIR/$tfile
19074 }
19075 run_test 248a "fast read verification"
19076
19077 test_248b() {
19078         # Default short_io_bytes=16384, try both smaller and larger sizes.
19079         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
19080         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
19081         echo "bs=53248 count=113 normal buffered write"
19082         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
19083                 error "dd of initial data file failed"
19084         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
19085
19086         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
19087         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
19088                 error "dd with sync normal writes failed"
19089         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
19090
19091         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
19092         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
19093                 error "dd with sync small writes failed"
19094         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
19095
19096         cancel_lru_locks osc
19097
19098         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
19099         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
19100         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
19101         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
19102                 iflag=direct || error "dd with O_DIRECT small read failed"
19103         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
19104         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
19105                 error "compare $TMP/$tfile.1 failed"
19106
19107         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
19108         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
19109
19110         # just to see what the maximum tunable value is, and test parsing
19111         echo "test invalid parameter 2MB"
19112         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
19113                 error "too-large short_io_bytes allowed"
19114         echo "test maximum parameter 512KB"
19115         # if we can set a larger short_io_bytes, run test regardless of version
19116         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
19117                 # older clients may not allow setting it this large, that's OK
19118                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
19119                         skip "Need at least client version 2.13.50"
19120                 error "medium short_io_bytes failed"
19121         fi
19122         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
19123         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
19124
19125         echo "test large parameter 64KB"
19126         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
19127         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
19128
19129         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
19130         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
19131                 error "dd with sync large writes failed"
19132         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
19133
19134         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
19135         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
19136         num=$((113 * 4096 / PAGE_SIZE))
19137         echo "bs=$size count=$num oflag=direct large write $tfile.3"
19138         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
19139                 error "dd with O_DIRECT large writes failed"
19140         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
19141                 error "compare $DIR/$tfile.3 failed"
19142
19143         cancel_lru_locks osc
19144
19145         echo "bs=$size count=$num iflag=direct large read $tfile.2"
19146         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
19147                 error "dd with O_DIRECT large read failed"
19148         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
19149                 error "compare $TMP/$tfile.2 failed"
19150
19151         echo "bs=$size count=$num iflag=direct large read $tfile.3"
19152         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
19153                 error "dd with O_DIRECT large read failed"
19154         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
19155                 error "compare $TMP/$tfile.3 failed"
19156 }
19157 run_test 248b "test short_io read and write for both small and large sizes"
19158
19159 test_249() { # LU-7890
19160         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
19161                 skip "Need at least version 2.8.54"
19162
19163         rm -f $DIR/$tfile
19164         $LFS setstripe -c 1 $DIR/$tfile
19165         # Offset 2T == 4k * 512M
19166         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
19167                 error "dd to 2T offset failed"
19168 }
19169 run_test 249 "Write above 2T file size"
19170
19171 test_250() {
19172         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
19173          && skip "no 16TB file size limit on ZFS"
19174
19175         $LFS setstripe -c 1 $DIR/$tfile
19176         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
19177         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
19178         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
19179         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
19180                 conv=notrunc,fsync && error "append succeeded"
19181         return 0
19182 }
19183 run_test 250 "Write above 16T limit"
19184
19185 test_251() {
19186         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
19187
19188         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
19189         #Skip once - writing the first stripe will succeed
19190         $LCTL set_param fail_loc=0xa0001407 fail_val=1
19191         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
19192                 error "short write happened"
19193
19194         $LCTL set_param fail_loc=0xa0001407 fail_val=1
19195         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
19196                 error "short read happened"
19197
19198         rm -f $DIR/$tfile
19199 }
19200 run_test 251 "Handling short read and write correctly"
19201
19202 test_252() {
19203         remote_mds_nodsh && skip "remote MDS with nodsh"
19204         remote_ost_nodsh && skip "remote OST with nodsh"
19205         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
19206                 skip_env "ldiskfs only test"
19207         fi
19208
19209         local tgt
19210         local dev
19211         local out
19212         local uuid
19213         local num
19214         local gen
19215
19216         # check lr_reader on OST0000
19217         tgt=ost1
19218         dev=$(facet_device $tgt)
19219         out=$(do_facet $tgt $LR_READER $dev)
19220         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19221         echo "$out"
19222         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
19223         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
19224                 error "Invalid uuid returned by $LR_READER on target $tgt"
19225         echo -e "uuid returned by $LR_READER is '$uuid'\n"
19226
19227         # check lr_reader -c on MDT0000
19228         tgt=mds1
19229         dev=$(facet_device $tgt)
19230         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
19231                 skip "$LR_READER does not support additional options"
19232         fi
19233         out=$(do_facet $tgt $LR_READER -c $dev)
19234         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19235         echo "$out"
19236         num=$(echo "$out" | grep -c "mdtlov")
19237         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
19238                 error "Invalid number of mdtlov clients returned by $LR_READER"
19239         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
19240
19241         # check lr_reader -cr on MDT0000
19242         out=$(do_facet $tgt $LR_READER -cr $dev)
19243         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19244         echo "$out"
19245         echo "$out" | grep -q "^reply_data:$" ||
19246                 error "$LR_READER should have returned 'reply_data' section"
19247         num=$(echo "$out" | grep -c "client_generation")
19248         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
19249 }
19250 run_test 252 "check lr_reader tool"
19251
19252 test_253() {
19253         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19254         remote_mds_nodsh && skip "remote MDS with nodsh"
19255         remote_mgs_nodsh && skip "remote MGS with nodsh"
19256
19257         local ostidx=0
19258         local rc=0
19259         local ost_name=$(ostname_from_index $ostidx)
19260
19261         # on the mdt's osc
19262         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
19263         do_facet $SINGLEMDS $LCTL get_param -n \
19264                 osp.$mdtosc_proc1.reserved_mb_high ||
19265                 skip  "remote MDS does not support reserved_mb_high"
19266
19267         rm -rf $DIR/$tdir
19268         wait_mds_ost_sync
19269         wait_delete_completed
19270         mkdir $DIR/$tdir
19271
19272         pool_add $TESTNAME || error "Pool creation failed"
19273         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
19274
19275         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
19276                 error "Setstripe failed"
19277
19278         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
19279
19280         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
19281                     grep "watermarks")
19282         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
19283
19284         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
19285                         osp.$mdtosc_proc1.prealloc_status)
19286         echo "prealloc_status $oa_status"
19287
19288         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
19289                 error "File creation should fail"
19290
19291         #object allocation was stopped, but we still able to append files
19292         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
19293                 oflag=append || error "Append failed"
19294
19295         rm -f $DIR/$tdir/$tfile.0
19296
19297         # For this test, we want to delete the files we created to go out of
19298         # space but leave the watermark, so we remain nearly out of space
19299         ost_watermarks_enospc_delete_files $tfile $ostidx
19300
19301         wait_delete_completed
19302
19303         sleep_maxage
19304
19305         for i in $(seq 10 12); do
19306                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
19307                         2>/dev/null || error "File creation failed after rm"
19308         done
19309
19310         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
19311                         osp.$mdtosc_proc1.prealloc_status)
19312         echo "prealloc_status $oa_status"
19313
19314         if (( oa_status != 0 )); then
19315                 error "Object allocation still disable after rm"
19316         fi
19317 }
19318 run_test 253 "Check object allocation limit"
19319
19320 test_254() {
19321         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19322         remote_mds_nodsh && skip "remote MDS with nodsh"
19323         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
19324                 skip "MDS does not support changelog_size"
19325
19326         local cl_user
19327         local MDT0=$(facet_svc $SINGLEMDS)
19328
19329         changelog_register || error "changelog_register failed"
19330
19331         changelog_clear 0 || error "changelog_clear failed"
19332
19333         local size1=$(do_facet $SINGLEMDS \
19334                       $LCTL get_param -n mdd.$MDT0.changelog_size)
19335         echo "Changelog size $size1"
19336
19337         rm -rf $DIR/$tdir
19338         $LFS mkdir -i 0 $DIR/$tdir
19339         # change something
19340         mkdir -p $DIR/$tdir/pics/2008/zachy
19341         touch $DIR/$tdir/pics/2008/zachy/timestamp
19342         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
19343         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
19344         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
19345         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
19346         rm $DIR/$tdir/pics/desktop.jpg
19347
19348         local size2=$(do_facet $SINGLEMDS \
19349                       $LCTL get_param -n mdd.$MDT0.changelog_size)
19350         echo "Changelog size after work $size2"
19351
19352         (( $size2 > $size1 )) ||
19353                 error "new Changelog size=$size2 less than old size=$size1"
19354 }
19355 run_test 254 "Check changelog size"
19356
19357 ladvise_no_type()
19358 {
19359         local type=$1
19360         local file=$2
19361
19362         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
19363                 awk -F: '{print $2}' | grep $type > /dev/null
19364         if [ $? -ne 0 ]; then
19365                 return 0
19366         fi
19367         return 1
19368 }
19369
19370 ladvise_no_ioctl()
19371 {
19372         local file=$1
19373
19374         lfs ladvise -a willread $file > /dev/null 2>&1
19375         if [ $? -eq 0 ]; then
19376                 return 1
19377         fi
19378
19379         lfs ladvise -a willread $file 2>&1 |
19380                 grep "Inappropriate ioctl for device" > /dev/null
19381         if [ $? -eq 0 ]; then
19382                 return 0
19383         fi
19384         return 1
19385 }
19386
19387 percent() {
19388         bc <<<"scale=2; ($1 - $2) * 100 / $2"
19389 }
19390
19391 # run a random read IO workload
19392 # usage: random_read_iops <filename> <filesize> <iosize>
19393 random_read_iops() {
19394         local file=$1
19395         local fsize=$2
19396         local iosize=${3:-4096}
19397
19398         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
19399                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
19400 }
19401
19402 drop_file_oss_cache() {
19403         local file="$1"
19404         local nodes="$2"
19405
19406         $LFS ladvise -a dontneed $file 2>/dev/null ||
19407                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
19408 }
19409
19410 ladvise_willread_performance()
19411 {
19412         local repeat=10
19413         local average_origin=0
19414         local average_cache=0
19415         local average_ladvise=0
19416
19417         for ((i = 1; i <= $repeat; i++)); do
19418                 echo "Iter $i/$repeat: reading without willread hint"
19419                 cancel_lru_locks osc
19420                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
19421                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
19422                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
19423                 average_origin=$(bc <<<"$average_origin + $speed_origin")
19424
19425                 cancel_lru_locks osc
19426                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
19427                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
19428                 average_cache=$(bc <<<"$average_cache + $speed_cache")
19429
19430                 cancel_lru_locks osc
19431                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
19432                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
19433                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
19434                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
19435                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
19436         done
19437         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
19438         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
19439         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
19440
19441         speedup_cache=$(percent $average_cache $average_origin)
19442         speedup_ladvise=$(percent $average_ladvise $average_origin)
19443
19444         echo "Average uncached read: $average_origin"
19445         echo "Average speedup with OSS cached read: " \
19446                 "$average_cache = +$speedup_cache%"
19447         echo "Average speedup with ladvise willread: " \
19448                 "$average_ladvise = +$speedup_ladvise%"
19449
19450         local lowest_speedup=20
19451         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
19452                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
19453                         "got $average_cache%. Skipping ladvise willread check."
19454                 return 0
19455         fi
19456
19457         # the test won't work on ZFS until it supports 'ladvise dontneed', but
19458         # it is still good to run until then to exercise 'ladvise willread'
19459         ! $LFS ladvise -a dontneed $DIR/$tfile &&
19460                 [ "$ost1_FSTYPE" = "zfs" ] &&
19461                 echo "osd-zfs does not support dontneed or drop_caches" &&
19462                 return 0
19463
19464         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
19465         [[ ${average_ladvise%.*} > $lowest_speedup ]] ||
19466                 error_not_in_vm "Speedup with willread is less than " \
19467                         "$lowest_speedup%, got $average_ladvise%"
19468 }
19469
19470 test_255a() {
19471         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
19472                 skip "lustre < 2.8.54 does not support ladvise "
19473         remote_ost_nodsh && skip "remote OST with nodsh"
19474
19475         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
19476
19477         ladvise_no_type willread $DIR/$tfile &&
19478                 skip "willread ladvise is not supported"
19479
19480         ladvise_no_ioctl $DIR/$tfile &&
19481                 skip "ladvise ioctl is not supported"
19482
19483         local size_mb=100
19484         local size=$((size_mb * 1048576))
19485         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
19486                 error "dd to $DIR/$tfile failed"
19487
19488         lfs ladvise -a willread $DIR/$tfile ||
19489                 error "Ladvise failed with no range argument"
19490
19491         lfs ladvise -a willread -s 0 $DIR/$tfile ||
19492                 error "Ladvise failed with no -l or -e argument"
19493
19494         lfs ladvise -a willread -e 1 $DIR/$tfile ||
19495                 error "Ladvise failed with only -e argument"
19496
19497         lfs ladvise -a willread -l 1 $DIR/$tfile ||
19498                 error "Ladvise failed with only -l argument"
19499
19500         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
19501                 error "End offset should not be smaller than start offset"
19502
19503         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
19504                 error "End offset should not be equal to start offset"
19505
19506         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
19507                 error "Ladvise failed with overflowing -s argument"
19508
19509         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
19510                 error "Ladvise failed with overflowing -e argument"
19511
19512         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
19513                 error "Ladvise failed with overflowing -l argument"
19514
19515         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
19516                 error "Ladvise succeeded with conflicting -l and -e arguments"
19517
19518         echo "Synchronous ladvise should wait"
19519         local delay=4
19520 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
19521         do_nodes $(comma_list $(osts_nodes)) \
19522                 $LCTL set_param fail_val=$delay fail_loc=0x237
19523
19524         local start_ts=$SECONDS
19525         lfs ladvise -a willread $DIR/$tfile ||
19526                 error "Ladvise failed with no range argument"
19527         local end_ts=$SECONDS
19528         local inteval_ts=$((end_ts - start_ts))
19529
19530         if [ $inteval_ts -lt $(($delay - 1)) ]; then
19531                 error "Synchronous advice didn't wait reply"
19532         fi
19533
19534         echo "Asynchronous ladvise shouldn't wait"
19535         local start_ts=$SECONDS
19536         lfs ladvise -a willread -b $DIR/$tfile ||
19537                 error "Ladvise failed with no range argument"
19538         local end_ts=$SECONDS
19539         local inteval_ts=$((end_ts - start_ts))
19540
19541         if [ $inteval_ts -gt $(($delay / 2)) ]; then
19542                 error "Asynchronous advice blocked"
19543         fi
19544
19545         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
19546         ladvise_willread_performance
19547 }
19548 run_test 255a "check 'lfs ladvise -a willread'"
19549
19550 facet_meminfo() {
19551         local facet=$1
19552         local info=$2
19553
19554         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
19555 }
19556
19557 test_255b() {
19558         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
19559                 skip "lustre < 2.8.54 does not support ladvise "
19560         remote_ost_nodsh && skip "remote OST with nodsh"
19561
19562         lfs setstripe -c 1 -i 0 $DIR/$tfile
19563
19564         ladvise_no_type dontneed $DIR/$tfile &&
19565                 skip "dontneed ladvise is not supported"
19566
19567         ladvise_no_ioctl $DIR/$tfile &&
19568                 skip "ladvise ioctl is not supported"
19569
19570         ! $LFS ladvise -a dontneed $DIR/$tfile &&
19571                 [ "$ost1_FSTYPE" = "zfs" ] &&
19572                 skip "zfs-osd does not support 'ladvise dontneed'"
19573
19574         local size_mb=100
19575         local size=$((size_mb * 1048576))
19576         # In order to prevent disturbance of other processes, only check 3/4
19577         # of the memory usage
19578         local kibibytes=$((size_mb * 1024 * 3 / 4))
19579
19580         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
19581                 error "dd to $DIR/$tfile failed"
19582
19583         #force write to complete before dropping OST cache & checking memory
19584         sync
19585
19586         local total=$(facet_meminfo ost1 MemTotal)
19587         echo "Total memory: $total KiB"
19588
19589         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
19590         local before_read=$(facet_meminfo ost1 Cached)
19591         echo "Cache used before read: $before_read KiB"
19592
19593         lfs ladvise -a willread $DIR/$tfile ||
19594                 error "Ladvise willread failed"
19595         local after_read=$(facet_meminfo ost1 Cached)
19596         echo "Cache used after read: $after_read KiB"
19597
19598         lfs ladvise -a dontneed $DIR/$tfile ||
19599                 error "Ladvise dontneed again failed"
19600         local no_read=$(facet_meminfo ost1 Cached)
19601         echo "Cache used after dontneed ladvise: $no_read KiB"
19602
19603         if [ $total -lt $((before_read + kibibytes)) ]; then
19604                 echo "Memory is too small, abort checking"
19605                 return 0
19606         fi
19607
19608         if [ $((before_read + kibibytes)) -gt $after_read ]; then
19609                 error "Ladvise willread should use more memory" \
19610                         "than $kibibytes KiB"
19611         fi
19612
19613         if [ $((no_read + kibibytes)) -gt $after_read ]; then
19614                 error "Ladvise dontneed should release more memory" \
19615                         "than $kibibytes KiB"
19616         fi
19617 }
19618 run_test 255b "check 'lfs ladvise -a dontneed'"
19619
19620 test_255c() {
19621         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
19622                 skip "lustre < 2.10.50 does not support lockahead"
19623
19624         local count
19625         local new_count
19626         local difference
19627         local i
19628         local rc
19629
19630         test_mkdir -p $DIR/$tdir
19631         $LFS setstripe -i 0 -c 1 $DIR/$tdir
19632
19633         #test 10 returns only success/failure
19634         i=10
19635         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19636         rc=$?
19637         if [ $rc -eq 255 ]; then
19638                 error "Ladvise test${i} failed, ${rc}"
19639         fi
19640
19641         #test 11 counts lock enqueue requests, all others count new locks
19642         i=11
19643         count=$(do_facet ost1 \
19644                 $LCTL get_param -n ost.OSS.ost.stats)
19645         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
19646
19647         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19648         rc=$?
19649         if [ $rc -eq 255 ]; then
19650                 error "Ladvise test${i} failed, ${rc}"
19651         fi
19652
19653         new_count=$(do_facet ost1 \
19654                 $LCTL get_param -n ost.OSS.ost.stats)
19655         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
19656                    awk '{ print $2 }')
19657
19658         difference="$((new_count - count))"
19659         if [ $difference -ne $rc ]; then
19660                 error "Ladvise test${i}, bad enqueue count, returned " \
19661                       "${rc}, actual ${difference}"
19662         fi
19663
19664         for i in $(seq 12 21); do
19665                 # If we do not do this, we run the risk of having too many
19666                 # locks and starting lock cancellation while we are checking
19667                 # lock counts.
19668                 cancel_lru_locks osc
19669
19670                 count=$($LCTL get_param -n \
19671                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
19672
19673                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
19674                 rc=$?
19675                 if [ $rc -eq 255 ]; then
19676                         error "Ladvise test ${i} failed, ${rc}"
19677                 fi
19678
19679                 new_count=$($LCTL get_param -n \
19680                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
19681                 difference="$((new_count - count))"
19682
19683                 # Test 15 output is divided by 100 to map down to valid return
19684                 if [ $i -eq 15 ]; then
19685                         rc="$((rc * 100))"
19686                 fi
19687
19688                 if [ $difference -ne $rc ]; then
19689                         error "Ladvise test ${i}, bad lock count, returned " \
19690                               "${rc}, actual ${difference}"
19691                 fi
19692         done
19693
19694         #test 22 returns only success/failure
19695         i=22
19696         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19697         rc=$?
19698         if [ $rc -eq 255 ]; then
19699                 error "Ladvise test${i} failed, ${rc}"
19700         fi
19701 }
19702 run_test 255c "suite of ladvise lockahead tests"
19703
19704 test_256() {
19705         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19706         remote_mds_nodsh && skip "remote MDS with nodsh"
19707         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
19708         changelog_users $SINGLEMDS | grep "^cl" &&
19709                 skip "active changelog user"
19710
19711         local cl_user
19712         local cat_sl
19713         local mdt_dev
19714
19715         mdt_dev=$(mdsdevname 1)
19716         echo $mdt_dev
19717
19718         changelog_register || error "changelog_register failed"
19719
19720         rm -rf $DIR/$tdir
19721         mkdir -p $DIR/$tdir
19722
19723         changelog_clear 0 || error "changelog_clear failed"
19724
19725         # change something
19726         touch $DIR/$tdir/{1..10}
19727
19728         # stop the MDT
19729         stop $SINGLEMDS || error "Fail to stop MDT"
19730
19731         # remount the MDT
19732
19733         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
19734
19735         #after mount new plainllog is used
19736         touch $DIR/$tdir/{11..19}
19737         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
19738         stack_trap "rm -f $tmpfile"
19739         cat_sl=$(do_facet $SINGLEMDS "sync; \
19740                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
19741                  llog_reader $tmpfile | grep -c type=1064553b")
19742         do_facet $SINGLEMDS llog_reader $tmpfile
19743
19744         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
19745
19746         changelog_clear 0 || error "changelog_clear failed"
19747
19748         cat_sl=$(do_facet $SINGLEMDS "sync; \
19749                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
19750                  llog_reader $tmpfile | grep -c type=1064553b")
19751
19752         if (( cat_sl == 2 )); then
19753                 error "Empty plain llog was not deleted from changelog catalog"
19754         elif (( cat_sl != 1 )); then
19755                 error "Active plain llog shouldn't be deleted from catalog"
19756         fi
19757 }
19758 run_test 256 "Check llog delete for empty and not full state"
19759
19760 test_257() {
19761         remote_mds_nodsh && skip "remote MDS with nodsh"
19762         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
19763                 skip "Need MDS version at least 2.8.55"
19764
19765         test_mkdir $DIR/$tdir
19766
19767         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
19768                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
19769         stat $DIR/$tdir
19770
19771 #define OBD_FAIL_MDS_XATTR_REP                  0x161
19772         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
19773         local facet=mds$((mdtidx + 1))
19774         set_nodes_failloc $(facet_active_host $facet) 0x80000161
19775         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
19776
19777         stop $facet || error "stop MDS failed"
19778         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
19779                 error "start MDS fail"
19780         wait_recovery_complete $facet
19781 }
19782 run_test 257 "xattr locks are not lost"
19783
19784 # Verify we take the i_mutex when security requires it
19785 test_258a() {
19786 #define OBD_FAIL_IMUTEX_SEC 0x141c
19787         $LCTL set_param fail_loc=0x141c
19788         touch $DIR/$tfile
19789         chmod u+s $DIR/$tfile
19790         chmod a+rwx $DIR/$tfile
19791         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
19792         RC=$?
19793         if [ $RC -ne 0 ]; then
19794                 error "error, failed to take i_mutex, rc=$?"
19795         fi
19796         rm -f $DIR/$tfile
19797 }
19798 run_test 258a "verify i_mutex security behavior when suid attributes is set"
19799
19800 # Verify we do NOT take the i_mutex in the normal case
19801 test_258b() {
19802 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
19803         $LCTL set_param fail_loc=0x141d
19804         touch $DIR/$tfile
19805         chmod a+rwx $DIR
19806         chmod a+rw $DIR/$tfile
19807         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
19808         RC=$?
19809         if [ $RC -ne 0 ]; then
19810                 error "error, took i_mutex unnecessarily, rc=$?"
19811         fi
19812         rm -f $DIR/$tfile
19813
19814 }
19815 run_test 258b "verify i_mutex security behavior"
19816
19817 test_259() {
19818         local file=$DIR/$tfile
19819         local before
19820         local after
19821
19822         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
19823
19824         stack_trap "rm -f $file" EXIT
19825
19826         wait_delete_completed
19827         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19828         echo "before: $before"
19829
19830         $LFS setstripe -i 0 -c 1 $file
19831         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
19832         sync_all_data
19833         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19834         echo "after write: $after"
19835
19836 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
19837         do_facet ost1 $LCTL set_param fail_loc=0x2301
19838         $TRUNCATE $file 0
19839         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19840         echo "after truncate: $after"
19841
19842         stop ost1
19843         do_facet ost1 $LCTL set_param fail_loc=0
19844         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19845         sleep 2
19846         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19847         echo "after restart: $after"
19848         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
19849                 error "missing truncate?"
19850
19851         return 0
19852 }
19853 run_test 259 "crash at delayed truncate"
19854
19855 test_260() {
19856 #define OBD_FAIL_MDC_CLOSE               0x806
19857         $LCTL set_param fail_loc=0x80000806
19858         touch $DIR/$tfile
19859
19860 }
19861 run_test 260 "Check mdc_close fail"
19862
19863 ### Data-on-MDT sanity tests ###
19864 test_270a() {
19865         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19866                 skip "Need MDS version at least 2.10.55 for DoM"
19867
19868         # create DoM file
19869         local dom=$DIR/$tdir/dom_file
19870         local tmp=$DIR/$tdir/tmp_file
19871
19872         mkdir -p $DIR/$tdir
19873
19874         # basic checks for DoM component creation
19875         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
19876                 error "Can set MDT layout to non-first entry"
19877
19878         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
19879                 error "Can define multiple entries as MDT layout"
19880
19881         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
19882
19883         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
19884         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
19885         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
19886
19887         local mdtidx=$($LFS getstripe -m $dom)
19888         local mdtname=MDT$(printf %04x $mdtidx)
19889         local facet=mds$((mdtidx + 1))
19890         local space_check=1
19891
19892         # Skip free space checks with ZFS
19893         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
19894
19895         # write
19896         sync
19897         local size_tmp=$((65536 * 3))
19898         local mdtfree1=$(do_facet $facet \
19899                          lctl get_param -n osd*.*$mdtname.kbytesfree)
19900
19901         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
19902         # check also direct IO along write
19903         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
19904         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
19905         sync
19906         cmp $tmp $dom || error "file data is different"
19907         [ $(stat -c%s $dom) == $size_tmp ] ||
19908                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
19909         if [ $space_check == 1 ]; then
19910                 local mdtfree2=$(do_facet $facet \
19911                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
19912
19913                 # increase in usage from by $size_tmp
19914                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
19915                         error "MDT free space wrong after write: " \
19916                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
19917         fi
19918
19919         # truncate
19920         local size_dom=10000
19921
19922         $TRUNCATE $dom $size_dom
19923         [ $(stat -c%s $dom) == $size_dom ] ||
19924                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
19925         if [ $space_check == 1 ]; then
19926                 mdtfree1=$(do_facet $facet \
19927                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19928                 # decrease in usage from $size_tmp to new $size_dom
19929                 [ $(($mdtfree1 - $mdtfree2)) -ge \
19930                   $(((size_tmp - size_dom) / 1024)) ] ||
19931                         error "MDT free space is wrong after truncate: " \
19932                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
19933         fi
19934
19935         # append
19936         cat $tmp >> $dom
19937         sync
19938         size_dom=$((size_dom + size_tmp))
19939         [ $(stat -c%s $dom) == $size_dom ] ||
19940                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
19941         if [ $space_check == 1 ]; then
19942                 mdtfree2=$(do_facet $facet \
19943                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19944                 # increase in usage by $size_tmp from previous
19945                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
19946                         error "MDT free space is wrong after append: " \
19947                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
19948         fi
19949
19950         # delete
19951         rm $dom
19952         if [ $space_check == 1 ]; then
19953                 mdtfree1=$(do_facet $facet \
19954                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19955                 # decrease in usage by $size_dom from previous
19956                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
19957                         error "MDT free space is wrong after removal: " \
19958                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
19959         fi
19960
19961         # combined striping
19962         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
19963                 error "Can't create DoM + OST striping"
19964
19965         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
19966         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
19967         # check also direct IO along write
19968         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
19969         sync
19970         cmp $tmp $dom || error "file data is different"
19971         [ $(stat -c%s $dom) == $size_tmp ] ||
19972                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
19973         rm $dom $tmp
19974
19975         return 0
19976 }
19977 run_test 270a "DoM: basic functionality tests"
19978
19979 test_270b() {
19980         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19981                 skip "Need MDS version at least 2.10.55"
19982
19983         local dom=$DIR/$tdir/dom_file
19984         local max_size=1048576
19985
19986         mkdir -p $DIR/$tdir
19987         $LFS setstripe -E $max_size -L mdt $dom
19988
19989         # truncate over the limit
19990         $TRUNCATE $dom $(($max_size + 1)) &&
19991                 error "successful truncate over the maximum size"
19992         # write over the limit
19993         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
19994                 error "successful write over the maximum size"
19995         # append over the limit
19996         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
19997         echo "12345" >> $dom && error "successful append over the maximum size"
19998         rm $dom
19999
20000         return 0
20001 }
20002 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
20003
20004 test_270c() {
20005         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20006                 skip "Need MDS version at least 2.10.55"
20007
20008         mkdir -p $DIR/$tdir
20009         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20010
20011         # check files inherit DoM EA
20012         touch $DIR/$tdir/first
20013         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
20014                 error "bad pattern"
20015         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
20016                 error "bad stripe count"
20017         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
20018                 error "bad stripe size"
20019
20020         # check directory inherits DoM EA and uses it as default
20021         mkdir $DIR/$tdir/subdir
20022         touch $DIR/$tdir/subdir/second
20023         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
20024                 error "bad pattern in sub-directory"
20025         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
20026                 error "bad stripe count in sub-directory"
20027         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
20028                 error "bad stripe size in sub-directory"
20029         return 0
20030 }
20031 run_test 270c "DoM: DoM EA inheritance tests"
20032
20033 test_270d() {
20034         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20035                 skip "Need MDS version at least 2.10.55"
20036
20037         mkdir -p $DIR/$tdir
20038         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20039
20040         # inherit default DoM striping
20041         mkdir $DIR/$tdir/subdir
20042         touch $DIR/$tdir/subdir/f1
20043
20044         # change default directory striping
20045         $LFS setstripe -c 1 $DIR/$tdir/subdir
20046         touch $DIR/$tdir/subdir/f2
20047         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
20048                 error "wrong default striping in file 2"
20049         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
20050                 error "bad pattern in file 2"
20051         return 0
20052 }
20053 run_test 270d "DoM: change striping from DoM to RAID0"
20054
20055 test_270e() {
20056         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20057                 skip "Need MDS version at least 2.10.55"
20058
20059         mkdir -p $DIR/$tdir/dom
20060         mkdir -p $DIR/$tdir/norm
20061         DOMFILES=20
20062         NORMFILES=10
20063         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
20064         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
20065
20066         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
20067         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
20068
20069         # find DoM files by layout
20070         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
20071         [ $NUM -eq  $DOMFILES ] ||
20072                 error "lfs find -L: found $NUM, expected $DOMFILES"
20073         echo "Test 1: lfs find 20 DOM files by layout: OK"
20074
20075         # there should be 1 dir with default DOM striping
20076         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
20077         [ $NUM -eq  1 ] ||
20078                 error "lfs find -L: found $NUM, expected 1 dir"
20079         echo "Test 2: lfs find 1 DOM dir by layout: OK"
20080
20081         # find DoM files by stripe size
20082         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
20083         [ $NUM -eq  $DOMFILES ] ||
20084                 error "lfs find -S: found $NUM, expected $DOMFILES"
20085         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
20086
20087         # find files by stripe offset except DoM files
20088         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
20089         [ $NUM -eq  $NORMFILES ] ||
20090                 error "lfs find -i: found $NUM, expected $NORMFILES"
20091         echo "Test 5: lfs find no DOM files by stripe index: OK"
20092         return 0
20093 }
20094 run_test 270e "DoM: lfs find with DoM files test"
20095
20096 test_270f() {
20097         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20098                 skip "Need MDS version at least 2.10.55"
20099
20100         local mdtname=${FSNAME}-MDT0000-mdtlov
20101         local dom=$DIR/$tdir/dom_file
20102         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
20103                                                 lod.$mdtname.dom_stripesize)
20104         local dom_limit=131072
20105
20106         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
20107         local dom_current=$(do_facet mds1 $LCTL get_param -n \
20108                                                 lod.$mdtname.dom_stripesize)
20109         [ ${dom_limit} -eq ${dom_current} ] ||
20110                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
20111
20112         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20113         $LFS setstripe -d $DIR/$tdir
20114         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
20115                 error "Can't set directory default striping"
20116
20117         # exceed maximum stripe size
20118         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
20119                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
20120         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
20121                 error "Able to create DoM component size more than LOD limit"
20122
20123         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
20124         dom_current=$(do_facet mds1 $LCTL get_param -n \
20125                                                 lod.$mdtname.dom_stripesize)
20126         [ 0 -eq ${dom_current} ] ||
20127                 error "Can't set zero DoM stripe limit"
20128         rm $dom
20129
20130         # attempt to create DoM file on server with disabled DoM should
20131         # remove DoM entry from layout and be succeed
20132         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
20133                 error "Can't create DoM file (DoM is disabled)"
20134         [ $($LFS getstripe -L $dom) == "mdt" ] &&
20135                 error "File has DoM component while DoM is disabled"
20136         rm $dom
20137
20138         # attempt to create DoM file with only DoM stripe should return error
20139         $LFS setstripe -E $dom_limit -L mdt $dom &&
20140                 error "Able to create DoM-only file while DoM is disabled"
20141
20142         # too low values to be aligned with smallest stripe size 64K
20143         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
20144         dom_current=$(do_facet mds1 $LCTL get_param -n \
20145                                                 lod.$mdtname.dom_stripesize)
20146         [ 30000 -eq ${dom_current} ] &&
20147                 error "Can set too small DoM stripe limit"
20148
20149         # 64K is a minimal stripe size in Lustre, expect limit of that size
20150         [ 65536 -eq ${dom_current} ] ||
20151                 error "Limit is not set to 64K but ${dom_current}"
20152
20153         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
20154         dom_current=$(do_facet mds1 $LCTL get_param -n \
20155                                                 lod.$mdtname.dom_stripesize)
20156         echo $dom_current
20157         [ 2147483648 -eq ${dom_current} ] &&
20158                 error "Can set too large DoM stripe limit"
20159
20160         do_facet mds1 $LCTL set_param -n \
20161                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
20162         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
20163                 error "Can't create DoM component size after limit change"
20164         do_facet mds1 $LCTL set_param -n \
20165                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
20166         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
20167                 error "Can't create DoM file after limit decrease"
20168         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
20169                 error "Can create big DoM component after limit decrease"
20170         touch ${dom}_def ||
20171                 error "Can't create file with old default layout"
20172
20173         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
20174         return 0
20175 }
20176 run_test 270f "DoM: maximum DoM stripe size checks"
20177
20178 test_270g() {
20179         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20180                 skip "Need MDS version at least 2.13.52"
20181         local dom=$DIR/$tdir/$tfile
20182
20183         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20184         local lodname=${FSNAME}-MDT0000-mdtlov
20185
20186         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20187         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
20188         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
20189         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20190
20191         local dom_limit=1024
20192         local dom_threshold="50%"
20193
20194         $LFS setstripe -d $DIR/$tdir
20195         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
20196                 error "Can't set directory default striping"
20197
20198         do_facet mds1 $LCTL set_param -n \
20199                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
20200         # set 0 threshold and create DOM file to change tunable stripesize
20201         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
20202         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
20203                 error "Failed to create $dom file"
20204         # now tunable dom_cur_stripesize should reach maximum
20205         local dom_current=$(do_facet mds1 $LCTL get_param -n \
20206                                         lod.${lodname}.dom_stripesize_cur_kb)
20207         [[ $dom_current == $dom_limit ]] ||
20208                 error "Current DOM stripesize is not maximum"
20209         rm $dom
20210
20211         # set threshold for further tests
20212         do_facet mds1 $LCTL set_param -n \
20213                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
20214         echo "DOM threshold is $dom_threshold free space"
20215         local dom_def
20216         local dom_set
20217         # Spoof bfree to exceed threshold
20218         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
20219         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
20220         for spfree in 40 20 0 15 30 55; do
20221                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
20222                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
20223                         error "Failed to create $dom file"
20224                 dom_def=$(do_facet mds1 $LCTL get_param -n \
20225                                         lod.${lodname}.dom_stripesize_cur_kb)
20226                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
20227                 [[ $dom_def != $dom_current ]] ||
20228                         error "Default stripe size was not changed"
20229                 if [[ $spfree > 0 ]] ; then
20230                         dom_set=$($LFS getstripe -S $dom)
20231                         [[ $dom_set == $((dom_def * 1024)) ]] ||
20232                                 error "DOM component size is still old"
20233                 else
20234                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
20235                                 error "DoM component is set with no free space"
20236                 fi
20237                 rm $dom
20238                 dom_current=$dom_def
20239         done
20240 }
20241 run_test 270g "DoM: default DoM stripe size depends on free space"
20242
20243 test_270h() {
20244         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20245                 skip "Need MDS version at least 2.13.53"
20246
20247         local mdtname=${FSNAME}-MDT0000-mdtlov
20248         local dom=$DIR/$tdir/$tfile
20249         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20250
20251         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
20252         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20253
20254         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20255         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
20256                 error "can't create OST file"
20257         # mirrored file with DOM entry in the second mirror
20258         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
20259                 error "can't create mirror with DoM component"
20260
20261         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
20262
20263         # DOM component in the middle and has other enries in the same mirror,
20264         # should succeed but lost DoM component
20265         $LFS setstripe --copy=${dom}_1 $dom ||
20266                 error "Can't create file from OST|DOM mirror layout"
20267         # check new file has no DoM layout after all
20268         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
20269                 error "File has DoM component while DoM is disabled"
20270 }
20271 run_test 270h "DoM: DoM stripe removal when disabled on server"
20272
20273 test_271a() {
20274         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20275                 skip "Need MDS version at least 2.10.55"
20276
20277         local dom=$DIR/$tdir/dom
20278
20279         mkdir -p $DIR/$tdir
20280
20281         $LFS setstripe -E 1024K -L mdt $dom
20282
20283         lctl set_param -n mdc.*.stats=clear
20284         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
20285         cat $dom > /dev/null
20286         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
20287         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
20288         ls $dom
20289         rm -f $dom
20290 }
20291 run_test 271a "DoM: data is cached for read after write"
20292
20293 test_271b() {
20294         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20295                 skip "Need MDS version at least 2.10.55"
20296
20297         local dom=$DIR/$tdir/dom
20298
20299         mkdir -p $DIR/$tdir
20300
20301         $LFS setstripe -E 1024K -L mdt -E EOF $dom
20302
20303         lctl set_param -n mdc.*.stats=clear
20304         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
20305         cancel_lru_locks mdc
20306         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
20307         # second stat to check size is cached on client
20308         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
20309         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
20310         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
20311         rm -f $dom
20312 }
20313 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
20314
20315 test_271ba() {
20316         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20317                 skip "Need MDS version at least 2.10.55"
20318
20319         local dom=$DIR/$tdir/dom
20320
20321         mkdir -p $DIR/$tdir
20322
20323         $LFS setstripe -E 1024K -L mdt -E EOF $dom
20324
20325         lctl set_param -n mdc.*.stats=clear
20326         lctl set_param -n osc.*.stats=clear
20327         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
20328         cancel_lru_locks mdc
20329         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
20330         # second stat to check size is cached on client
20331         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
20332         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
20333         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
20334         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
20335         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
20336         rm -f $dom
20337 }
20338 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
20339
20340
20341 get_mdc_stats() {
20342         local mdtidx=$1
20343         local param=$2
20344         local mdt=MDT$(printf %04x $mdtidx)
20345
20346         if [ -z $param ]; then
20347                 lctl get_param -n mdc.*$mdt*.stats
20348         else
20349                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
20350         fi
20351 }
20352
20353 test_271c() {
20354         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20355                 skip "Need MDS version at least 2.10.55"
20356
20357         local dom=$DIR/$tdir/dom
20358
20359         mkdir -p $DIR/$tdir
20360
20361         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20362
20363         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
20364         local facet=mds$((mdtidx + 1))
20365
20366         cancel_lru_locks mdc
20367         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
20368         createmany -o $dom 1000
20369         lctl set_param -n mdc.*.stats=clear
20370         smalliomany -w $dom 1000 200
20371         get_mdc_stats $mdtidx
20372         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
20373         # Each file has 1 open, 1 IO enqueues, total 2000
20374         # but now we have also +1 getxattr for security.capability, total 3000
20375         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
20376         unlinkmany $dom 1000
20377
20378         cancel_lru_locks mdc
20379         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
20380         createmany -o $dom 1000
20381         lctl set_param -n mdc.*.stats=clear
20382         smalliomany -w $dom 1000 200
20383         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
20384         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
20385         # for OPEN and IO lock.
20386         [ $((enq - enq_2)) -ge 1000 ] ||
20387                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
20388         unlinkmany $dom 1000
20389         return 0
20390 }
20391 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
20392
20393 cleanup_271def_tests() {
20394         trap 0
20395         rm -f $1
20396 }
20397
20398 test_271d() {
20399         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
20400                 skip "Need MDS version at least 2.10.57"
20401
20402         local dom=$DIR/$tdir/dom
20403         local tmp=$TMP/$tfile
20404         trap "cleanup_271def_tests $tmp" EXIT
20405
20406         mkdir -p $DIR/$tdir
20407
20408         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20409
20410         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
20411
20412         cancel_lru_locks mdc
20413         dd if=/dev/urandom of=$tmp bs=1000 count=1
20414         dd if=$tmp of=$dom bs=1000 count=1
20415         cancel_lru_locks mdc
20416
20417         cat /etc/hosts >> $tmp
20418         lctl set_param -n mdc.*.stats=clear
20419
20420         # append data to the same file it should update local page
20421         echo "Append to the same page"
20422         cat /etc/hosts >> $dom
20423         local num=$(get_mdc_stats $mdtidx ost_read)
20424         local ra=$(get_mdc_stats $mdtidx req_active)
20425         local rw=$(get_mdc_stats $mdtidx req_waittime)
20426
20427         [ -z $num ] || error "$num READ RPC occured"
20428         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20429         echo "... DONE"
20430
20431         # compare content
20432         cmp $tmp $dom || error "file miscompare"
20433
20434         cancel_lru_locks mdc
20435         lctl set_param -n mdc.*.stats=clear
20436
20437         echo "Open and read file"
20438         cat $dom > /dev/null
20439         local num=$(get_mdc_stats $mdtidx ost_read)
20440         local ra=$(get_mdc_stats $mdtidx req_active)
20441         local rw=$(get_mdc_stats $mdtidx req_waittime)
20442
20443         [ -z $num ] || error "$num READ RPC occured"
20444         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20445         echo "... DONE"
20446
20447         # compare content
20448         cmp $tmp $dom || error "file miscompare"
20449
20450         return 0
20451 }
20452 run_test 271d "DoM: read on open (1K file in reply buffer)"
20453
20454 test_271f() {
20455         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
20456                 skip "Need MDS version at least 2.10.57"
20457
20458         local dom=$DIR/$tdir/dom
20459         local tmp=$TMP/$tfile
20460         trap "cleanup_271def_tests $tmp" EXIT
20461
20462         mkdir -p $DIR/$tdir
20463
20464         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20465
20466         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
20467
20468         cancel_lru_locks mdc
20469         dd if=/dev/urandom of=$tmp bs=265000 count=1
20470         dd if=$tmp of=$dom bs=265000 count=1
20471         cancel_lru_locks mdc
20472         cat /etc/hosts >> $tmp
20473         lctl set_param -n mdc.*.stats=clear
20474
20475         echo "Append to the same page"
20476         cat /etc/hosts >> $dom
20477         local num=$(get_mdc_stats $mdtidx ost_read)
20478         local ra=$(get_mdc_stats $mdtidx req_active)
20479         local rw=$(get_mdc_stats $mdtidx req_waittime)
20480
20481         [ -z $num ] || error "$num READ RPC occured"
20482         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20483         echo "... DONE"
20484
20485         # compare content
20486         cmp $tmp $dom || error "file miscompare"
20487
20488         cancel_lru_locks mdc
20489         lctl set_param -n mdc.*.stats=clear
20490
20491         echo "Open and read file"
20492         cat $dom > /dev/null
20493         local num=$(get_mdc_stats $mdtidx ost_read)
20494         local ra=$(get_mdc_stats $mdtidx req_active)
20495         local rw=$(get_mdc_stats $mdtidx req_waittime)
20496
20497         [ -z $num ] && num=0
20498         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
20499         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20500         echo "... DONE"
20501
20502         # compare content
20503         cmp $tmp $dom || error "file miscompare"
20504
20505         return 0
20506 }
20507 run_test 271f "DoM: read on open (200K file and read tail)"
20508
20509 test_271g() {
20510         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
20511                 skip "Skipping due to old client or server version"
20512
20513         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
20514         # to get layout
20515         $CHECKSTAT -t file $DIR1/$tfile
20516
20517         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
20518         MULTIOP_PID=$!
20519         sleep 1
20520         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
20521         $LCTL set_param fail_loc=0x80000314
20522         rm $DIR1/$tfile || error "Unlink fails"
20523         RC=$?
20524         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
20525         [ $RC -eq 0 ] || error "Failed write to stale object"
20526 }
20527 run_test 271g "Discard DoM data vs client flush race"
20528
20529 test_272a() {
20530         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20531                 skip "Need MDS version at least 2.11.50"
20532
20533         local dom=$DIR/$tdir/dom
20534         mkdir -p $DIR/$tdir
20535
20536         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
20537         dd if=/dev/urandom of=$dom bs=512K count=1 ||
20538                 error "failed to write data into $dom"
20539         local old_md5=$(md5sum $dom)
20540
20541         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
20542                 error "failed to migrate to the same DoM component"
20543
20544         local new_md5=$(md5sum $dom)
20545
20546         [ "$old_md5" == "$new_md5" ] ||
20547                 error "md5sum differ: $old_md5, $new_md5"
20548
20549         [ $($LFS getstripe -c $dom) -eq 2 ] ||
20550                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
20551 }
20552 run_test 272a "DoM migration: new layout with the same DOM component"
20553
20554 test_272b() {
20555         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20556                 skip "Need MDS version at least 2.11.50"
20557
20558         local dom=$DIR/$tdir/dom
20559         mkdir -p $DIR/$tdir
20560         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20561
20562         local mdtidx=$($LFS getstripe -m $dom)
20563         local mdtname=MDT$(printf %04x $mdtidx)
20564         local facet=mds$((mdtidx + 1))
20565
20566         local mdtfree1=$(do_facet $facet \
20567                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20568         dd if=/dev/urandom of=$dom bs=2M count=1 ||
20569                 error "failed to write data into $dom"
20570         local old_md5=$(md5sum $dom)
20571         cancel_lru_locks mdc
20572         local mdtfree1=$(do_facet $facet \
20573                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20574
20575         $LFS migrate -c2 $dom ||
20576                 error "failed to migrate to the new composite layout"
20577         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20578                 error "MDT stripe was not removed"
20579
20580         cancel_lru_locks mdc
20581         local new_md5=$(md5sum $dom)
20582         [ "$old_md5" == "$new_md5" ] ||
20583                 error "$old_md5 != $new_md5"
20584
20585         # Skip free space checks with ZFS
20586         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20587                 local mdtfree2=$(do_facet $facet \
20588                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20589                 [ $mdtfree2 -gt $mdtfree1 ] ||
20590                         error "MDT space is not freed after migration"
20591         fi
20592         return 0
20593 }
20594 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
20595
20596 test_272c() {
20597         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20598                 skip "Need MDS version at least 2.11.50"
20599
20600         local dom=$DIR/$tdir/$tfile
20601         mkdir -p $DIR/$tdir
20602         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20603
20604         local mdtidx=$($LFS getstripe -m $dom)
20605         local mdtname=MDT$(printf %04x $mdtidx)
20606         local facet=mds$((mdtidx + 1))
20607
20608         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
20609                 error "failed to write data into $dom"
20610         local old_md5=$(md5sum $dom)
20611         cancel_lru_locks mdc
20612         local mdtfree1=$(do_facet $facet \
20613                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20614
20615         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
20616                 error "failed to migrate to the new composite layout"
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 migration"
20631         fi
20632         return 0
20633 }
20634 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
20635
20636 test_272d() {
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 -E 1M -L mdt -E -1 -c1 $dom
20643
20644         local mdtidx=$($LFS getstripe -m $dom)
20645         local mdtname=MDT$(printf %04x $mdtidx)
20646         local facet=mds$((mdtidx + 1))
20647
20648         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
20649                 error "failed to write data into $dom"
20650         local old_md5=$(md5sum $dom)
20651         cancel_lru_locks mdc
20652         local mdtfree1=$(do_facet $facet \
20653                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20654
20655         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
20656                 error "failed mirroring to the new composite layout"
20657         $LFS mirror resync $dom ||
20658                 error "failed mirror resync"
20659         $LFS mirror split --mirror-id 1 -d $dom ||
20660                 error "failed mirror split"
20661
20662         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20663                 error "MDT stripe was not removed"
20664
20665         cancel_lru_locks mdc
20666         local new_md5=$(md5sum $dom)
20667         [ "$old_md5" == "$new_md5" ] ||
20668                 error "$old_md5 != $new_md5"
20669
20670         # Skip free space checks with ZFS
20671         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20672                 local mdtfree2=$(do_facet $facet \
20673                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20674                 [ $mdtfree2 -gt $mdtfree1 ] ||
20675                         error "MDS space is not freed after DOM mirror deletion"
20676         fi
20677         return 0
20678 }
20679 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
20680
20681 test_272e() {
20682         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20683                 skip "Need MDS version at least 2.12.55"
20684
20685         local dom=$DIR/$tdir/$tfile
20686         mkdir -p $DIR/$tdir
20687         $LFS setstripe -c 2 $dom
20688
20689         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
20690                 error "failed to write data into $dom"
20691         local old_md5=$(md5sum $dom)
20692         cancel_lru_locks mdc
20693
20694         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
20695                 error "failed mirroring to the DOM layout"
20696         $LFS mirror resync $dom ||
20697                 error "failed mirror resync"
20698         $LFS mirror split --mirror-id 1 -d $dom ||
20699                 error "failed mirror split"
20700
20701         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20702                 error "MDT stripe was not removed"
20703
20704         cancel_lru_locks mdc
20705         local new_md5=$(md5sum $dom)
20706         [ "$old_md5" == "$new_md5" ] ||
20707                 error "$old_md5 != $new_md5"
20708
20709         return 0
20710 }
20711 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
20712
20713 test_272f() {
20714         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20715                 skip "Need MDS version at least 2.12.55"
20716
20717         local dom=$DIR/$tdir/$tfile
20718         mkdir -p $DIR/$tdir
20719         $LFS setstripe -c 2 $dom
20720
20721         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
20722                 error "failed to write data into $dom"
20723         local old_md5=$(md5sum $dom)
20724         cancel_lru_locks mdc
20725
20726         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
20727                 error "failed migrating to the DOM file"
20728
20729         cancel_lru_locks mdc
20730         local new_md5=$(md5sum $dom)
20731         [ "$old_md5" != "$new_md5" ] &&
20732                 error "$old_md5 != $new_md5"
20733
20734         return 0
20735 }
20736 run_test 272f "DoM migration: OST-striped file to DOM file"
20737
20738 test_273a() {
20739         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20740                 skip "Need MDS version at least 2.11.50"
20741
20742         # Layout swap cannot be done if either file has DOM component,
20743         # this will never be supported, migration should be used instead
20744
20745         local dom=$DIR/$tdir/$tfile
20746         mkdir -p $DIR/$tdir
20747
20748         $LFS setstripe -c2 ${dom}_plain
20749         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
20750         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
20751                 error "can swap layout with DoM component"
20752         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
20753                 error "can swap layout with DoM component"
20754
20755         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
20756         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
20757                 error "can swap layout with DoM component"
20758         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
20759                 error "can swap layout with DoM component"
20760         return 0
20761 }
20762 run_test 273a "DoM: layout swapping should fail with DOM"
20763
20764 test_275() {
20765         remote_ost_nodsh && skip "remote OST with nodsh"
20766         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
20767                 skip "Need OST version >= 2.10.57"
20768
20769         local file=$DIR/$tfile
20770         local oss
20771
20772         oss=$(comma_list $(osts_nodes))
20773
20774         dd if=/dev/urandom of=$file bs=1M count=2 ||
20775                 error "failed to create a file"
20776         cancel_lru_locks osc
20777
20778         #lock 1
20779         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
20780                 error "failed to read a file"
20781
20782 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
20783         $LCTL set_param fail_loc=0x8000031f
20784
20785         cancel_lru_locks osc &
20786         sleep 1
20787
20788 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
20789         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
20790         #IO takes another lock, but matches the PENDING one
20791         #and places it to the IO RPC
20792         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
20793                 error "failed to read a file with PENDING lock"
20794 }
20795 run_test 275 "Read on a canceled duplicate lock"
20796
20797 test_276() {
20798         remote_ost_nodsh && skip "remote OST with nodsh"
20799         local pid
20800
20801         do_facet ost1 "(while true; do \
20802                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
20803                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
20804         pid=$!
20805
20806         for LOOP in $(seq 20); do
20807                 stop ost1
20808                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
20809         done
20810         kill -9 $pid
20811         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
20812                 rm $TMP/sanity_276_pid"
20813 }
20814 run_test 276 "Race between mount and obd_statfs"
20815
20816 test_277() {
20817         $LCTL set_param ldlm.namespaces.*.lru_size=0
20818         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
20819         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
20820                         grep ^used_mb | awk '{print $2}')
20821         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
20822         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
20823                 oflag=direct conv=notrunc
20824         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
20825                         grep ^used_mb | awk '{print $2}')
20826         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
20827 }
20828 run_test 277 "Direct IO shall drop page cache"
20829
20830 test_278() {
20831         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
20832         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
20833         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
20834                 skip "needs the same host for mdt1 mdt2" && return
20835
20836         local pid1
20837         local pid2
20838
20839 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
20840         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
20841         stop mds2 &
20842         pid2=$!
20843
20844         stop mds1
20845
20846         echo "Starting MDTs"
20847         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
20848         wait $pid2
20849 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
20850 #will return NULL
20851         do_facet mds2 $LCTL set_param fail_loc=0
20852
20853         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
20854         wait_recovery_complete mds2
20855 }
20856 run_test 278 "Race starting MDS between MDTs stop/start"
20857
20858 test_280() {
20859         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
20860                 skip "Need MGS version at least 2.13.52"
20861         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20862         combined_mgs_mds || skip "needs combined MGS/MDT"
20863
20864         umount_client $MOUNT
20865 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
20866         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
20867
20868         mount_client $MOUNT &
20869         sleep 1
20870         stop mgs || error "stop mgs failed"
20871         #for a race mgs would crash
20872         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
20873         mount_client $MOUNT || error "mount client failed"
20874 }
20875 run_test 280 "Race between MGS umount and client llog processing"
20876
20877 cleanup_test_300() {
20878         trap 0
20879         umask $SAVE_UMASK
20880 }
20881 test_striped_dir() {
20882         local mdt_index=$1
20883         local stripe_count
20884         local stripe_index
20885
20886         mkdir -p $DIR/$tdir
20887
20888         SAVE_UMASK=$(umask)
20889         trap cleanup_test_300 RETURN EXIT
20890
20891         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
20892                                                 $DIR/$tdir/striped_dir ||
20893                 error "set striped dir error"
20894
20895         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
20896         [ "$mode" = "755" ] || error "expect 755 got $mode"
20897
20898         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
20899                 error "getdirstripe failed"
20900         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
20901         if [ "$stripe_count" != "2" ]; then
20902                 error "1:stripe_count is $stripe_count, expect 2"
20903         fi
20904         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
20905         if [ "$stripe_count" != "2" ]; then
20906                 error "2:stripe_count is $stripe_count, expect 2"
20907         fi
20908
20909         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
20910         if [ "$stripe_index" != "$mdt_index" ]; then
20911                 error "stripe_index is $stripe_index, expect $mdt_index"
20912         fi
20913
20914         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
20915                 error "nlink error after create striped dir"
20916
20917         mkdir $DIR/$tdir/striped_dir/a
20918         mkdir $DIR/$tdir/striped_dir/b
20919
20920         stat $DIR/$tdir/striped_dir/a ||
20921                 error "create dir under striped dir failed"
20922         stat $DIR/$tdir/striped_dir/b ||
20923                 error "create dir under striped dir failed"
20924
20925         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
20926                 error "nlink error after mkdir"
20927
20928         rmdir $DIR/$tdir/striped_dir/a
20929         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
20930                 error "nlink error after rmdir"
20931
20932         rmdir $DIR/$tdir/striped_dir/b
20933         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
20934                 error "nlink error after rmdir"
20935
20936         chattr +i $DIR/$tdir/striped_dir
20937         createmany -o $DIR/$tdir/striped_dir/f 10 &&
20938                 error "immutable flags not working under striped dir!"
20939         chattr -i $DIR/$tdir/striped_dir
20940
20941         rmdir $DIR/$tdir/striped_dir ||
20942                 error "rmdir striped dir error"
20943
20944         cleanup_test_300
20945
20946         true
20947 }
20948
20949 test_300a() {
20950         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20951                 skip "skipped for lustre < 2.7.0"
20952         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20953         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20954
20955         test_striped_dir 0 || error "failed on striped dir on MDT0"
20956         test_striped_dir 1 || error "failed on striped dir on MDT0"
20957 }
20958 run_test 300a "basic striped dir sanity test"
20959
20960 test_300b() {
20961         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20962                 skip "skipped for lustre < 2.7.0"
20963         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20964         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20965
20966         local i
20967         local mtime1
20968         local mtime2
20969         local mtime3
20970
20971         test_mkdir $DIR/$tdir || error "mkdir fail"
20972         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
20973                 error "set striped dir error"
20974         for i in {0..9}; do
20975                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
20976                 sleep 1
20977                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
20978                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
20979                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
20980                 sleep 1
20981                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
20982                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
20983                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
20984         done
20985         true
20986 }
20987 run_test 300b "check ctime/mtime for striped dir"
20988
20989 test_300c() {
20990         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20991                 skip "skipped for lustre < 2.7.0"
20992         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20993         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20994
20995         local file_count
20996
20997         mkdir -p $DIR/$tdir
20998         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
20999                 error "set striped dir error"
21000
21001         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
21002                 error "chown striped dir failed"
21003
21004         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
21005                 error "create 5k files failed"
21006
21007         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
21008
21009         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
21010
21011         rm -rf $DIR/$tdir
21012 }
21013 run_test 300c "chown && check ls under striped directory"
21014
21015 test_300d() {
21016         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21017                 skip "skipped for lustre < 2.7.0"
21018         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21019         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21020
21021         local stripe_count
21022         local file
21023
21024         mkdir -p $DIR/$tdir
21025         $LFS setstripe -c 2 $DIR/$tdir
21026
21027         #local striped directory
21028         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21029                 error "set striped dir error"
21030         #look at the directories for debug purposes
21031         ls -l $DIR/$tdir
21032         $LFS getdirstripe $DIR/$tdir
21033         ls -l $DIR/$tdir/striped_dir
21034         $LFS getdirstripe $DIR/$tdir/striped_dir
21035         createmany -o $DIR/$tdir/striped_dir/f 10 ||
21036                 error "create 10 files failed"
21037
21038         #remote striped directory
21039         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
21040                 error "set striped dir error"
21041         #look at the directories for debug purposes
21042         ls -l $DIR/$tdir
21043         $LFS getdirstripe $DIR/$tdir
21044         ls -l $DIR/$tdir/remote_striped_dir
21045         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
21046         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
21047                 error "create 10 files failed"
21048
21049         for file in $(find $DIR/$tdir); do
21050                 stripe_count=$($LFS getstripe -c $file)
21051                 [ $stripe_count -eq 2 ] ||
21052                         error "wrong stripe $stripe_count for $file"
21053         done
21054
21055         rm -rf $DIR/$tdir
21056 }
21057 run_test 300d "check default stripe under striped directory"
21058
21059 test_300e() {
21060         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21061                 skip "Need MDS version at least 2.7.55"
21062         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21063         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21064
21065         local stripe_count
21066         local file
21067
21068         mkdir -p $DIR/$tdir
21069
21070         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21071                 error "set striped dir error"
21072
21073         touch $DIR/$tdir/striped_dir/a
21074         touch $DIR/$tdir/striped_dir/b
21075         touch $DIR/$tdir/striped_dir/c
21076
21077         mkdir $DIR/$tdir/striped_dir/dir_a
21078         mkdir $DIR/$tdir/striped_dir/dir_b
21079         mkdir $DIR/$tdir/striped_dir/dir_c
21080
21081         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
21082                 error "set striped adir under striped dir error"
21083
21084         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
21085                 error "set striped bdir under striped dir error"
21086
21087         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
21088                 error "set striped cdir under striped dir error"
21089
21090         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
21091                 error "rename dir under striped dir fails"
21092
21093         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
21094                 error "rename dir under different stripes fails"
21095
21096         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
21097                 error "rename file under striped dir should succeed"
21098
21099         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
21100                 error "rename dir under striped dir should succeed"
21101
21102         rm -rf $DIR/$tdir
21103 }
21104 run_test 300e "check rename under striped directory"
21105
21106 test_300f() {
21107         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21108         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21109         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21110                 skip "Need MDS version at least 2.7.55"
21111
21112         local stripe_count
21113         local file
21114
21115         rm -rf $DIR/$tdir
21116         mkdir -p $DIR/$tdir
21117
21118         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21119                 error "set striped dir error"
21120
21121         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
21122                 error "set striped dir error"
21123
21124         touch $DIR/$tdir/striped_dir/a
21125         mkdir $DIR/$tdir/striped_dir/dir_a
21126         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
21127                 error "create striped dir under striped dir fails"
21128
21129         touch $DIR/$tdir/striped_dir1/b
21130         mkdir $DIR/$tdir/striped_dir1/dir_b
21131         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
21132                 error "create striped dir under striped dir fails"
21133
21134         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
21135                 error "rename dir under different striped dir should fail"
21136
21137         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
21138                 error "rename striped dir under diff striped dir should fail"
21139
21140         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
21141                 error "rename file under diff striped dirs fails"
21142
21143         rm -rf $DIR/$tdir
21144 }
21145 run_test 300f "check rename cross striped directory"
21146
21147 test_300_check_default_striped_dir()
21148 {
21149         local dirname=$1
21150         local default_count=$2
21151         local default_index=$3
21152         local stripe_count
21153         local stripe_index
21154         local dir_stripe_index
21155         local dir
21156
21157         echo "checking $dirname $default_count $default_index"
21158         $LFS setdirstripe -D -c $default_count -i $default_index \
21159                                 -t all_char $DIR/$tdir/$dirname ||
21160                 error "set default stripe on striped dir error"
21161         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
21162         [ $stripe_count -eq $default_count ] ||
21163                 error "expect $default_count get $stripe_count for $dirname"
21164
21165         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
21166         [ $stripe_index -eq $default_index ] ||
21167                 error "expect $default_index get $stripe_index for $dirname"
21168
21169         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
21170                                                 error "create dirs failed"
21171
21172         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
21173         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
21174         for dir in $(find $DIR/$tdir/$dirname/*); do
21175                 stripe_count=$($LFS getdirstripe -c $dir)
21176                 [ $stripe_count -eq $default_count ] ||
21177                 [ $stripe_count -eq 0 ] || [ $default_count -eq 1 ] ||
21178                 error "stripe count $default_count != $stripe_count for $dir"
21179
21180                 stripe_index=$($LFS getdirstripe -i $dir)
21181                 [ $default_index -eq -1 ] ||
21182                         [ $stripe_index -eq $default_index ] ||
21183                         error "$stripe_index != $default_index for $dir"
21184
21185                 #check default stripe
21186                 stripe_count=$($LFS getdirstripe -D -c $dir)
21187                 [ $stripe_count -eq $default_count ] ||
21188                 error "default count $default_count != $stripe_count for $dir"
21189
21190                 stripe_index=$($LFS getdirstripe -D -i $dir)
21191                 [ $stripe_index -eq $default_index ] ||
21192                 error "default index $default_index != $stripe_index for $dir"
21193         done
21194         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
21195 }
21196
21197 test_300g() {
21198         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21199         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21200                 skip "Need MDS version at least 2.7.55"
21201
21202         local dir
21203         local stripe_count
21204         local stripe_index
21205
21206         mkdir $DIR/$tdir
21207         mkdir $DIR/$tdir/normal_dir
21208
21209         #Checking when client cache stripe index
21210         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
21211         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
21212                 error "create striped_dir failed"
21213
21214         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
21215                 error "create dir0 fails"
21216         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
21217         [ $stripe_index -eq 0 ] ||
21218                 error "dir0 expect index 0 got $stripe_index"
21219
21220         mkdir $DIR/$tdir/striped_dir/dir1 ||
21221                 error "create dir1 fails"
21222         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
21223         [ $stripe_index -eq 1 ] ||
21224                 error "dir1 expect index 1 got $stripe_index"
21225
21226         #check default stripe count/stripe index
21227         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
21228         test_300_check_default_striped_dir normal_dir 1 0
21229         test_300_check_default_striped_dir normal_dir 2 1
21230         test_300_check_default_striped_dir normal_dir 2 -1
21231
21232         #delete default stripe information
21233         echo "delete default stripeEA"
21234         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
21235                 error "set default stripe on striped dir error"
21236
21237         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
21238         for dir in $(find $DIR/$tdir/normal_dir/*); do
21239                 stripe_count=$($LFS getdirstripe -c $dir)
21240                 [ $stripe_count -eq 0 ] ||
21241                         error "expect 1 get $stripe_count for $dir"
21242                 stripe_index=$($LFS getdirstripe -i $dir)
21243                 [ $stripe_index -eq 0 ] ||
21244                         error "expect 0 get $stripe_index for $dir"
21245         done
21246 }
21247 run_test 300g "check default striped directory for normal directory"
21248
21249 test_300h() {
21250         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21251         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21252                 skip "Need MDS version at least 2.7.55"
21253
21254         local dir
21255         local stripe_count
21256
21257         mkdir $DIR/$tdir
21258         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21259                 error "set striped dir error"
21260
21261         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
21262         test_300_check_default_striped_dir striped_dir 1 0
21263         test_300_check_default_striped_dir striped_dir 2 1
21264         test_300_check_default_striped_dir striped_dir 2 -1
21265
21266         #delete default stripe information
21267         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
21268                 error "set default stripe on striped dir error"
21269
21270         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
21271         for dir in $(find $DIR/$tdir/striped_dir/*); do
21272                 stripe_count=$($LFS getdirstripe -c $dir)
21273                 [ $stripe_count -eq 0 ] ||
21274                         error "expect 1 get $stripe_count for $dir"
21275         done
21276 }
21277 run_test 300h "check default striped directory for striped directory"
21278
21279 test_300i() {
21280         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21281         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21282         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21283                 skip "Need MDS version at least 2.7.55"
21284
21285         local stripe_count
21286         local file
21287
21288         mkdir $DIR/$tdir
21289
21290         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21291                 error "set striped dir error"
21292
21293         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
21294                 error "create files under striped dir failed"
21295
21296         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
21297                 error "set striped hashdir error"
21298
21299         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
21300                 error "create dir0 under hash dir failed"
21301         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
21302                 error "create dir1 under hash dir failed"
21303
21304         # unfortunately, we need to umount to clear dir layout cache for now
21305         # once we fully implement dir layout, we can drop this
21306         umount_client $MOUNT || error "umount failed"
21307         mount_client $MOUNT || error "mount failed"
21308
21309         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
21310         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
21311         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
21312
21313         #set the stripe to be unknown hash type
21314         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
21315         $LCTL set_param fail_loc=0x1901
21316         for ((i = 0; i < 10; i++)); do
21317                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
21318                         error "stat f-$i failed"
21319                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
21320         done
21321
21322         touch $DIR/$tdir/striped_dir/f0 &&
21323                 error "create under striped dir with unknown hash should fail"
21324
21325         $LCTL set_param fail_loc=0
21326
21327         umount_client $MOUNT || error "umount failed"
21328         mount_client $MOUNT || error "mount failed"
21329
21330         return 0
21331 }
21332 run_test 300i "client handle unknown hash type striped directory"
21333
21334 test_300j() {
21335         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21336         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21337         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21338                 skip "Need MDS version at least 2.7.55"
21339
21340         local stripe_count
21341         local file
21342
21343         mkdir $DIR/$tdir
21344
21345         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
21346         $LCTL set_param fail_loc=0x1702
21347         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21348                 error "set striped dir error"
21349
21350         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
21351                 error "create files under striped dir failed"
21352
21353         $LCTL set_param fail_loc=0
21354
21355         rm -rf $DIR/$tdir || error "unlink striped dir fails"
21356
21357         return 0
21358 }
21359 run_test 300j "test large update record"
21360
21361 test_300k() {
21362         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21363         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21364         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21365                 skip "Need MDS version at least 2.7.55"
21366
21367         # this test needs a huge transaction
21368         local kb
21369         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21370              osd*.$FSNAME-MDT0000.kbytestotal")
21371         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
21372
21373         local stripe_count
21374         local file
21375
21376         mkdir $DIR/$tdir
21377
21378         #define OBD_FAIL_LARGE_STRIPE   0x1703
21379         $LCTL set_param fail_loc=0x1703
21380         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
21381                 error "set striped dir error"
21382         $LCTL set_param fail_loc=0
21383
21384         $LFS getdirstripe $DIR/$tdir/striped_dir ||
21385                 error "getstripeddir fails"
21386         rm -rf $DIR/$tdir/striped_dir ||
21387                 error "unlink striped dir fails"
21388
21389         return 0
21390 }
21391 run_test 300k "test large striped directory"
21392
21393 test_300l() {
21394         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21395         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21396         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21397                 skip "Need MDS version at least 2.7.55"
21398
21399         local stripe_index
21400
21401         test_mkdir -p $DIR/$tdir/striped_dir
21402         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
21403                         error "chown $RUNAS_ID failed"
21404         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
21405                 error "set default striped dir failed"
21406
21407         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
21408         $LCTL set_param fail_loc=0x80000158
21409         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
21410
21411         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
21412         [ $stripe_index -eq 1 ] ||
21413                 error "expect 1 get $stripe_index for $dir"
21414 }
21415 run_test 300l "non-root user to create dir under striped dir with stale layout"
21416
21417 test_300m() {
21418         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21419         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
21420         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21421                 skip "Need MDS version at least 2.7.55"
21422
21423         mkdir -p $DIR/$tdir/striped_dir
21424         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
21425                 error "set default stripes dir error"
21426
21427         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
21428
21429         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
21430         [ $stripe_count -eq 0 ] ||
21431                         error "expect 0 get $stripe_count for a"
21432
21433         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
21434                 error "set default stripes dir error"
21435
21436         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
21437
21438         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
21439         [ $stripe_count -eq 0 ] ||
21440                         error "expect 0 get $stripe_count for b"
21441
21442         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
21443                 error "set default stripes dir error"
21444
21445         mkdir $DIR/$tdir/striped_dir/c &&
21446                 error "default stripe_index is invalid, mkdir c should fails"
21447
21448         rm -rf $DIR/$tdir || error "rmdir fails"
21449 }
21450 run_test 300m "setstriped directory on single MDT FS"
21451
21452 cleanup_300n() {
21453         local list=$(comma_list $(mdts_nodes))
21454
21455         trap 0
21456         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21457 }
21458
21459 test_300n() {
21460         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21461         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21462         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21463                 skip "Need MDS version at least 2.7.55"
21464         remote_mds_nodsh && skip "remote MDS with nodsh"
21465
21466         local stripe_index
21467         local list=$(comma_list $(mdts_nodes))
21468
21469         trap cleanup_300n RETURN EXIT
21470         mkdir -p $DIR/$tdir
21471         chmod 777 $DIR/$tdir
21472         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
21473                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
21474                 error "create striped dir succeeds with gid=0"
21475
21476         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
21477         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
21478                 error "create striped dir fails with gid=-1"
21479
21480         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21481         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
21482                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
21483                 error "set default striped dir succeeds with gid=0"
21484
21485
21486         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
21487         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
21488                 error "set default striped dir fails with gid=-1"
21489
21490
21491         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21492         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
21493                                         error "create test_dir fails"
21494         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
21495                                         error "create test_dir1 fails"
21496         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
21497                                         error "create test_dir2 fails"
21498         cleanup_300n
21499 }
21500 run_test 300n "non-root user to create dir under striped dir with default EA"
21501
21502 test_300o() {
21503         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21504         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21505         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21506                 skip "Need MDS version at least 2.7.55"
21507
21508         local numfree1
21509         local numfree2
21510
21511         mkdir -p $DIR/$tdir
21512
21513         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
21514         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
21515         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
21516                 skip "not enough free inodes $numfree1 $numfree2"
21517         fi
21518
21519         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
21520         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
21521         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
21522                 skip "not enough free space $numfree1 $numfree2"
21523         fi
21524
21525         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
21526                 error "setdirstripe fails"
21527
21528         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
21529                 error "create dirs fails"
21530
21531         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
21532         ls $DIR/$tdir/striped_dir > /dev/null ||
21533                 error "ls striped dir fails"
21534         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
21535                 error "unlink big striped dir fails"
21536 }
21537 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
21538
21539 test_300p() {
21540         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21541         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21542         remote_mds_nodsh && skip "remote MDS with nodsh"
21543
21544         mkdir -p $DIR/$tdir
21545
21546         #define OBD_FAIL_OUT_ENOSPC     0x1704
21547         do_facet mds2 lctl set_param fail_loc=0x80001704
21548         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
21549                  && error "create striped directory should fail"
21550
21551         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
21552
21553         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
21554         true
21555 }
21556 run_test 300p "create striped directory without space"
21557
21558 test_300q() {
21559         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21560         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21561
21562         local fd=$(free_fd)
21563         local cmd="exec $fd<$tdir"
21564         cd $DIR
21565         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
21566         eval $cmd
21567         cmd="exec $fd<&-"
21568         trap "eval $cmd" EXIT
21569         cd $tdir || error "cd $tdir fails"
21570         rmdir  ../$tdir || error "rmdir $tdir fails"
21571         mkdir local_dir && error "create dir succeeds"
21572         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
21573         eval $cmd
21574         return 0
21575 }
21576 run_test 300q "create remote directory under orphan directory"
21577
21578 test_300r() {
21579         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21580                 skip "Need MDS version at least 2.7.55" && return
21581         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
21582
21583         mkdir $DIR/$tdir
21584
21585         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
21586                 error "set striped dir error"
21587
21588         $LFS getdirstripe $DIR/$tdir/striped_dir ||
21589                 error "getstripeddir fails"
21590
21591         local stripe_count
21592         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
21593                       awk '/lmv_stripe_count:/ { print $2 }')
21594
21595         [ $MDSCOUNT -ne $stripe_count ] &&
21596                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
21597
21598         rm -rf $DIR/$tdir/striped_dir ||
21599                 error "unlink striped dir fails"
21600 }
21601 run_test 300r "test -1 striped directory"
21602
21603 prepare_remote_file() {
21604         mkdir $DIR/$tdir/src_dir ||
21605                 error "create remote source failed"
21606
21607         cp /etc/hosts $DIR/$tdir/src_dir/a ||
21608                  error "cp to remote source failed"
21609         touch $DIR/$tdir/src_dir/a
21610
21611         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
21612                 error "create remote target dir failed"
21613
21614         touch $DIR/$tdir/tgt_dir/b
21615
21616         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
21617                 error "rename dir cross MDT failed!"
21618
21619         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
21620                 error "src_child still exists after rename"
21621
21622         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
21623                 error "missing file(a) after rename"
21624
21625         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
21626                 error "diff after rename"
21627 }
21628
21629 test_310a() {
21630         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
21631         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21632
21633         local remote_file=$DIR/$tdir/tgt_dir/b
21634
21635         mkdir -p $DIR/$tdir
21636
21637         prepare_remote_file || error "prepare remote file failed"
21638
21639         #open-unlink file
21640         $OPENUNLINK $remote_file $remote_file ||
21641                 error "openunlink $remote_file failed"
21642         $CHECKSTAT -a $remote_file || error "$remote_file exists"
21643 }
21644 run_test 310a "open unlink remote file"
21645
21646 test_310b() {
21647         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
21648         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21649
21650         local remote_file=$DIR/$tdir/tgt_dir/b
21651
21652         mkdir -p $DIR/$tdir
21653
21654         prepare_remote_file || error "prepare remote file failed"
21655
21656         ln $remote_file $DIR/$tfile || error "link failed for remote file"
21657         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
21658         $CHECKSTAT -t file $remote_file || error "check file failed"
21659 }
21660 run_test 310b "unlink remote file with multiple links while open"
21661
21662 test_310c() {
21663         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21664         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
21665
21666         local remote_file=$DIR/$tdir/tgt_dir/b
21667
21668         mkdir -p $DIR/$tdir
21669
21670         prepare_remote_file || error "prepare remote file failed"
21671
21672         ln $remote_file $DIR/$tfile || error "link failed for remote file"
21673         multiop_bg_pause $remote_file O_uc ||
21674                         error "mulitop failed for remote file"
21675         MULTIPID=$!
21676         $MULTIOP $DIR/$tfile Ouc
21677         kill -USR1 $MULTIPID
21678         wait $MULTIPID
21679 }
21680 run_test 310c "open-unlink remote file with multiple links"
21681
21682 #LU-4825
21683 test_311() {
21684         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21685         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
21686         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
21687                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
21688         remote_mds_nodsh && skip "remote MDS with nodsh"
21689
21690         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
21691         local mdts=$(comma_list $(mdts_nodes))
21692
21693         mkdir -p $DIR/$tdir
21694         $LFS setstripe -i 0 -c 1 $DIR/$tdir
21695         createmany -o $DIR/$tdir/$tfile. 1000
21696
21697         # statfs data is not real time, let's just calculate it
21698         old_iused=$((old_iused + 1000))
21699
21700         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21701                         osp.*OST0000*MDT0000.create_count")
21702         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21703                                 osp.*OST0000*MDT0000.max_create_count")
21704         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
21705
21706         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
21707         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
21708         [ $index -ne 0 ] || error "$tfile stripe index is 0"
21709
21710         unlinkmany $DIR/$tdir/$tfile. 1000
21711
21712         do_nodes $mdts "$LCTL set_param -n \
21713                         osp.*OST0000*.max_create_count=$max_count"
21714         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
21715                 do_nodes $mdts "$LCTL set_param -n \
21716                                 osp.*OST0000*.create_count=$count"
21717         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
21718                         grep "=0" && error "create_count is zero"
21719
21720         local new_iused
21721         for i in $(seq 120); do
21722                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
21723                 # system may be too busy to destroy all objs in time, use
21724                 # a somewhat small value to not fail autotest
21725                 [ $((old_iused - new_iused)) -gt 400 ] && break
21726                 sleep 1
21727         done
21728
21729         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
21730         [ $((old_iused - new_iused)) -gt 400 ] ||
21731                 error "objs not destroyed after unlink"
21732 }
21733 run_test 311 "disable OSP precreate, and unlink should destroy objs"
21734
21735 zfs_oid_to_objid()
21736 {
21737         local ost=$1
21738         local objid=$2
21739
21740         local vdevdir=$(dirname $(facet_vdevice $ost))
21741         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
21742         local zfs_zapid=$(do_facet $ost $cmd |
21743                           grep -w "/O/0/d$((objid%32))" -C 5 |
21744                           awk '/Object/{getline; print $1}')
21745         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
21746                           awk "/$objid = /"'{printf $3}')
21747
21748         echo $zfs_objid
21749 }
21750
21751 zfs_object_blksz() {
21752         local ost=$1
21753         local objid=$2
21754
21755         local vdevdir=$(dirname $(facet_vdevice $ost))
21756         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
21757         local blksz=$(do_facet $ost $cmd $objid |
21758                       awk '/dblk/{getline; printf $4}')
21759
21760         case "${blksz: -1}" in
21761                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
21762                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
21763                 *) ;;
21764         esac
21765
21766         echo $blksz
21767 }
21768
21769 test_312() { # LU-4856
21770         remote_ost_nodsh && skip "remote OST with nodsh"
21771         [ "$ost1_FSTYPE" = "zfs" ] ||
21772                 skip_env "the test only applies to zfs"
21773
21774         local max_blksz=$(do_facet ost1 \
21775                           $ZFS get -p recordsize $(facet_device ost1) |
21776                           awk '!/VALUE/{print $3}')
21777
21778         # to make life a little bit easier
21779         $LFS mkdir -c 1 -i 0 $DIR/$tdir
21780         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21781
21782         local tf=$DIR/$tdir/$tfile
21783         touch $tf
21784         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
21785
21786         # Get ZFS object id
21787         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
21788         # block size change by sequential overwrite
21789         local bs
21790
21791         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
21792                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
21793
21794                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
21795                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
21796         done
21797         rm -f $tf
21798
21799         # block size change by sequential append write
21800         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
21801         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
21802         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
21803         local count
21804
21805         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
21806                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
21807                         oflag=sync conv=notrunc
21808
21809                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
21810                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
21811                         error "blksz error, actual $blksz, " \
21812                                 "expected: 2 * $count * $PAGE_SIZE"
21813         done
21814         rm -f $tf
21815
21816         # random write
21817         touch $tf
21818         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
21819         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
21820
21821         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
21822         blksz=$(zfs_object_blksz ost1 $zfs_objid)
21823         [ $blksz -eq $PAGE_SIZE ] ||
21824                 error "blksz error: $blksz, expected: $PAGE_SIZE"
21825
21826         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
21827         blksz=$(zfs_object_blksz ost1 $zfs_objid)
21828         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
21829
21830         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
21831         blksz=$(zfs_object_blksz ost1 $zfs_objid)
21832         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
21833 }
21834 run_test 312 "make sure ZFS adjusts its block size by write pattern"
21835
21836 test_313() {
21837         remote_ost_nodsh && skip "remote OST with nodsh"
21838
21839         local file=$DIR/$tfile
21840
21841         rm -f $file
21842         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
21843
21844         # define OBD_FAIL_TGT_RCVD_EIO           0x720
21845         do_facet ost1 "$LCTL set_param fail_loc=0x720"
21846         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
21847                 error "write should failed"
21848         do_facet ost1 "$LCTL set_param fail_loc=0"
21849         rm -f $file
21850 }
21851 run_test 313 "io should fail after last_rcvd update fail"
21852
21853 test_314() {
21854         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
21855
21856         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
21857         do_facet ost1 "$LCTL set_param fail_loc=0x720"
21858         rm -f $DIR/$tfile
21859         wait_delete_completed
21860         do_facet ost1 "$LCTL set_param fail_loc=0"
21861 }
21862 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
21863
21864 test_315() { # LU-618
21865         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
21866
21867         local file=$DIR/$tfile
21868         rm -f $file
21869
21870         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
21871                 error "multiop file write failed"
21872         $MULTIOP $file oO_RDONLY:r4063232_c &
21873         PID=$!
21874
21875         sleep 2
21876
21877         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
21878         kill -USR1 $PID
21879
21880         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
21881         rm -f $file
21882 }
21883 run_test 315 "read should be accounted"
21884
21885 test_316() {
21886         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21887         large_xattr_enabled || skip_env "ea_inode feature disabled"
21888
21889         rm -rf $DIR/$tdir/d
21890         mkdir -p $DIR/$tdir/d
21891         chown nobody $DIR/$tdir/d
21892         touch $DIR/$tdir/d/file
21893
21894         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
21895 }
21896 run_test 316 "lfs mv"
21897
21898 test_317() {
21899         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
21900                 skip "Need MDS version at least 2.11.53"
21901         if [ "$ost1_FSTYPE" == "zfs" ]; then
21902                 skip "LU-10370: no implementation for ZFS"
21903         fi
21904
21905         local trunc_sz
21906         local grant_blk_size
21907
21908         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
21909                         awk '/grant_block_size:/ { print $2; exit; }')
21910         #
21911         # Create File of size 5M. Truncate it to below size's and verify
21912         # blocks count.
21913         #
21914         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
21915                 error "Create file $DIR/$tfile failed"
21916         stack_trap "rm -f $DIR/$tfile" EXIT
21917
21918         for trunc_sz in 2097152 4097 4000 509 0; do
21919                 $TRUNCATE $DIR/$tfile $trunc_sz ||
21920                         error "truncate $tfile to $trunc_sz failed"
21921                 local sz=$(stat --format=%s $DIR/$tfile)
21922                 local blk=$(stat --format=%b $DIR/$tfile)
21923                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
21924                                      grant_blk_size) * 8))
21925
21926                 if [[ $blk -ne $trunc_blk ]]; then
21927                         $(which stat) $DIR/$tfile
21928                         error "Expected Block $trunc_blk got $blk for $tfile"
21929                 fi
21930
21931                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
21932                         error "Expected Size $trunc_sz got $sz for $tfile"
21933         done
21934
21935         #
21936         # sparse file test
21937         # Create file with a hole and write actual two blocks. Block count
21938         # must be 16.
21939         #
21940         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
21941                 conv=fsync || error "Create file : $DIR/$tfile"
21942
21943         # Calculate the final truncate size.
21944         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
21945
21946         #
21947         # truncate to size $trunc_sz bytes. Strip the last block
21948         # The block count must drop to 8
21949         #
21950         $TRUNCATE $DIR/$tfile $trunc_sz ||
21951                 error "truncate $tfile to $trunc_sz failed"
21952
21953         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
21954         sz=$(stat --format=%s $DIR/$tfile)
21955         blk=$(stat --format=%b $DIR/$tfile)
21956
21957         if [[ $blk -ne $trunc_bsz ]]; then
21958                 $(which stat) $DIR/$tfile
21959                 error "Expected Block $trunc_bsz got $blk for $tfile"
21960         fi
21961
21962         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
21963                 error "Expected Size $trunc_sz got $sz for $tfile"
21964 }
21965 run_test 317 "Verify blocks get correctly update after truncate"
21966
21967 test_318() {
21968         local old_max_active=$($LCTL get_param -n \
21969                             llite.*.max_read_ahead_async_active 2>/dev/null)
21970
21971         $LCTL set_param llite.*.max_read_ahead_async_active=256
21972         local max_active=$($LCTL get_param -n \
21973                            llite.*.max_read_ahead_async_active 2>/dev/null)
21974         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
21975
21976         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
21977                 error "set max_read_ahead_async_active should succeed"
21978
21979         $LCTL set_param llite.*.max_read_ahead_async_active=512
21980         max_active=$($LCTL get_param -n \
21981                      llite.*.max_read_ahead_async_active 2>/dev/null)
21982         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
21983
21984         # restore @max_active
21985         [ $old_max_active -ne 0 ] && $LCTL set_param \
21986                 llite.*.max_read_ahead_async_active=$old_max_active
21987
21988         local old_threshold=$($LCTL get_param -n \
21989                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
21990         local max_per_file_mb=$($LCTL get_param -n \
21991                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
21992
21993         local invalid=$(($max_per_file_mb + 1))
21994         $LCTL set_param \
21995                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
21996                         && error "set $invalid should fail"
21997
21998         local valid=$(($invalid - 1))
21999         $LCTL set_param \
22000                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
22001                         error "set $valid should succeed"
22002         local threshold=$($LCTL get_param -n \
22003                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
22004         [ $threshold -eq $valid ] || error \
22005                 "expect threshold $valid got $threshold"
22006         $LCTL set_param \
22007                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
22008 }
22009 run_test 318 "Verify async readahead tunables"
22010
22011 test_319() {
22012         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
22013
22014         local before=$(date +%s)
22015         local evict
22016         local mdir=$DIR/$tdir
22017         local file=$mdir/xxx
22018
22019         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
22020         touch $file
22021
22022 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
22023         $LCTL set_param fail_val=5 fail_loc=0x8000032c
22024         $LFS mv -m1 $file &
22025
22026         sleep 1
22027         dd if=$file of=/dev/null
22028         wait
22029         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
22030           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
22031
22032         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
22033 }
22034 run_test 319 "lost lease lock on migrate error"
22035
22036 test_398a() { # LU-4198
22037         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22038         $LCTL set_param ldlm.namespaces.*.lru_size=clear
22039
22040         # request a new lock on client
22041         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22042
22043         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
22044         local lock_count=$($LCTL get_param -n \
22045                            ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
22046         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
22047
22048         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
22049
22050         # no lock cached, should use lockless IO and not enqueue new lock
22051         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
22052         lock_count=$($LCTL get_param -n \
22053                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
22054         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
22055 }
22056 run_test 398a "direct IO should cancel lock otherwise lockless"
22057
22058 test_398b() { # LU-4198
22059         which fio || skip_env "no fio installed"
22060         $LFS setstripe -c -1 $DIR/$tfile
22061
22062         local size=12
22063         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
22064
22065         local njobs=4
22066         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
22067         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
22068                 --numjobs=$njobs --fallocate=none \
22069                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22070                 --filename=$DIR/$tfile &
22071         bg_pid=$!
22072
22073         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
22074         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
22075                 --numjobs=$njobs --fallocate=none \
22076                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22077                 --filename=$DIR/$tfile || true
22078         wait $bg_pid
22079
22080         rm -rf $DIR/$tfile
22081 }
22082 run_test 398b "DIO and buffer IO race"
22083
22084 test_398c() { # LU-4198
22085         which fio || skip_env "no fio installed"
22086
22087         saved_debug=$($LCTL get_param -n debug)
22088         $LCTL set_param debug=0
22089
22090         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
22091         ((size /= 1024)) # by megabytes
22092         ((size /= 2)) # write half of the OST at most
22093         [ $size -gt 40 ] && size=40 #reduce test time anyway
22094
22095         $LFS setstripe -c 1 $DIR/$tfile
22096
22097         # it seems like ldiskfs reserves more space than necessary if the
22098         # writing blocks are not mapped, so it extends the file firstly
22099         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
22100         cancel_lru_locks osc
22101
22102         # clear and verify rpc_stats later
22103         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
22104
22105         local njobs=4
22106         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
22107         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
22108                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
22109                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22110                 --filename=$DIR/$tfile
22111         [ $? -eq 0 ] || error "fio write error"
22112
22113         [ $($LCTL get_param -n \
22114          ldlm.namespaces.${FSNAME}-OST0000-osc-ffff*.lock_count) -eq 0 ] ||
22115                 error "Locks were requested while doing AIO"
22116
22117         # get the percentage of 1-page I/O
22118         pct=$($LCTL get_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats |
22119                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
22120                 awk '{print $7}')
22121         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
22122
22123         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
22124         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
22125                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
22126                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22127                 --filename=$DIR/$tfile
22128         [ $? -eq 0 ] || error "fio mixed read write error"
22129
22130         echo "AIO with large block size ${size}M"
22131         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
22132                 --numjobs=1 --fallocate=none --ioengine=libaio \
22133                 --iodepth=16 --allow_file_create=0 --size=${size}M \
22134                 --filename=$DIR/$tfile
22135         [ $? -eq 0 ] || error "fio large block size failed"
22136
22137         rm -rf $DIR/$tfile
22138         $LCTL set_param debug="$saved_debug"
22139 }
22140 run_test 398c "run fio to test AIO"
22141
22142 test_398d() { #  LU-13846
22143         test -f aiocp || skip_env "no aiocp installed"
22144         local aio_file=$DIR/aio_file
22145
22146         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
22147
22148         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
22149         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
22150
22151         diff $DIR/$tfile $aio_file || "file diff after aiocp"
22152
22153         # make sure we don't crash and fail properly
22154         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
22155                 error "aio not aligned with PAGE SIZE should fail"
22156
22157         rm -rf $DIR/$tfile $aio_file
22158 }
22159 run_test 398d "run aiocp to verify block size > stripe size"
22160
22161 test_fake_rw() {
22162         local read_write=$1
22163         if [ "$read_write" = "write" ]; then
22164                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
22165         elif [ "$read_write" = "read" ]; then
22166                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
22167         else
22168                 error "argument error"
22169         fi
22170
22171         # turn off debug for performance testing
22172         local saved_debug=$($LCTL get_param -n debug)
22173         $LCTL set_param debug=0
22174
22175         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22176
22177         # get ost1 size - $FSNAME-OST0000
22178         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
22179         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
22180         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
22181
22182         if [ "$read_write" = "read" ]; then
22183                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
22184         fi
22185
22186         local start_time=$(date +%s.%N)
22187         $dd_cmd bs=1M count=$blocks oflag=sync ||
22188                 error "real dd $read_write error"
22189         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
22190
22191         if [ "$read_write" = "write" ]; then
22192                 rm -f $DIR/$tfile
22193         fi
22194
22195         # define OBD_FAIL_OST_FAKE_RW           0x238
22196         do_facet ost1 $LCTL set_param fail_loc=0x238
22197
22198         local start_time=$(date +%s.%N)
22199         $dd_cmd bs=1M count=$blocks oflag=sync ||
22200                 error "fake dd $read_write error"
22201         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
22202
22203         if [ "$read_write" = "write" ]; then
22204                 # verify file size
22205                 cancel_lru_locks osc
22206                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
22207                         error "$tfile size not $blocks MB"
22208         fi
22209         do_facet ost1 $LCTL set_param fail_loc=0
22210
22211         echo "fake $read_write $duration_fake vs. normal $read_write" \
22212                 "$duration in seconds"
22213         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
22214                 error_not_in_vm "fake write is slower"
22215
22216         $LCTL set_param -n debug="$saved_debug"
22217         rm -f $DIR/$tfile
22218 }
22219 test_399a() { # LU-7655 for OST fake write
22220         remote_ost_nodsh && skip "remote OST with nodsh"
22221
22222         test_fake_rw write
22223 }
22224 run_test 399a "fake write should not be slower than normal write"
22225
22226 test_399b() { # LU-8726 for OST fake read
22227         remote_ost_nodsh && skip "remote OST with nodsh"
22228         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
22229                 skip_env "ldiskfs only test"
22230         fi
22231
22232         test_fake_rw read
22233 }
22234 run_test 399b "fake read should not be slower than normal read"
22235
22236 test_400a() { # LU-1606, was conf-sanity test_74
22237         if ! which $CC > /dev/null 2>&1; then
22238                 skip_env "$CC is not installed"
22239         fi
22240
22241         local extra_flags=''
22242         local out=$TMP/$tfile
22243         local prefix=/usr/include/lustre
22244         local prog
22245
22246         # Oleg removes c files in his test rig so test if any c files exist
22247         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
22248                 skip_env "Needed c test files are missing"
22249
22250         if ! [[ -d $prefix ]]; then
22251                 # Assume we're running in tree and fixup the include path.
22252                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
22253                 extra_flags+=" -L$LUSTRE/utils/.lib"
22254         fi
22255
22256         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
22257                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
22258                         error "client api broken"
22259         done
22260         rm -f $out
22261 }
22262 run_test 400a "Lustre client api program can compile and link"
22263
22264 test_400b() { # LU-1606, LU-5011
22265         local header
22266         local out=$TMP/$tfile
22267         local prefix=/usr/include/linux/lustre
22268
22269         # We use a hard coded prefix so that this test will not fail
22270         # when run in tree. There are headers in lustre/include/lustre/
22271         # that are not packaged (like lustre_idl.h) and have more
22272         # complicated include dependencies (like config.h and lnet/types.h).
22273         # Since this test about correct packaging we just skip them when
22274         # they don't exist (see below) rather than try to fixup cppflags.
22275
22276         if ! which $CC > /dev/null 2>&1; then
22277                 skip_env "$CC is not installed"
22278         fi
22279
22280         for header in $prefix/*.h; do
22281                 if ! [[ -f "$header" ]]; then
22282                         continue
22283                 fi
22284
22285                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
22286                         continue # lustre_ioctl.h is internal header
22287                 fi
22288
22289                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
22290                         error "cannot compile '$header'"
22291         done
22292         rm -f $out
22293 }
22294 run_test 400b "packaged headers can be compiled"
22295
22296 test_401a() { #LU-7437
22297         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
22298         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
22299
22300         #count the number of parameters by "list_param -R"
22301         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
22302         #count the number of parameters by listing proc files
22303         local proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
22304         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
22305         echo "proc_dirs='$proc_dirs'"
22306         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
22307         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
22308                       sort -u | wc -l)
22309
22310         [ $params -eq $procs ] ||
22311                 error "found $params parameters vs. $procs proc files"
22312
22313         # test the list_param -D option only returns directories
22314         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
22315         #count the number of parameters by listing proc directories
22316         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
22317                 sort -u | wc -l)
22318
22319         [ $params -eq $procs ] ||
22320                 error "found $params parameters vs. $procs proc files"
22321 }
22322 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
22323
22324 test_401b() {
22325         # jobid_var may not allow arbitrary values, so use jobid_name
22326         # if available
22327         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22328                 local testname=jobid_name tmp='testing%p'
22329         else
22330                 local testname=jobid_var tmp=testing
22331         fi
22332
22333         local save=$($LCTL get_param -n $testname)
22334
22335         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
22336                 error "no error returned when setting bad parameters"
22337
22338         local jobid_new=$($LCTL get_param -n foe $testname baz)
22339         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
22340
22341         $LCTL set_param -n fog=bam $testname=$save bat=fog
22342         local jobid_old=$($LCTL get_param -n foe $testname bag)
22343         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
22344 }
22345 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
22346
22347 test_401c() {
22348         # jobid_var may not allow arbitrary values, so use jobid_name
22349         # if available
22350         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22351                 local testname=jobid_name
22352         else
22353                 local testname=jobid_var
22354         fi
22355
22356         local jobid_var_old=$($LCTL get_param -n $testname)
22357         local jobid_var_new
22358
22359         $LCTL set_param $testname= &&
22360                 error "no error returned for 'set_param a='"
22361
22362         jobid_var_new=$($LCTL get_param -n $testname)
22363         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
22364                 error "$testname was changed by setting without value"
22365
22366         $LCTL set_param $testname &&
22367                 error "no error returned for 'set_param a'"
22368
22369         jobid_var_new=$($LCTL get_param -n $testname)
22370         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
22371                 error "$testname was changed by setting without value"
22372 }
22373 run_test 401c "Verify 'lctl set_param' without value fails in either format."
22374
22375 test_401d() {
22376         # jobid_var may not allow arbitrary values, so use jobid_name
22377         # if available
22378         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22379                 local testname=jobid_name new_value='foo=bar%p'
22380         else
22381                 local testname=jobid_var new_valuie=foo=bar
22382         fi
22383
22384         local jobid_var_old=$($LCTL get_param -n $testname)
22385         local jobid_var_new
22386
22387         $LCTL set_param $testname=$new_value ||
22388                 error "'set_param a=b' did not accept a value containing '='"
22389
22390         jobid_var_new=$($LCTL get_param -n $testname)
22391         [[ "$jobid_var_new" == "$new_value" ]] ||
22392                 error "'set_param a=b' failed on a value containing '='"
22393
22394         # Reset the $testname to test the other format
22395         $LCTL set_param $testname=$jobid_var_old
22396         jobid_var_new=$($LCTL get_param -n $testname)
22397         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
22398                 error "failed to reset $testname"
22399
22400         $LCTL set_param $testname $new_value ||
22401                 error "'set_param a b' did not accept a value containing '='"
22402
22403         jobid_var_new=$($LCTL get_param -n $testname)
22404         [[ "$jobid_var_new" == "$new_value" ]] ||
22405                 error "'set_param a b' failed on a value containing '='"
22406
22407         $LCTL set_param $testname $jobid_var_old
22408         jobid_var_new=$($LCTL get_param -n $testname)
22409         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
22410                 error "failed to reset $testname"
22411 }
22412 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
22413
22414 test_402() {
22415         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
22416         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
22417                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
22418         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
22419                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
22420                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
22421         remote_mds_nodsh && skip "remote MDS with nodsh"
22422
22423         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
22424 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
22425         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
22426         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
22427                 echo "Touch failed - OK"
22428 }
22429 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
22430
22431 test_403() {
22432         local file1=$DIR/$tfile.1
22433         local file2=$DIR/$tfile.2
22434         local tfile=$TMP/$tfile
22435
22436         rm -f $file1 $file2 $tfile
22437
22438         touch $file1
22439         ln $file1 $file2
22440
22441         # 30 sec OBD_TIMEOUT in ll_getattr()
22442         # right before populating st_nlink
22443         $LCTL set_param fail_loc=0x80001409
22444         stat -c %h $file1 > $tfile &
22445
22446         # create an alias, drop all locks and reclaim the dentry
22447         < $file2
22448         cancel_lru_locks mdc
22449         cancel_lru_locks osc
22450         sysctl -w vm.drop_caches=2
22451
22452         wait
22453
22454         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
22455
22456         rm -f $tfile $file1 $file2
22457 }
22458 run_test 403 "i_nlink should not drop to zero due to aliasing"
22459
22460 test_404() { # LU-6601
22461         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
22462                 skip "Need server version newer than 2.8.52"
22463         remote_mds_nodsh && skip "remote MDS with nodsh"
22464
22465         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
22466                 awk '/osp .*-osc-MDT/ { print $4}')
22467
22468         local osp
22469         for osp in $mosps; do
22470                 echo "Deactivate: " $osp
22471                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
22472                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
22473                         awk -vp=$osp '$4 == p { print $2 }')
22474                 [ $stat = IN ] || {
22475                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
22476                         error "deactivate error"
22477                 }
22478                 echo "Activate: " $osp
22479                 do_facet $SINGLEMDS $LCTL --device %$osp activate
22480                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
22481                         awk -vp=$osp '$4 == p { print $2 }')
22482                 [ $stat = UP ] || {
22483                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
22484                         error "activate error"
22485                 }
22486         done
22487 }
22488 run_test 404 "validate manual {de}activated works properly for OSPs"
22489
22490 test_405() {
22491         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
22492         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
22493                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
22494                         skip "Layout swap lock is not supported"
22495
22496         check_swap_layouts_support
22497         check_swap_layout_no_dom $DIR
22498
22499         test_mkdir $DIR/$tdir
22500         swap_lock_test -d $DIR/$tdir ||
22501                 error "One layout swap locked test failed"
22502 }
22503 run_test 405 "Various layout swap lock tests"
22504
22505 test_406() {
22506         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22507         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
22508         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
22509         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22510         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
22511                 skip "Need MDS version at least 2.8.50"
22512
22513         local def_stripe_size=$($LFS getstripe -S $MOUNT)
22514         local test_pool=$TESTNAME
22515
22516         pool_add $test_pool || error "pool_add failed"
22517         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
22518                 error "pool_add_targets failed"
22519
22520         save_layout_restore_at_exit $MOUNT
22521
22522         # parent set default stripe count only, child will stripe from both
22523         # parent and fs default
22524         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
22525                 error "setstripe $MOUNT failed"
22526         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
22527         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
22528         for i in $(seq 10); do
22529                 local f=$DIR/$tdir/$tfile.$i
22530                 touch $f || error "touch failed"
22531                 local count=$($LFS getstripe -c $f)
22532                 [ $count -eq $OSTCOUNT ] ||
22533                         error "$f stripe count $count != $OSTCOUNT"
22534                 local offset=$($LFS getstripe -i $f)
22535                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
22536                 local size=$($LFS getstripe -S $f)
22537                 [ $size -eq $((def_stripe_size * 2)) ] ||
22538                         error "$f stripe size $size != $((def_stripe_size * 2))"
22539                 local pool=$($LFS getstripe -p $f)
22540                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
22541         done
22542
22543         # change fs default striping, delete parent default striping, now child
22544         # will stripe from new fs default striping only
22545         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
22546                 error "change $MOUNT default stripe failed"
22547         $LFS setstripe -c 0 $DIR/$tdir ||
22548                 error "delete $tdir default stripe failed"
22549         for i in $(seq 11 20); do
22550                 local f=$DIR/$tdir/$tfile.$i
22551                 touch $f || error "touch $f failed"
22552                 local count=$($LFS getstripe -c $f)
22553                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
22554                 local offset=$($LFS getstripe -i $f)
22555                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
22556                 local size=$($LFS getstripe -S $f)
22557                 [ $size -eq $def_stripe_size ] ||
22558                         error "$f stripe size $size != $def_stripe_size"
22559                 local pool=$($LFS getstripe -p $f)
22560                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
22561         done
22562
22563         unlinkmany $DIR/$tdir/$tfile. 1 20
22564
22565         local f=$DIR/$tdir/$tfile
22566         pool_remove_all_targets $test_pool $f
22567         pool_remove $test_pool $f
22568 }
22569 run_test 406 "DNE support fs default striping"
22570
22571 test_407() {
22572         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22573         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
22574                 skip "Need MDS version at least 2.8.55"
22575         remote_mds_nodsh && skip "remote MDS with nodsh"
22576
22577         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
22578                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
22579         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
22580                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
22581         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
22582
22583         #define OBD_FAIL_DT_TXN_STOP    0x2019
22584         for idx in $(seq $MDSCOUNT); do
22585                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
22586         done
22587         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
22588         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
22589                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
22590         true
22591 }
22592 run_test 407 "transaction fail should cause operation fail"
22593
22594 test_408() {
22595         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
22596
22597         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
22598         lctl set_param fail_loc=0x8000040a
22599         # let ll_prepare_partial_page() fail
22600         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
22601
22602         rm -f $DIR/$tfile
22603
22604         # create at least 100 unused inodes so that
22605         # shrink_icache_memory(0) should not return 0
22606         touch $DIR/$tfile-{0..100}
22607         rm -f $DIR/$tfile-{0..100}
22608         sync
22609
22610         echo 2 > /proc/sys/vm/drop_caches
22611 }
22612 run_test 408 "drop_caches should not hang due to page leaks"
22613
22614 test_409()
22615 {
22616         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22617
22618         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
22619         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
22620         touch $DIR/$tdir/guard || error "(2) Fail to create"
22621
22622         local PREFIX=$(str_repeat 'A' 128)
22623         echo "Create 1K hard links start at $(date)"
22624         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
22625                 error "(3) Fail to hard link"
22626
22627         echo "Links count should be right although linkEA overflow"
22628         stat $DIR/$tdir/guard || error "(4) Fail to stat"
22629         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
22630         [ $linkcount -eq 1001 ] ||
22631                 error "(5) Unexpected hard links count: $linkcount"
22632
22633         echo "List all links start at $(date)"
22634         ls -l $DIR/$tdir/foo > /dev/null ||
22635                 error "(6) Fail to list $DIR/$tdir/foo"
22636
22637         echo "Unlink hard links start at $(date)"
22638         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
22639                 error "(7) Fail to unlink"
22640         echo "Unlink hard links finished at $(date)"
22641 }
22642 run_test 409 "Large amount of cross-MDTs hard links on the same file"
22643
22644 test_410()
22645 {
22646         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
22647                 skip "Need client version at least 2.9.59"
22648         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
22649                 skip "Need MODULES build"
22650
22651         # Create a file, and stat it from the kernel
22652         local testfile=$DIR/$tfile
22653         touch $testfile
22654
22655         local run_id=$RANDOM
22656         local my_ino=$(stat --format "%i" $testfile)
22657
22658         # Try to insert the module. This will always fail as the
22659         # module is designed to not be inserted.
22660         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
22661             &> /dev/null
22662
22663         # Anything but success is a test failure
22664         dmesg | grep -q \
22665             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
22666             error "no inode match"
22667 }
22668 run_test 410 "Test inode number returned from kernel thread"
22669
22670 cleanup_test411_cgroup() {
22671         trap 0
22672         rmdir "$1"
22673 }
22674
22675 test_411() {
22676         local cg_basedir=/sys/fs/cgroup/memory
22677         # LU-9966
22678         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
22679                 skip "no setup for cgroup"
22680
22681         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
22682                 error "test file creation failed"
22683         cancel_lru_locks osc
22684
22685         # Create a very small memory cgroup to force a slab allocation error
22686         local cgdir=$cg_basedir/osc_slab_alloc
22687         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
22688         trap "cleanup_test411_cgroup $cgdir" EXIT
22689         echo 2M > $cgdir/memory.kmem.limit_in_bytes
22690         echo 1M > $cgdir/memory.limit_in_bytes
22691
22692         # Should not LBUG, just be killed by oom-killer
22693         # dd will return 0 even allocation failure in some environment.
22694         # So don't check return value
22695         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
22696         cleanup_test411_cgroup $cgdir
22697
22698         return 0
22699 }
22700 run_test 411 "Slab allocation error with cgroup does not LBUG"
22701
22702 test_412() {
22703         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22704         if [ $MDS1_VERSION -lt $(version_code 2.10.55) ]; then
22705                 skip "Need server version at least 2.10.55"
22706         fi
22707
22708         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
22709                 error "mkdir failed"
22710         $LFS getdirstripe $DIR/$tdir
22711         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
22712         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
22713                 error "expect $((MDSCOUT - 1)) get $stripe_index"
22714         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
22715         [ $stripe_count -eq 2 ] ||
22716                 error "expect 2 get $stripe_count"
22717 }
22718 run_test 412 "mkdir on specific MDTs"
22719
22720 test_qos_mkdir() {
22721         local mkdir_cmd=$1
22722         local stripe_count=$2
22723         local mdts=$(comma_list $(mdts_nodes))
22724
22725         local testdir
22726         local lmv_qos_prio_free
22727         local lmv_qos_threshold_rr
22728         local lmv_qos_maxage
22729         local lod_qos_prio_free
22730         local lod_qos_threshold_rr
22731         local lod_qos_maxage
22732         local count
22733         local i
22734
22735         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
22736         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
22737         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
22738                 head -n1)
22739         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
22740         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
22741         stack_trap "$LCTL set_param \
22742                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null" EXIT
22743         stack_trap "$LCTL set_param \
22744                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
22745         stack_trap "$LCTL set_param \
22746                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" EXIT
22747
22748         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
22749                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
22750         lod_qos_prio_free=${lod_qos_prio_free%%%}
22751         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
22752                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
22753         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
22754         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
22755                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
22756         stack_trap "do_nodes $mdts $LCTL set_param \
22757                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null" EXIT
22758         stack_trap "do_nodes $mdts $LCTL set_param \
22759                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null" \
22760                 EXIT
22761         stack_trap "do_nodes $mdts $LCTL set_param \
22762                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" EXIT
22763
22764         echo
22765         echo "Mkdir (stripe_count $stripe_count) roundrobin:"
22766
22767         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
22768         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
22769
22770         testdir=$DIR/$tdir-s$stripe_count/rr
22771
22772         for i in $(seq $((100 * MDSCOUNT))); do
22773                 eval $mkdir_cmd $testdir/subdir$i ||
22774                         error "$mkdir_cmd subdir$i failed"
22775         done
22776
22777         for i in $(seq $MDSCOUNT); do
22778                 count=$($LFS getdirstripe -i $testdir/* |
22779                                 grep ^$((i - 1))$ | wc -l)
22780                 echo "$count directories created on MDT$((i - 1))"
22781                 [ $count -eq 100 ] || error "subdirs are not evenly distributed"
22782
22783                 if [ $stripe_count -gt 1 ]; then
22784                         count=$($LFS getdirstripe $testdir/* |
22785                                 grep -P "^\s+$((i - 1))\t" | wc -l)
22786                         echo "$count stripes created on MDT$((i - 1))"
22787                         # deviation should < 5% of average
22788                         [ $count -lt $((95 * stripe_count)) ] ||
22789                         [ $count -gt $((105 * stripe_count)) ] &&
22790                                 error "stripes are not evenly distributed"
22791                 fi
22792         done
22793
22794         $LCTL set_param lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null
22795         do_nodes $mdts $LCTL set_param \
22796                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null
22797
22798         echo
22799         echo "Check for uneven MDTs: "
22800
22801         local ffree
22802         local bavail
22803         local max
22804         local min
22805         local max_index
22806         local min_index
22807         local tmp
22808
22809         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
22810         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
22811         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
22812
22813         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
22814         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
22815         max_index=0
22816         min_index=0
22817         for ((i = 1; i < ${#ffree[@]}; i++)); do
22818                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
22819                 if [ $tmp -gt $max ]; then
22820                         max=$tmp
22821                         max_index=$i
22822                 fi
22823                 if [ $tmp -lt $min ]; then
22824                         min=$tmp
22825                         min_index=$i
22826                 fi
22827         done
22828
22829         [ ${ffree[min_index]} -eq 0 ] &&
22830                 skip "no free files in MDT$min_index"
22831         [ ${ffree[min_index]} -gt 100000000 ] &&
22832                 skip "too much free files in MDT$min_index"
22833
22834         # Check if we need to generate uneven MDTs
22835         local threshold=50
22836         local diff=$(((max - min) * 100 / min))
22837         local value="$(generate_string 1024)"
22838
22839         while [ $diff -lt $threshold ]; do
22840                 # generate uneven MDTs, create till $threshold% diff
22841                 echo -n "weight diff=$diff% must be > $threshold% ..."
22842                 count=$((${ffree[min_index]} / 10))
22843                 # 50 sec per 10000 files in vm
22844                 [ $count -gt 40000 ] && [ "$SLOW" = "no" ] &&
22845                         skip "$count files to create"
22846                 echo "Fill MDT$min_index with $count files"
22847                 [ -d $DIR/$tdir-MDT$min_index ] ||
22848                         $LFS mkdir -i $min_index $DIR/$tdir-MDT$min_index ||
22849                         error "mkdir $tdir-MDT$min_index failed"
22850                 for i in $(seq $count); do
22851                         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE \
22852                                 $DIR/$tdir-MDT$min_index/f$j_$i > /dev/null ||
22853                                 error "create f$j_$i failed"
22854                         setfattr -n user.413b -v $value \
22855                                 $DIR/$tdir-MDT$min_index/f$j_$i ||
22856                                 error "setfattr f$j_$i failed"
22857                 done
22858
22859                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
22860                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
22861                 max=$(((${ffree[max_index]} >> 8) * \
22862                         (${bavail[max_index]} * bsize >> 16)))
22863                 min=$(((${ffree[min_index]} >> 8) * \
22864                         (${bavail[min_index]} * bsize >> 16)))
22865                 diff=$(((max - min) * 100 / min))
22866         done
22867
22868         echo "MDT filesfree available: ${ffree[@]}"
22869         echo "MDT blocks available: ${bavail[@]}"
22870         echo "weight diff=$diff%"
22871
22872         echo
22873         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
22874
22875         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
22876         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
22877         # decrease statfs age, so that it can be updated in time
22878         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
22879         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
22880
22881         sleep 1
22882
22883         testdir=$DIR/$tdir-s$stripe_count/qos
22884
22885         for i in $(seq $((100 * MDSCOUNT))); do
22886                 eval $mkdir_cmd $testdir/subdir$i ||
22887                         error "$mkdir_cmd subdir$i failed"
22888         done
22889
22890         for i in $(seq $MDSCOUNT); do
22891                 count=$($LFS getdirstripe -i $testdir/* | grep ^$((i - 1))$ |
22892                         wc -l)
22893                 echo "$count directories created on MDT$((i - 1))"
22894
22895                 if [ $stripe_count -gt 1 ]; then
22896                         count=$($LFS getdirstripe $testdir/* |
22897                                 grep -P "^\s+$((i - 1))\t" | wc -l)
22898                         echo "$count stripes created on MDT$((i - 1))"
22899                 fi
22900         done
22901
22902         max=$($LFS getdirstripe -i $testdir/* | grep ^$max_index$ | wc -l)
22903         min=$($LFS getdirstripe -i $testdir/* | grep ^$min_index$ | wc -l)
22904
22905         # D-value should > 10% of averge
22906         [ $((max - min)) -lt 10 ] &&
22907                 error "subdirs shouldn't be evenly distributed"
22908
22909         # ditto
22910         if [ $stripe_count -gt 1 ]; then
22911                 max=$($LFS getdirstripe $testdir/* |
22912                         grep -P "^\s+$max_index\t" | wc -l)
22913                 min=$($LFS getdirstripe $testdir/* |
22914                         grep -P "^\s+$min_index\t" | wc -l)
22915                 [ $((max - min)) -le $((10 * stripe_count)) ] &&
22916                         error "stripes shouldn't be evenly distributed"|| true
22917         fi
22918 }
22919
22920 test_413a() {
22921         [ $MDSCOUNT -lt 2 ] &&
22922                 skip "We need at least 2 MDTs for this test"
22923
22924         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
22925                 skip "Need server version at least 2.12.52"
22926
22927         local stripe_count
22928
22929         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
22930                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
22931                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
22932                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
22933                 test_qos_mkdir "$LFS mkdir -c $stripe_count" $stripe_count
22934         done
22935 }
22936 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
22937
22938 test_413b() {
22939         [ $MDSCOUNT -lt 2 ] &&
22940                 skip "We need at least 2 MDTs for this test"
22941
22942         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
22943                 skip "Need server version at least 2.12.52"
22944
22945         local stripe_count
22946
22947         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
22948                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
22949                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
22950                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
22951                 $LFS setdirstripe -D -c $stripe_count \
22952                         $DIR/$tdir-s$stripe_count/rr ||
22953                         error "setdirstripe failed"
22954                 $LFS setdirstripe -D -c $stripe_count \
22955                         $DIR/$tdir-s$stripe_count/qos ||
22956                         error "setdirstripe failed"
22957                 test_qos_mkdir "mkdir" $stripe_count
22958         done
22959 }
22960 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
22961
22962 test_414() {
22963 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
22964         $LCTL set_param fail_loc=0x80000521
22965         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
22966         rm -f $DIR/$tfile
22967 }
22968 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
22969
22970 test_415() {
22971         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22972         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22973                 skip "Need server version at least 2.11.52"
22974
22975         # LU-11102
22976         local total
22977         local setattr_pid
22978         local start_time
22979         local end_time
22980         local duration
22981
22982         total=500
22983         # this test may be slow on ZFS
22984         [ "$mds1_FSTYPE" == "zfs" ] && total=100
22985
22986         # though this test is designed for striped directory, let's test normal
22987         # directory too since lock is always saved as CoS lock.
22988         test_mkdir $DIR/$tdir || error "mkdir $tdir"
22989         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
22990
22991         (
22992                 while true; do
22993                         touch $DIR/$tdir
22994                 done
22995         ) &
22996         setattr_pid=$!
22997
22998         start_time=$(date +%s)
22999         for i in $(seq $total); do
23000                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
23001                         > /dev/null
23002         done
23003         end_time=$(date +%s)
23004         duration=$((end_time - start_time))
23005
23006         kill -9 $setattr_pid
23007
23008         echo "rename $total files took $duration sec"
23009         [ $duration -lt 100 ] || error "rename took $duration sec"
23010 }
23011 run_test 415 "lock revoke is not missing"
23012
23013 test_416() {
23014         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
23015                 skip "Need server version at least 2.11.55"
23016
23017         # define OBD_FAIL_OSD_TXN_START    0x19a
23018         do_facet mds1 lctl set_param fail_loc=0x19a
23019
23020         lfs mkdir -c $MDSCOUNT $DIR/$tdir
23021
23022         true
23023 }
23024 run_test 416 "transaction start failure won't cause system hung"
23025
23026 cleanup_417() {
23027         trap 0
23028         do_nodes $(comma_list $(mdts_nodes)) \
23029                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
23030         do_nodes $(comma_list $(mdts_nodes)) \
23031                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
23032         do_nodes $(comma_list $(mdts_nodes)) \
23033                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
23034 }
23035
23036 test_417() {
23037         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23038         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
23039                 skip "Need MDS version at least 2.11.56"
23040
23041         trap cleanup_417 RETURN EXIT
23042
23043         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
23044         do_nodes $(comma_list $(mdts_nodes)) \
23045                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
23046         $LFS migrate -m 0 $DIR/$tdir.1 &&
23047                 error "migrate dir $tdir.1 should fail"
23048
23049         do_nodes $(comma_list $(mdts_nodes)) \
23050                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
23051         $LFS mkdir -i 1 $DIR/$tdir.2 &&
23052                 error "create remote dir $tdir.2 should fail"
23053
23054         do_nodes $(comma_list $(mdts_nodes)) \
23055                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
23056         $LFS mkdir -c 2 $DIR/$tdir.3 &&
23057                 error "create striped dir $tdir.3 should fail"
23058         true
23059 }
23060 run_test 417 "disable remote dir, striped dir and dir migration"
23061
23062 # Checks that the outputs of df [-i] and lfs df [-i] match
23063 #
23064 # usage: check_lfs_df <blocks | inodes> <mountpoint>
23065 check_lfs_df() {
23066         local dir=$2
23067         local inodes
23068         local df_out
23069         local lfs_df_out
23070         local count
23071         local passed=false
23072
23073         # blocks or inodes
23074         [ "$1" == "blocks" ] && inodes= || inodes="-i"
23075
23076         for count in {1..100}; do
23077                 cancel_lru_locks
23078                 sync; sleep 0.2
23079
23080                 # read the lines of interest
23081                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
23082                         error "df $inodes $dir | tail -n +2 failed"
23083                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
23084                         error "lfs df $inodes $dir | grep summary: failed"
23085
23086                 # skip first substrings of each output as they are different
23087                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
23088                 # compare the two outputs
23089                 passed=true
23090                 for i in {1..5}; do
23091                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
23092                 done
23093                 $passed && break
23094         done
23095
23096         if ! $passed; then
23097                 df -P $inodes $dir
23098                 echo
23099                 lfs df $inodes $dir
23100                 error "df and lfs df $1 output mismatch: "      \
23101                       "df ${inodes}: ${df_out[*]}, "            \
23102                       "lfs df ${inodes}: ${lfs_df_out[*]}"
23103         fi
23104 }
23105
23106 test_418() {
23107         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23108
23109         local dir=$DIR/$tdir
23110         local numfiles=$((RANDOM % 4096 + 2))
23111         local numblocks=$((RANDOM % 256 + 1))
23112
23113         wait_delete_completed
23114         test_mkdir $dir
23115
23116         # check block output
23117         check_lfs_df blocks $dir
23118         # check inode output
23119         check_lfs_df inodes $dir
23120
23121         # create a single file and retest
23122         echo "Creating a single file and testing"
23123         createmany -o $dir/$tfile- 1 &>/dev/null ||
23124                 error "creating 1 file in $dir failed"
23125         check_lfs_df blocks $dir
23126         check_lfs_df inodes $dir
23127
23128         # create a random number of files
23129         echo "Creating $((numfiles - 1)) files and testing"
23130         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
23131                 error "creating $((numfiles - 1)) files in $dir failed"
23132
23133         # write a random number of blocks to the first test file
23134         echo "Writing $numblocks 4K blocks and testing"
23135         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
23136                 count=$numblocks &>/dev/null ||
23137                 error "dd to $dir/${tfile}-0 failed"
23138
23139         # retest
23140         check_lfs_df blocks $dir
23141         check_lfs_df inodes $dir
23142
23143         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
23144                 error "unlinking $numfiles files in $dir failed"
23145 }
23146 run_test 418 "df and lfs df outputs match"
23147
23148 test_419()
23149 {
23150         local dir=$DIR/$tdir
23151
23152         mkdir -p $dir
23153         touch $dir/file
23154
23155         cancel_lru_locks mdc
23156
23157         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
23158         $LCTL set_param fail_loc=0x1410
23159         cat $dir/file
23160         $LCTL set_param fail_loc=0
23161         rm -rf $dir
23162 }
23163 run_test 419 "Verify open file by name doesn't crash kernel"
23164
23165 test_420()
23166 {
23167         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
23168                 skip "Need MDS version at least 2.12.53"
23169
23170         local SAVE_UMASK=$(umask)
23171         local dir=$DIR/$tdir
23172         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
23173
23174         mkdir -p $dir
23175         umask 0000
23176         mkdir -m03777 $dir/testdir
23177         ls -dn $dir/testdir
23178         # Need to remove trailing '.' when SELinux is enabled
23179         local dirperms=$(ls -dn $dir/testdir |
23180                          awk '{ sub(/\.$/, "", $1); print $1}')
23181         [ $dirperms == "drwxrwsrwt" ] ||
23182                 error "incorrect perms on $dir/testdir"
23183
23184         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
23185                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
23186         ls -n $dir/testdir/testfile
23187         local fileperms=$(ls -n $dir/testdir/testfile |
23188                           awk '{ sub(/\.$/, "", $1); print $1}')
23189         [ $fileperms == "-rwxr-xr-x" ] ||
23190                 error "incorrect perms on $dir/testdir/testfile"
23191
23192         umask $SAVE_UMASK
23193 }
23194 run_test 420 "clear SGID bit on non-directories for non-members"
23195
23196 test_421a() {
23197         local cnt
23198         local fid1
23199         local fid2
23200
23201         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23202                 skip "Need MDS version at least 2.12.54"
23203
23204         test_mkdir $DIR/$tdir
23205         createmany -o $DIR/$tdir/f 3
23206         cnt=$(ls -1 $DIR/$tdir | wc -l)
23207         [ $cnt != 3 ] && error "unexpected #files: $cnt"
23208
23209         fid1=$(lfs path2fid $DIR/$tdir/f1)
23210         fid2=$(lfs path2fid $DIR/$tdir/f2)
23211         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
23212
23213         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
23214         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
23215
23216         cnt=$(ls -1 $DIR/$tdir | wc -l)
23217         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
23218
23219         rm -f $DIR/$tdir/f3 || error "can't remove f3"
23220         createmany -o $DIR/$tdir/f 3
23221         cnt=$(ls -1 $DIR/$tdir | wc -l)
23222         [ $cnt != 3 ] && error "unexpected #files: $cnt"
23223
23224         fid1=$(lfs path2fid $DIR/$tdir/f1)
23225         fid2=$(lfs path2fid $DIR/$tdir/f2)
23226         echo "remove using fsname $FSNAME"
23227         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
23228
23229         cnt=$(ls -1 $DIR/$tdir | wc -l)
23230         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
23231 }
23232 run_test 421a "simple rm by fid"
23233
23234 test_421b() {
23235         local cnt
23236         local FID1
23237         local FID2
23238
23239         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23240                 skip "Need MDS version at least 2.12.54"
23241
23242         test_mkdir $DIR/$tdir
23243         createmany -o $DIR/$tdir/f 3
23244         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
23245         MULTIPID=$!
23246
23247         FID1=$(lfs path2fid $DIR/$tdir/f1)
23248         FID2=$(lfs path2fid $DIR/$tdir/f2)
23249         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
23250
23251         kill -USR1 $MULTIPID
23252         wait
23253
23254         cnt=$(ls $DIR/$tdir | wc -l)
23255         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
23256 }
23257 run_test 421b "rm by fid on open file"
23258
23259 test_421c() {
23260         local cnt
23261         local FIDS
23262
23263         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23264                 skip "Need MDS version at least 2.12.54"
23265
23266         test_mkdir $DIR/$tdir
23267         createmany -o $DIR/$tdir/f 3
23268         touch $DIR/$tdir/$tfile
23269         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
23270         cnt=$(ls -1 $DIR/$tdir | wc -l)
23271         [ $cnt != 184 ] && error "unexpected #files: $cnt"
23272
23273         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
23274         $LFS rmfid $DIR $FID1 || error "rmfid failed"
23275
23276         cnt=$(ls $DIR/$tdir | wc -l)
23277         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
23278 }
23279 run_test 421c "rm by fid against hardlinked files"
23280
23281 test_421d() {
23282         local cnt
23283         local FIDS
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         createmany -o $DIR/$tdir/f 4097
23290         cnt=$(ls -1 $DIR/$tdir | wc -l)
23291         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
23292
23293         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
23294         $LFS rmfid $DIR $FIDS || error "rmfid failed"
23295
23296         cnt=$(ls $DIR/$tdir | wc -l)
23297         rm -rf $DIR/$tdir
23298         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23299 }
23300 run_test 421d "rmfid en masse"
23301
23302 test_421e() {
23303         local cnt
23304         local FID
23305
23306         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23307         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23308                 skip "Need MDS version at least 2.12.54"
23309
23310         mkdir -p $DIR/$tdir
23311         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23312         createmany -o $DIR/$tdir/striped_dir/f 512
23313         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23314         [ $cnt != 512 ] && error "unexpected #files: $cnt"
23315
23316         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
23317                 sed "s/[/][^:]*://g")
23318         $LFS rmfid $DIR $FIDS || error "rmfid failed"
23319
23320         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
23321         rm -rf $DIR/$tdir
23322         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23323 }
23324 run_test 421e "rmfid in DNE"
23325
23326 test_421f() {
23327         local cnt
23328         local FID
23329
23330         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23331                 skip "Need MDS version at least 2.12.54"
23332
23333         test_mkdir $DIR/$tdir
23334         touch $DIR/$tdir/f
23335         cnt=$(ls -1 $DIR/$tdir | wc -l)
23336         [ $cnt != 1 ] && error "unexpected #files: $cnt"
23337
23338         FID=$(lfs path2fid $DIR/$tdir/f)
23339         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
23340         # rmfid should fail
23341         cnt=$(ls -1 $DIR/$tdir | wc -l)
23342         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
23343
23344         chmod a+rw $DIR/$tdir
23345         ls -la $DIR/$tdir
23346         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
23347         # rmfid should fail
23348         cnt=$(ls -1 $DIR/$tdir | wc -l)
23349         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
23350
23351         rm -f $DIR/$tdir/f
23352         $RUNAS touch $DIR/$tdir/f
23353         FID=$(lfs path2fid $DIR/$tdir/f)
23354         echo "rmfid as root"
23355         $LFS rmfid $DIR $FID || error "rmfid as root failed"
23356         cnt=$(ls -1 $DIR/$tdir | wc -l)
23357         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
23358
23359         rm -f $DIR/$tdir/f
23360         $RUNAS touch $DIR/$tdir/f
23361         cnt=$(ls -1 $DIR/$tdir | wc -l)
23362         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
23363         FID=$(lfs path2fid $DIR/$tdir/f)
23364         # rmfid w/o user_fid2path mount option should fail
23365         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
23366         cnt=$(ls -1 $DIR/$tdir | wc -l)
23367         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
23368
23369         umount_client $MOUNT || error "failed to umount client"
23370         mount_client $MOUNT "$MOUNT_OPTS,user_fid2path" ||
23371                 error "failed to mount client'"
23372
23373         $RUNAS $LFS rmfid $DIR $FID || error "rmfid failed"
23374         # rmfid should succeed
23375         cnt=$(ls -1 $DIR/$tdir | wc -l)
23376         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
23377
23378         # rmfid shouldn't allow to remove files due to dir's permission
23379         chmod a+rwx $DIR/$tdir
23380         touch $DIR/$tdir/f
23381         ls -la $DIR/$tdir
23382         FID=$(lfs path2fid $DIR/$tdir/f)
23383         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail"
23384
23385         umount_client $MOUNT || error "failed to umount client"
23386         mount_client $MOUNT "$MOUNT_OPTS" ||
23387                 error "failed to mount client'"
23388
23389 }
23390 run_test 421f "rmfid checks permissions"
23391
23392 test_421g() {
23393         local cnt
23394         local FIDS
23395
23396         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23397         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23398                 skip "Need MDS version at least 2.12.54"
23399
23400         mkdir -p $DIR/$tdir
23401         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23402         createmany -o $DIR/$tdir/striped_dir/f 512
23403         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23404         [ $cnt != 512 ] && error "unexpected #files: $cnt"
23405
23406         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
23407                 sed "s/[/][^:]*://g")
23408
23409         rm -f $DIR/$tdir/striped_dir/f1*
23410         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23411         removed=$((512 - cnt))
23412
23413         # few files have been just removed, so we expect
23414         # rmfid to fail on their fids
23415         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
23416         [ $removed != $errors ] && error "$errors != $removed"
23417
23418         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
23419         rm -rf $DIR/$tdir
23420         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23421 }
23422 run_test 421g "rmfid to return errors properly"
23423
23424 test_422() {
23425         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
23426         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
23427         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
23428         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
23429         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
23430
23431         local amc=$(at_max_get client)
23432         local amo=$(at_max_get mds1)
23433         local timeout=`lctl get_param -n timeout`
23434
23435         at_max_set 0 client
23436         at_max_set 0 mds1
23437
23438 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
23439         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
23440                         fail_val=$(((2*timeout + 10)*1000))
23441         touch $DIR/$tdir/d3/file &
23442         sleep 2
23443 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
23444         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
23445                         fail_val=$((2*timeout + 5))
23446         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
23447         local pid=$!
23448         sleep 1
23449         kill -9 $pid
23450         sleep $((2 * timeout))
23451         echo kill $pid
23452         kill -9 $pid
23453         lctl mark touch
23454         touch $DIR/$tdir/d2/file3
23455         touch $DIR/$tdir/d2/file4
23456         touch $DIR/$tdir/d2/file5
23457
23458         wait
23459         at_max_set $amc client
23460         at_max_set $amo mds1
23461
23462         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
23463         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
23464                 error "Watchdog is always throttled"
23465 }
23466 run_test 422 "kill a process with RPC in progress"
23467
23468 stat_test() {
23469     df -h $MOUNT &
23470     df -h $MOUNT &
23471     df -h $MOUNT &
23472     df -h $MOUNT &
23473     df -h $MOUNT &
23474     df -h $MOUNT &
23475 }
23476
23477 test_423() {
23478     local _stats
23479     # ensure statfs cache is expired
23480     sleep 2;
23481
23482     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
23483     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
23484
23485     return 0
23486 }
23487 run_test 423 "statfs should return a right data"
23488
23489 test_424() {
23490 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
23491         $LCTL set_param fail_loc=0x80000522
23492         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
23493         rm -f $DIR/$tfile
23494 }
23495 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
23496
23497 test_425() {
23498         test_mkdir -c -1 $DIR/$tdir
23499         $LFS setstripe -c -1 $DIR/$tdir
23500
23501         lru_resize_disable "" 100
23502         stack_trap "lru_resize_enable" EXIT
23503
23504         sleep 5
23505
23506         for i in $(seq $((MDSCOUNT * 125))); do
23507                 local t=$DIR/$tdir/$tfile_$i
23508
23509                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
23510                         error_noexit "Create file $t"
23511         done
23512         stack_trap "rm -rf $DIR/$tdir" EXIT
23513
23514         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
23515                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
23516                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
23517
23518                 [ $lock_count -le $lru_size ] ||
23519                         error "osc lock count $lock_count > lru size $lru_size"
23520         done
23521
23522         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
23523                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
23524                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
23525
23526                 [ $lock_count -le $lru_size ] ||
23527                         error "mdc lock count $lock_count > lru size $lru_size"
23528         done
23529 }
23530 run_test 425 "lock count should not exceed lru size"
23531
23532 test_426() {
23533         splice-test -r $DIR/$tfile
23534         splice-test -rd $DIR/$tfile
23535         splice-test $DIR/$tfile
23536         splice-test -d $DIR/$tfile
23537 }
23538 run_test 426 "splice test on Lustre"
23539
23540 prep_801() {
23541         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
23542         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
23543                 skip "Need server version at least 2.9.55"
23544
23545         start_full_debug_logging
23546 }
23547
23548 post_801() {
23549         stop_full_debug_logging
23550 }
23551
23552 barrier_stat() {
23553         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
23554                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
23555                            awk '/The barrier for/ { print $7 }')
23556                 echo $st
23557         else
23558                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
23559                 echo \'$st\'
23560         fi
23561 }
23562
23563 barrier_expired() {
23564         local expired
23565
23566         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
23567                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
23568                           awk '/will be expired/ { print $7 }')
23569         else
23570                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
23571         fi
23572
23573         echo $expired
23574 }
23575
23576 test_801a() {
23577         prep_801
23578
23579         echo "Start barrier_freeze at: $(date)"
23580         #define OBD_FAIL_BARRIER_DELAY          0x2202
23581         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
23582         # Do not reduce barrier time - See LU-11873
23583         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
23584
23585         sleep 2
23586         local b_status=$(barrier_stat)
23587         echo "Got barrier status at: $(date)"
23588         [ "$b_status" = "'freezing_p1'" ] ||
23589                 error "(1) unexpected barrier status $b_status"
23590
23591         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
23592         wait
23593         b_status=$(barrier_stat)
23594         [ "$b_status" = "'frozen'" ] ||
23595                 error "(2) unexpected barrier status $b_status"
23596
23597         local expired=$(barrier_expired)
23598         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
23599         sleep $((expired + 3))
23600
23601         b_status=$(barrier_stat)
23602         [ "$b_status" = "'expired'" ] ||
23603                 error "(3) unexpected barrier status $b_status"
23604
23605         # Do not reduce barrier time - See LU-11873
23606         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
23607                 error "(4) fail to freeze barrier"
23608
23609         b_status=$(barrier_stat)
23610         [ "$b_status" = "'frozen'" ] ||
23611                 error "(5) unexpected barrier status $b_status"
23612
23613         echo "Start barrier_thaw at: $(date)"
23614         #define OBD_FAIL_BARRIER_DELAY          0x2202
23615         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
23616         do_facet mgs $LCTL barrier_thaw $FSNAME &
23617
23618         sleep 2
23619         b_status=$(barrier_stat)
23620         echo "Got barrier status at: $(date)"
23621         [ "$b_status" = "'thawing'" ] ||
23622                 error "(6) unexpected barrier status $b_status"
23623
23624         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
23625         wait
23626         b_status=$(barrier_stat)
23627         [ "$b_status" = "'thawed'" ] ||
23628                 error "(7) unexpected barrier status $b_status"
23629
23630         #define OBD_FAIL_BARRIER_FAILURE        0x2203
23631         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
23632         do_facet mgs $LCTL barrier_freeze $FSNAME
23633
23634         b_status=$(barrier_stat)
23635         [ "$b_status" = "'failed'" ] ||
23636                 error "(8) unexpected barrier status $b_status"
23637
23638         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
23639         do_facet mgs $LCTL barrier_thaw $FSNAME
23640
23641         post_801
23642 }
23643 run_test 801a "write barrier user interfaces and stat machine"
23644
23645 test_801b() {
23646         prep_801
23647
23648         mkdir $DIR/$tdir || error "(1) fail to mkdir"
23649         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
23650         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
23651         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
23652         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
23653
23654         cancel_lru_locks mdc
23655
23656         # 180 seconds should be long enough
23657         do_facet mgs $LCTL barrier_freeze $FSNAME 180
23658
23659         local b_status=$(barrier_stat)
23660         [ "$b_status" = "'frozen'" ] ||
23661                 error "(6) unexpected barrier status $b_status"
23662
23663         mkdir $DIR/$tdir/d0/d10 &
23664         mkdir_pid=$!
23665
23666         touch $DIR/$tdir/d1/f13 &
23667         touch_pid=$!
23668
23669         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
23670         ln_pid=$!
23671
23672         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
23673         mv_pid=$!
23674
23675         rm -f $DIR/$tdir/d4/f12 &
23676         rm_pid=$!
23677
23678         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
23679
23680         # To guarantee taht the 'stat' is not blocked
23681         b_status=$(barrier_stat)
23682         [ "$b_status" = "'frozen'" ] ||
23683                 error "(8) unexpected barrier status $b_status"
23684
23685         # let above commands to run at background
23686         sleep 5
23687
23688         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
23689         ps -p $touch_pid || error "(10) touch should be blocked"
23690         ps -p $ln_pid || error "(11) link should be blocked"
23691         ps -p $mv_pid || error "(12) rename should be blocked"
23692         ps -p $rm_pid || error "(13) unlink should be blocked"
23693
23694         b_status=$(barrier_stat)
23695         [ "$b_status" = "'frozen'" ] ||
23696                 error "(14) unexpected barrier status $b_status"
23697
23698         do_facet mgs $LCTL barrier_thaw $FSNAME
23699         b_status=$(barrier_stat)
23700         [ "$b_status" = "'thawed'" ] ||
23701                 error "(15) unexpected barrier status $b_status"
23702
23703         wait $mkdir_pid || error "(16) mkdir should succeed"
23704         wait $touch_pid || error "(17) touch should succeed"
23705         wait $ln_pid || error "(18) link should succeed"
23706         wait $mv_pid || error "(19) rename should succeed"
23707         wait $rm_pid || error "(20) unlink should succeed"
23708
23709         post_801
23710 }
23711 run_test 801b "modification will be blocked by write barrier"
23712
23713 test_801c() {
23714         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
23715
23716         prep_801
23717
23718         stop mds2 || error "(1) Fail to stop mds2"
23719
23720         do_facet mgs $LCTL barrier_freeze $FSNAME 30
23721
23722         local b_status=$(barrier_stat)
23723         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
23724                 do_facet mgs $LCTL barrier_thaw $FSNAME
23725                 error "(2) unexpected barrier status $b_status"
23726         }
23727
23728         do_facet mgs $LCTL barrier_rescan $FSNAME ||
23729                 error "(3) Fail to rescan barrier bitmap"
23730
23731         # Do not reduce barrier time - See LU-11873
23732         do_facet mgs $LCTL barrier_freeze $FSNAME 20
23733
23734         b_status=$(barrier_stat)
23735         [ "$b_status" = "'frozen'" ] ||
23736                 error "(4) unexpected barrier status $b_status"
23737
23738         do_facet mgs $LCTL barrier_thaw $FSNAME
23739         b_status=$(barrier_stat)
23740         [ "$b_status" = "'thawed'" ] ||
23741                 error "(5) unexpected barrier status $b_status"
23742
23743         local devname=$(mdsdevname 2)
23744
23745         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
23746
23747         do_facet mgs $LCTL barrier_rescan $FSNAME ||
23748                 error "(7) Fail to rescan barrier bitmap"
23749
23750         post_801
23751 }
23752 run_test 801c "rescan barrier bitmap"
23753
23754 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
23755 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
23756 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
23757 saved_MOUNT_OPTS=$MOUNT_OPTS
23758
23759 cleanup_802a() {
23760         trap 0
23761
23762         stopall
23763         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
23764         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
23765         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
23766         MOUNT_OPTS=$saved_MOUNT_OPTS
23767         setupall
23768 }
23769
23770 test_802a() {
23771         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
23772         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
23773         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
23774                 skip "Need server version at least 2.9.55"
23775
23776         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
23777
23778         mkdir $DIR/$tdir || error "(1) fail to mkdir"
23779
23780         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
23781                 error "(2) Fail to copy"
23782
23783         trap cleanup_802a EXIT
23784
23785         # sync by force before remount as readonly
23786         sync; sync_all_data; sleep 3; sync_all_data
23787
23788         stopall
23789
23790         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
23791         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
23792         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
23793
23794         echo "Mount the server as read only"
23795         setupall server_only || error "(3) Fail to start servers"
23796
23797         echo "Mount client without ro should fail"
23798         mount_client $MOUNT &&
23799                 error "(4) Mount client without 'ro' should fail"
23800
23801         echo "Mount client with ro should succeed"
23802         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
23803         mount_client $MOUNT ||
23804                 error "(5) Mount client with 'ro' should succeed"
23805
23806         echo "Modify should be refused"
23807         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
23808
23809         echo "Read should be allowed"
23810         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
23811                 error "(7) Read should succeed under ro mode"
23812
23813         cleanup_802a
23814 }
23815 run_test 802a "simulate readonly device"
23816
23817 test_802b() {
23818         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23819         remote_mds_nodsh && skip "remote MDS with nodsh"
23820
23821         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
23822                 skip "readonly option not available"
23823
23824         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
23825
23826         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
23827                 error "(2) Fail to copy"
23828
23829         # write back all cached data before setting MDT to readonly
23830         cancel_lru_locks
23831         sync_all_data
23832
23833         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
23834         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
23835
23836         echo "Modify should be refused"
23837         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
23838
23839         echo "Read should be allowed"
23840         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
23841                 error "(7) Read should succeed under ro mode"
23842
23843         # disable readonly
23844         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
23845 }
23846 run_test 802b "be able to set MDTs to readonly"
23847
23848 test_803() {
23849         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
23850         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
23851                 skip "MDS needs to be newer than 2.10.54"
23852
23853         mkdir -p $DIR/$tdir
23854         # Create some objects on all MDTs to trigger related logs objects
23855         for idx in $(seq $MDSCOUNT); do
23856                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
23857                         $DIR/$tdir/dir${idx} ||
23858                         error "Fail to create $DIR/$tdir/dir${idx}"
23859         done
23860
23861         sync; sleep 3
23862         wait_delete_completed # ensure old test cleanups are finished
23863         echo "before create:"
23864         $LFS df -i $MOUNT
23865         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
23866
23867         for i in {1..10}; do
23868                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
23869                         error "Fail to create $DIR/$tdir/foo$i"
23870         done
23871
23872         sync; sleep 3
23873         echo "after create:"
23874         $LFS df -i $MOUNT
23875         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
23876
23877         # allow for an llog to be cleaned up during the test
23878         [ $after_used -ge $((before_used + 10 - 1)) ] ||
23879                 error "before ($before_used) + 10 > after ($after_used)"
23880
23881         for i in {1..10}; do
23882                 rm -rf $DIR/$tdir/foo$i ||
23883                         error "Fail to remove $DIR/$tdir/foo$i"
23884         done
23885
23886         sleep 3 # avoid MDT return cached statfs
23887         wait_delete_completed
23888         echo "after unlink:"
23889         $LFS df -i $MOUNT
23890         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
23891
23892         # allow for an llog to be created during the test
23893         [ $after_used -le $((before_used + 1)) ] ||
23894                 error "after ($after_used) > before ($before_used) + 1"
23895 }
23896 run_test 803 "verify agent object for remote object"
23897
23898 test_804() {
23899         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
23900         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
23901                 skip "MDS needs to be newer than 2.10.54"
23902         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
23903
23904         mkdir -p $DIR/$tdir
23905         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
23906                 error "Fail to create $DIR/$tdir/dir0"
23907
23908         local fid=$($LFS path2fid $DIR/$tdir/dir0)
23909         local dev=$(mdsdevname 2)
23910
23911         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23912                 grep ${fid} || error "NOT found agent entry for dir0"
23913
23914         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
23915                 error "Fail to create $DIR/$tdir/dir1"
23916
23917         touch $DIR/$tdir/dir1/foo0 ||
23918                 error "Fail to create $DIR/$tdir/dir1/foo0"
23919         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
23920         local rc=0
23921
23922         for idx in $(seq $MDSCOUNT); do
23923                 dev=$(mdsdevname $idx)
23924                 do_facet mds${idx} \
23925                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23926                         grep ${fid} && rc=$idx
23927         done
23928
23929         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
23930                 error "Fail to rename foo0 to foo1"
23931         if [ $rc -eq 0 ]; then
23932                 for idx in $(seq $MDSCOUNT); do
23933                         dev=$(mdsdevname $idx)
23934                         do_facet mds${idx} \
23935                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23936                         grep ${fid} && rc=$idx
23937                 done
23938         fi
23939
23940         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
23941                 error "Fail to rename foo1 to foo2"
23942         if [ $rc -eq 0 ]; then
23943                 for idx in $(seq $MDSCOUNT); do
23944                         dev=$(mdsdevname $idx)
23945                         do_facet mds${idx} \
23946                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23947                         grep ${fid} && rc=$idx
23948                 done
23949         fi
23950
23951         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
23952
23953         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
23954                 error "Fail to link to $DIR/$tdir/dir1/foo2"
23955         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
23956                 error "Fail to rename foo2 to foo0"
23957         unlink $DIR/$tdir/dir1/foo0 ||
23958                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
23959         rm -rf $DIR/$tdir/dir0 ||
23960                 error "Fail to rm $DIR/$tdir/dir0"
23961
23962         for idx in $(seq $MDSCOUNT); do
23963                 dev=$(mdsdevname $idx)
23964                 rc=0
23965
23966                 stop mds${idx}
23967                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
23968                         rc=$?
23969                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
23970                         error "mount mds$idx failed"
23971                 df $MOUNT > /dev/null 2>&1
23972
23973                 # e2fsck should not return error
23974                 [ $rc -eq 0 ] ||
23975                         error "e2fsck detected error on MDT${idx}: rc=$rc"
23976         done
23977 }
23978 run_test 804 "verify agent entry for remote entry"
23979
23980 cleanup_805() {
23981         do_facet $SINGLEMDS zfs set quota=$old $fsset
23982         unlinkmany $DIR/$tdir/f- 1000000
23983         trap 0
23984 }
23985
23986 test_805() {
23987         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
23988         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
23989         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
23990                 skip "netfree not implemented before 0.7"
23991         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
23992                 skip "Need MDS version at least 2.10.57"
23993
23994         local fsset
23995         local freekb
23996         local usedkb
23997         local old
23998         local quota
23999         local pref="osd-zfs.$FSNAME-MDT0000."
24000
24001         # limit available space on MDS dataset to meet nospace issue
24002         # quickly. then ZFS 0.7.2 can use reserved space if asked
24003         # properly (using netfree flag in osd_declare_destroy()
24004         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
24005         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
24006                 gawk '{print $3}')
24007         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
24008         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
24009         let "usedkb=usedkb-freekb"
24010         let "freekb=freekb/2"
24011         if let "freekb > 5000"; then
24012                 let "freekb=5000"
24013         fi
24014         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
24015         trap cleanup_805 EXIT
24016         mkdir $DIR/$tdir
24017         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
24018                 error "Can't set PFL layout"
24019         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
24020         rm -rf $DIR/$tdir || error "not able to remove"
24021         do_facet $SINGLEMDS zfs set quota=$old $fsset
24022         trap 0
24023 }
24024 run_test 805 "ZFS can remove from full fs"
24025
24026 # Size-on-MDS test
24027 check_lsom_data()
24028 {
24029         local file=$1
24030         local size=$($LFS getsom -s $file)
24031         local expect=$(stat -c %s $file)
24032
24033         [[ $size == $expect ]] ||
24034                 error "$file expected size: $expect, got: $size"
24035
24036         local blocks=$($LFS getsom -b $file)
24037         expect=$(stat -c %b $file)
24038         [[ $blocks == $expect ]] ||
24039                 error "$file expected blocks: $expect, got: $blocks"
24040 }
24041
24042 check_lsom_size()
24043 {
24044         local size=$($LFS getsom -s $1)
24045         local expect=$2
24046
24047         [[ $size == $expect ]] ||
24048                 error "$file expected size: $expect, got: $size"
24049 }
24050
24051 test_806() {
24052         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
24053                 skip "Need MDS version at least 2.11.52"
24054
24055         local bs=1048576
24056
24057         touch $DIR/$tfile || error "touch $tfile failed"
24058
24059         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24060         save_lustre_params client "llite.*.xattr_cache" > $save
24061         lctl set_param llite.*.xattr_cache=0
24062         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24063
24064         # single-threaded write
24065         echo "Test SOM for single-threaded write"
24066         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
24067                 error "write $tfile failed"
24068         check_lsom_size $DIR/$tfile $bs
24069
24070         local num=32
24071         local size=$(($num * $bs))
24072         local offset=0
24073         local i
24074
24075         echo "Test SOM for single client multi-threaded($num) write"
24076         $TRUNCATE $DIR/$tfile 0
24077         for ((i = 0; i < $num; i++)); do
24078                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24079                 local pids[$i]=$!
24080                 offset=$((offset + $bs))
24081         done
24082         for (( i=0; i < $num; i++ )); do
24083                 wait ${pids[$i]}
24084         done
24085         check_lsom_size $DIR/$tfile $size
24086
24087         $TRUNCATE $DIR/$tfile 0
24088         for ((i = 0; i < $num; i++)); do
24089                 offset=$((offset - $bs))
24090                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24091                 local pids[$i]=$!
24092         done
24093         for (( i=0; i < $num; i++ )); do
24094                 wait ${pids[$i]}
24095         done
24096         check_lsom_size $DIR/$tfile $size
24097
24098         # multi-client writes
24099         num=$(get_node_count ${CLIENTS//,/ })
24100         size=$(($num * $bs))
24101         offset=0
24102         i=0
24103
24104         echo "Test SOM for multi-client ($num) writes"
24105         $TRUNCATE $DIR/$tfile 0
24106         for client in ${CLIENTS//,/ }; do
24107                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24108                 local pids[$i]=$!
24109                 i=$((i + 1))
24110                 offset=$((offset + $bs))
24111         done
24112         for (( i=0; i < $num; i++ )); do
24113                 wait ${pids[$i]}
24114         done
24115         check_lsom_size $DIR/$tfile $offset
24116
24117         i=0
24118         $TRUNCATE $DIR/$tfile 0
24119         for client in ${CLIENTS//,/ }; do
24120                 offset=$((offset - $bs))
24121                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24122                 local pids[$i]=$!
24123                 i=$((i + 1))
24124         done
24125         for (( i=0; i < $num; i++ )); do
24126                 wait ${pids[$i]}
24127         done
24128         check_lsom_size $DIR/$tfile $size
24129
24130         # verify truncate
24131         echo "Test SOM for truncate"
24132         $TRUNCATE $DIR/$tfile 1048576
24133         check_lsom_size $DIR/$tfile 1048576
24134         $TRUNCATE $DIR/$tfile 1234
24135         check_lsom_size $DIR/$tfile 1234
24136
24137         # verify SOM blocks count
24138         echo "Verify SOM block count"
24139         $TRUNCATE $DIR/$tfile 0
24140         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
24141                 error "failed to write file $tfile"
24142         check_lsom_data $DIR/$tfile
24143 }
24144 run_test 806 "Verify Lazy Size on MDS"
24145
24146 test_807() {
24147         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
24148         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
24149                 skip "Need MDS version at least 2.11.52"
24150
24151         # Registration step
24152         changelog_register || error "changelog_register failed"
24153         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
24154         changelog_users $SINGLEMDS | grep -q $cl_user ||
24155                 error "User $cl_user not found in changelog_users"
24156
24157         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24158         save_lustre_params client "llite.*.xattr_cache" > $save
24159         lctl set_param llite.*.xattr_cache=0
24160         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24161
24162         rm -rf $DIR/$tdir || error "rm $tdir failed"
24163         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
24164         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
24165         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
24166         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
24167                 error "truncate $tdir/trunc failed"
24168
24169         local bs=1048576
24170         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
24171                 error "write $tfile failed"
24172
24173         # multi-client wirtes
24174         local num=$(get_node_count ${CLIENTS//,/ })
24175         local offset=0
24176         local i=0
24177
24178         echo "Test SOM for multi-client ($num) writes"
24179         touch $DIR/$tfile || error "touch $tfile failed"
24180         $TRUNCATE $DIR/$tfile 0
24181         for client in ${CLIENTS//,/ }; do
24182                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24183                 local pids[$i]=$!
24184                 i=$((i + 1))
24185                 offset=$((offset + $bs))
24186         done
24187         for (( i=0; i < $num; i++ )); do
24188                 wait ${pids[$i]}
24189         done
24190
24191         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
24192         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
24193         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
24194         check_lsom_data $DIR/$tdir/trunc
24195         check_lsom_data $DIR/$tdir/single_dd
24196         check_lsom_data $DIR/$tfile
24197
24198         rm -rf $DIR/$tdir
24199         # Deregistration step
24200         changelog_deregister || error "changelog_deregister failed"
24201 }
24202 run_test 807 "verify LSOM syncing tool"
24203
24204 check_som_nologged()
24205 {
24206         local lines=$($LFS changelog $FSNAME-MDT0000 |
24207                 grep 'x=trusted.som' | wc -l)
24208         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
24209 }
24210
24211 test_808() {
24212         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
24213                 skip "Need MDS version at least 2.11.55"
24214
24215         # Registration step
24216         changelog_register || error "changelog_register failed"
24217
24218         touch $DIR/$tfile || error "touch $tfile failed"
24219         check_som_nologged
24220
24221         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
24222                 error "write $tfile failed"
24223         check_som_nologged
24224
24225         $TRUNCATE $DIR/$tfile 1234
24226         check_som_nologged
24227
24228         $TRUNCATE $DIR/$tfile 1048576
24229         check_som_nologged
24230
24231         # Deregistration step
24232         changelog_deregister || error "changelog_deregister failed"
24233 }
24234 run_test 808 "Check trusted.som xattr not logged in Changelogs"
24235
24236 check_som_nodata()
24237 {
24238         $LFS getsom $1
24239         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
24240 }
24241
24242 test_809() {
24243         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
24244                 skip "Need MDS version at least 2.11.56"
24245
24246         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
24247                 error "failed to create DoM-only file $DIR/$tfile"
24248         touch $DIR/$tfile || error "touch $tfile failed"
24249         check_som_nodata $DIR/$tfile
24250
24251         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
24252                 error "write $tfile failed"
24253         check_som_nodata $DIR/$tfile
24254
24255         $TRUNCATE $DIR/$tfile 1234
24256         check_som_nodata $DIR/$tfile
24257
24258         $TRUNCATE $DIR/$tfile 4097
24259         check_som_nodata $DIR/$file
24260 }
24261 run_test 809 "Verify no SOM xattr store for DoM-only files"
24262
24263 test_810() {
24264         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24265         $GSS && skip_env "could not run with gss"
24266         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
24267                 skip "OST < 2.12.58 doesn't align checksum"
24268
24269         set_checksums 1
24270         stack_trap "set_checksums $ORIG_CSUM" EXIT
24271         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
24272
24273         local csum
24274         local before
24275         local after
24276         for csum in $CKSUM_TYPES; do
24277                 #define OBD_FAIL_OSC_NO_GRANT   0x411
24278                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
24279                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
24280                         eval set -- $i
24281                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
24282                         before=$(md5sum $DIR/$tfile)
24283                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
24284                         after=$(md5sum $DIR/$tfile)
24285                         [ "$before" == "$after" ] ||
24286                                 error "$csum: $before != $after bs=$1 seek=$2"
24287                 done
24288         done
24289 }
24290 run_test 810 "partial page writes on ZFS (LU-11663)"
24291
24292 test_812a() {
24293         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
24294                 skip "OST < 2.12.51 doesn't support this fail_loc"
24295         [ "$SHARED_KEY" = true ] &&
24296                 skip "OSC connections never go IDLE with Shared-Keys enabled"
24297
24298         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24299         # ensure ost1 is connected
24300         stat $DIR/$tfile >/dev/null || error "can't stat"
24301         wait_osc_import_state client ost1 FULL
24302         # no locks, no reqs to let the connection idle
24303         cancel_lru_locks osc
24304
24305         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
24306 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
24307         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
24308         wait_osc_import_state client ost1 CONNECTING
24309         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
24310
24311         stat $DIR/$tfile >/dev/null || error "can't stat file"
24312 }
24313 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
24314
24315 test_812b() { # LU-12378
24316         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
24317                 skip "OST < 2.12.51 doesn't support this fail_loc"
24318         [ "$SHARED_KEY" = true ] &&
24319                 skip "OSC connections never go IDLE with Shared-Keys enabled"
24320
24321         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
24322         # ensure ost1 is connected
24323         stat $DIR/$tfile >/dev/null || error "can't stat"
24324         wait_osc_import_state client ost1 FULL
24325         # no locks, no reqs to let the connection idle
24326         cancel_lru_locks osc
24327
24328         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
24329 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
24330         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
24331         wait_osc_import_state client ost1 CONNECTING
24332         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
24333
24334         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
24335         wait_osc_import_state client ost1 IDLE
24336 }
24337 run_test 812b "do not drop no resend request for idle connect"
24338
24339 test_813() {
24340         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
24341         [ -z "$file_heat_sav" ] && skip "no file heat support"
24342
24343         local readsample
24344         local writesample
24345         local readbyte
24346         local writebyte
24347         local readsample1
24348         local writesample1
24349         local readbyte1
24350         local writebyte1
24351
24352         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
24353         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
24354
24355         $LCTL set_param -n llite.*.file_heat=1
24356         echo "Turn on file heat"
24357         echo "Period second: $period_second, Decay percentage: $decay_pct"
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         local out=$($LFS heat_get $DIR/$tfile)
24368
24369         $LFS heat_get $DIR/$tfile
24370         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24371         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24372         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24373         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24374
24375         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
24376         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
24377         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
24378         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
24379
24380         sleep $((period_second + 3))
24381         echo "Sleep $((period_second + 3)) seconds..."
24382         # The recursion formula to calculate the heat of the file f is as
24383         # follow:
24384         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
24385         # Where Hi is the heat value in the period between time points i*I and
24386         # (i+1)*I; Ci is the access count in the period; the symbol P refers
24387         # to the weight of Ci.
24388         out=$($LFS heat_get $DIR/$tfile)
24389         $LFS heat_get $DIR/$tfile
24390         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24391         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24392         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24393         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24394
24395         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
24396                 error "read sample ($readsample) is wrong"
24397         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
24398                 error "write sample ($writesample) is wrong"
24399         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
24400                 error "read bytes ($readbyte) is wrong"
24401         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
24402                 error "write bytes ($writebyte) is wrong"
24403
24404         echo "QQQQ" > $DIR/$tfile
24405         echo "QQQQ" > $DIR/$tfile
24406         echo "QQQQ" > $DIR/$tfile
24407         cat $DIR/$tfile > /dev/null
24408         cat $DIR/$tfile > /dev/null
24409         cat $DIR/$tfile > /dev/null
24410         cat $DIR/$tfile > /dev/null
24411
24412         sleep $((period_second + 3))
24413         echo "Sleep $((period_second + 3)) seconds..."
24414
24415         out=$($LFS heat_get $DIR/$tfile)
24416         $LFS heat_get $DIR/$tfile
24417         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24418         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24419         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24420         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24421
24422         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
24423                 4 * $decay_pct) / 100") -eq 1 ] ||
24424                 error "read sample ($readsample1) is wrong"
24425         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
24426                 3 * $decay_pct) / 100") -eq 1 ] ||
24427                 error "write sample ($writesample1) is wrong"
24428         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
24429                 20 * $decay_pct) / 100") -eq 1 ] ||
24430                 error "read bytes ($readbyte1) is wrong"
24431         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
24432                 15 * $decay_pct) / 100") -eq 1 ] ||
24433                 error "write bytes ($writebyte1) is wrong"
24434
24435         echo "Turn off file heat for the file $DIR/$tfile"
24436         $LFS heat_set -o $DIR/$tfile
24437
24438         echo "QQQQ" > $DIR/$tfile
24439         echo "QQQQ" > $DIR/$tfile
24440         echo "QQQQ" > $DIR/$tfile
24441         cat $DIR/$tfile > /dev/null
24442         cat $DIR/$tfile > /dev/null
24443         cat $DIR/$tfile > /dev/null
24444         cat $DIR/$tfile > /dev/null
24445
24446         out=$($LFS heat_get $DIR/$tfile)
24447         $LFS heat_get $DIR/$tfile
24448         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24449         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24450         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24451         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24452
24453         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
24454         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
24455         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
24456         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
24457
24458         echo "Trun on file heat for the file $DIR/$tfile"
24459         $LFS heat_set -O $DIR/$tfile
24460
24461         echo "QQQQ" > $DIR/$tfile
24462         echo "QQQQ" > $DIR/$tfile
24463         echo "QQQQ" > $DIR/$tfile
24464         cat $DIR/$tfile > /dev/null
24465         cat $DIR/$tfile > /dev/null
24466         cat $DIR/$tfile > /dev/null
24467         cat $DIR/$tfile > /dev/null
24468
24469         out=$($LFS heat_get $DIR/$tfile)
24470         $LFS heat_get $DIR/$tfile
24471         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24472         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24473         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24474         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24475
24476         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
24477         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
24478         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
24479         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
24480
24481         $LFS heat_set -c $DIR/$tfile
24482         $LCTL set_param -n llite.*.file_heat=0
24483         echo "Turn off file heat support for the Lustre filesystem"
24484
24485         echo "QQQQ" > $DIR/$tfile
24486         echo "QQQQ" > $DIR/$tfile
24487         echo "QQQQ" > $DIR/$tfile
24488         cat $DIR/$tfile > /dev/null
24489         cat $DIR/$tfile > /dev/null
24490         cat $DIR/$tfile > /dev/null
24491         cat $DIR/$tfile > /dev/null
24492
24493         out=$($LFS heat_get $DIR/$tfile)
24494         $LFS heat_get $DIR/$tfile
24495         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24496         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24497         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24498         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24499
24500         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
24501         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
24502         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
24503         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
24504
24505         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
24506         rm -f $DIR/$tfile
24507 }
24508 run_test 813 "File heat verfication"
24509
24510 test_814()
24511 {
24512         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
24513         echo -n y >> $DIR/$tfile
24514         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
24515         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
24516 }
24517 run_test 814 "sparse cp works as expected (LU-12361)"
24518
24519 test_815()
24520 {
24521         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
24522         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
24523 }
24524 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
24525
24526 test_816() {
24527         [ "$SHARED_KEY" = true ] &&
24528                 skip "OSC connections never go IDLE with Shared-Keys enabled"
24529
24530         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24531         # ensure ost1 is connected
24532         stat $DIR/$tfile >/dev/null || error "can't stat"
24533         wait_osc_import_state client ost1 FULL
24534         # no locks, no reqs to let the connection idle
24535         cancel_lru_locks osc
24536         lru_resize_disable osc
24537         local before
24538         local now
24539         before=$($LCTL get_param -n \
24540                  ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
24541
24542         wait_osc_import_state client ost1 IDLE
24543         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
24544         now=$($LCTL get_param -n \
24545               ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
24546         [ $before == $now ] || error "lru_size changed $before != $now"
24547 }
24548 run_test 816 "do not reset lru_resize on idle reconnect"
24549
24550 cleanup_817() {
24551         umount $tmpdir
24552         exportfs -u localhost:$DIR/nfsexp
24553         rm -rf $DIR/nfsexp
24554 }
24555
24556 test_817() {
24557         systemctl restart nfs-server.service || skip "failed to restart nfsd"
24558
24559         mkdir -p $DIR/nfsexp
24560         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
24561                 error "failed to export nfs"
24562
24563         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
24564         stack_trap cleanup_817 EXIT
24565
24566         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
24567                 error "failed to mount nfs to $tmpdir"
24568
24569         cp /bin/true $tmpdir
24570         $DIR/nfsexp/true || error "failed to execute 'true' command"
24571 }
24572 run_test 817 "nfsd won't cache write lock for exec file"
24573
24574 test_818() {
24575         mkdir $DIR/$tdir
24576         $LFS setstripe -c1 -i0 $DIR/$tfile
24577         $LFS setstripe -c1 -i1 $DIR/$tfile
24578         stop $SINGLEMDS
24579         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
24580         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
24581         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
24582                 error "start $SINGLEMDS failed"
24583         rm -rf $DIR/$tdir
24584 }
24585 run_test 818 "unlink with failed llog"
24586
24587 test_819a() {
24588         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24589         cancel_lru_locks osc
24590         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
24591         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
24592         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
24593         rm -f $TDIR/$tfile
24594 }
24595 run_test 819a "too big niobuf in read"
24596
24597 test_819b() {
24598         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
24599         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
24600         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24601         cancel_lru_locks osc
24602         sleep 1
24603         rm -f $TDIR/$tfile
24604 }
24605 run_test 819b "too big niobuf in write"
24606
24607
24608 function test_820_start_ost() {
24609         sleep 5
24610
24611         for num in $(seq $OSTCOUNT); do
24612                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
24613         done
24614 }
24615
24616 test_820() {
24617         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24618
24619         mkdir $DIR/$tdir
24620         umount_client $MOUNT || error "umount failed"
24621         for num in $(seq $OSTCOUNT); do
24622                 stop ost$num
24623         done
24624
24625         # mount client with no active OSTs
24626         # so that the client can't initialize max LOV EA size
24627         # from OSC notifications
24628         mount_client $MOUNT || error "mount failed"
24629         # delay OST starting to keep this 0 max EA size for a while
24630         test_820_start_ost &
24631
24632         # create a directory on MDS2
24633         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
24634                 error "Failed to create directory"
24635         # open intent should update default EA size
24636         # see mdc_update_max_ea_from_body()
24637         # notice this is the very first RPC to MDS2
24638         cp /etc/services $DIR/$tdir/mds2 ||
24639                 error "Failed to copy files to mds$n"
24640 }
24641 run_test 820 "update max EA from open intent"
24642
24643 #
24644 # tests that do cleanup/setup should be run at the end
24645 #
24646
24647 test_900() {
24648         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24649         local ls
24650
24651         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
24652         $LCTL set_param fail_loc=0x903
24653
24654         cancel_lru_locks MGC
24655
24656         FAIL_ON_ERROR=true cleanup
24657         FAIL_ON_ERROR=true setup
24658 }
24659 run_test 900 "umount should not race with any mgc requeue thread"
24660
24661 # LUS-6253/LU-11185
24662 test_901() {
24663         local oldc
24664         local newc
24665         local olds
24666         local news
24667         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24668
24669         # some get_param have a bug to handle dot in param name
24670         cancel_lru_locks MGC
24671         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
24672         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
24673         umount_client $MOUNT || error "umount failed"
24674         mount_client $MOUNT || error "mount failed"
24675         cancel_lru_locks MGC
24676         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
24677         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
24678
24679         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
24680         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
24681
24682         return 0
24683 }
24684 run_test 901 "don't leak a mgc lock on client umount"
24685
24686 # LU-13377
24687 test_902() {
24688         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
24689                 skip "client does not have LU-13377 fix"
24690         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
24691         $LCTL set_param fail_loc=0x1415
24692         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24693         cancel_lru_locks osc
24694         rm -f $DIR/$tfile
24695 }
24696 run_test 902 "test short write doesn't hang lustre"
24697
24698 complete $SECONDS
24699 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
24700 check_and_cleanup_lustre
24701 if [ "$I_MOUNTED" != "yes" ]; then
24702         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
24703 fi
24704 exit_status